From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22979 invoked by alias); 18 Nov 2008 09:32:10 -0000 Received: (qmail 22922 invoked by alias); 18 Nov 2008 09:32:09 -0000 Subject: gnbd: master - make gnbd a standalone project To: cluster-cvs-relay@redhat.com X-Project: GFS Network Block Device X-Git-Module: gnbd.git X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: 18fedbfb34778196df1454d46d9f5fb460c11d64 X-Git-Newrev: 5a399cd7fd9306f7e7d9c8ef13f27501710e565a From: "Fabio M. Di Nitto" Message-Id: <20081118093054.1BDE9C046B@lists.fedorahosted.org> Date: Tue, 18 Nov 2008 09:32:00 -0000 X-Scanned-By: MIMEDefang 2.58 on 172.16.52.254 Mailing-List: contact cluster-cvs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: cluster-cvs-owner@sourceware.org X-SW-Source: 2008-q4/txt/msg00321.txt.bz2 Gitweb: http://git.fedorahosted.org/git/gnbd.git?p=gnbd.git;a=commitdiff;h=5a399cd7fd9306f7e7d9c8ef13f27501710e565a Commit: 5a399cd7fd9306f7e7d9c8ef13f27501710e565a Parent: 18fedbfb34778196df1454d46d9f5fb460c11d64 Author: Fabio M. Di Nitto AuthorDate: Tue Nov 18 10:29:27 2008 +0100 Committer: Fabio M. Di Nitto CommitterDate: Tue Nov 18 10:29:27 2008 +0100 make gnbd a standalone project remove all unrequired components. adapt build system. Signed-off-by: Fabio M. Di Nitto --- Makefile | 38 +- bindings/Makefile | 4 - bindings/perl/Makefile | 4 - bindings/perl/ccs/CCS.pm.in | 145 - bindings/perl/ccs/CCS.xs | 82 - bindings/perl/ccs/MANIFEST | 7 - bindings/perl/ccs/META.yml.in | 13 - bindings/perl/ccs/Makefile.PL | 28 - bindings/perl/ccs/Makefile.bindings | 13 - bindings/perl/ccs/test.pl | 20 - bindings/perl/ccs/typemap | 1 - bindings/python/Makefile | 4 - cman/Makefile | 4 - cman/cman_tool/Makefile | 31 - cman/cman_tool/cman_tool.h | 100 - cman/cman_tool/join.c | 254 - cman/cman_tool/main.c | 1067 - cman/daemon/Makefile | 41 - cman/daemon/ais.c | 318 - cman/daemon/ais.h | 10 - cman/daemon/barrier.c | 468 - cman/daemon/barrier.h | 6 - cman/daemon/cman-preconfig.c | 1150 - cman/daemon/cman.h | 15 - cman/daemon/cmanconfig.c | 297 - cman/daemon/cmanconfig.h | 3 - cman/daemon/cnxman-private.h | 183 - cman/daemon/cnxman-socket.h | 275 - cman/daemon/commands.c | 2217 -- cman/daemon/commands.h | 37 - cman/daemon/daemon.c | 539 - cman/daemon/daemon.h | 12 - cman/daemon/list.h | 97 - cman/daemon/logging.c | 25 - cman/daemon/logging.h | 17 - cman/daemon/nodelist.h | 93 - cman/init.d/Makefile | 25 - cman/init.d/cman.in | 764 - cman/init.d/qdiskd.in | 128 - cman/lib/Makefile | 12 - cman/lib/libcman.c | 1105 - cman/lib/libcman.h | 423 - cman/man/Makefile | 9 - cman/man/cman.5 | 222 - cman/man/cman_tool.8 | 411 - cman/man/cmannotifyd.8 | 66 - cman/man/mkqdisk.8 | 31 - cman/man/qdisk.5 | 462 - cman/man/qdiskd.8 | 25 - cman/notifyd/Makefile | 37 - cman/notifyd/cman_notify.in | 40 - cman/notifyd/main.c | 382 - cman/qdisk/Makefile | 51 - cman/qdisk/README | 1 - cman/qdisk/bitmap.c | 88 - cman/qdisk/crc32.c | 97 - cman/qdisk/daemon_init.c | 227 - cman/qdisk/disk.c | 757 - cman/qdisk/disk.h | 282 - cman/qdisk/disk_util.c | 260 - cman/qdisk/main.c | 1707 -- cman/qdisk/mkqdisk.c | 94 - cman/qdisk/platform.h | 40 - cman/qdisk/proc.c | 259 - cman/qdisk/scandisk.c | 761 - cman/qdisk/scandisk.h | 87 - cman/qdisk/score.c | 419 - cman/qdisk/score.h | 44 - cman/tests/Makefile | 23 - cman/tests/client.c | 113 - cman/tests/libtest.c | 132 - cman/tests/qwait.c | 58 - cman/tests/sysman.c | 72 - cman/tests/sysmand.c | 469 - cman/tests/user_service.c | 285 - common/Makefile | 4 - common/liblogthread/Makefile | 13 - common/liblogthread/liblogthread.c | 224 - common/liblogthread/liblogthread.h | 17 - config/Makefile | 4 - config/daemons/Makefile | 8 - config/daemons/ccsd/Makefile | 37 - config/daemons/ccsd/ccsd.c | 922 - config/daemons/ccsd/cluster_mgr.c | 688 - config/daemons/ccsd/cluster_mgr.h | 6 - config/daemons/ccsd/cnx_mgr.c | 1399 - config/daemons/ccsd/cnx_mgr.h | 7 - config/daemons/ccsd/comm_headers.h | 48 - config/daemons/ccsd/debug.h | 9 - config/daemons/ccsd/globals.c | 19 - config/daemons/ccsd/globals.h | 23 - config/daemons/ccsd/misc.c | 288 - config/daemons/ccsd/misc.h | 19 - config/daemons/man/Makefile | 9 - config/daemons/man/ccsd.8 | 74 - config/libs/Makefile | 7 - config/libs/libccscompat/Makefile | 15 - config/libs/libccscompat/libccscompat.c | 752 - config/libs/libccscompat/libccscompat.h | 18 - config/libs/libccsconfdb/Makefile | 24 - config/libs/libccsconfdb/ccs.h | 24 - config/libs/libccsconfdb/ccs_internal.h | 29 - config/libs/libccsconfdb/extras.c | 382 - config/libs/libccsconfdb/fullxpath.c | 334 - config/libs/libccsconfdb/libccs.c | 710 - config/libs/libccsconfdb/xpathlite.c | 424 - config/man/Makefile | 5 - config/man/ccs.7 | 22 - config/man/cluster.conf.5 | 61 - config/plugins/Makefile | 7 - config/plugins/ccsais/Makefile | 33 - config/plugins/ccsais/config.c | 236 - config/plugins/ldap/99cluster.ldif | 138 - config/plugins/ldap/Makefile | 30 - config/plugins/ldap/configldap.c | 279 - config/plugins/ldap/example.ldif | 137 - config/plugins/xml/Makefile | 28 - config/plugins/xml/config.c | 317 - config/tools/Makefile | 4 - config/tools/ccs_tool/Makefile | 53 - config/tools/ccs_tool/ccs_tool.c | 353 - config/tools/ccs_tool/editconf.c | 1262 - config/tools/ccs_tool/editconf.h | 8 - config/tools/ccs_tool/update.c | 673 - config/tools/ccs_tool/update.h | 6 - config/tools/ldap/Makefile | 27 - config/tools/ldap/confdb2ldif.c | 201 - config/tools/man/Makefile | 10 - config/tools/man/ccs_test.8 | 132 - config/tools/man/ccs_tool.8 | 185 - config/tools/man/confdb2ldif.8 | 64 - configure | 511 +- contrib/Makefile | 6 - contrib/askant/INSTALL | 42 - contrib/askant/Makefile | 24 - contrib/askant/PLUGINAPI | 65 - contrib/askant/README | 74 - contrib/askant/askant/about.py | 5 - contrib/askant/askant/askant.py | 24 - contrib/askant/askant/blktrace.py | 93 - contrib/askant/askant/commands.py | 333 - contrib/askant/askant/sysfs.py | 86 - contrib/askant/fsplugins/gfs2/gfs2.c | 405 - contrib/askant/fsplugins/gfs2/gfs2.h | 3 - contrib/askant/fsplugins/gfs2/gfs2module.c | 104 - contrib/askant/scripts/askant | 6 - contrib/askant/setup.py | 15 - contrib/libaislock/Makefile | 13 - contrib/libaislock/libaislock.c | 466 - contrib/libaislock/libaislock.h | 190 - dlm/Makefile | 4 - dlm/doc/dlm_tool.txt | 167 - dlm/doc/example.c | 52 - dlm/doc/libdlm.txt | 533 - dlm/doc/user-dlm-overview.txt | 325 - dlm/libdlm/51-dlm.rules | 5 - dlm/libdlm/Makefile | 61 - dlm/libdlm/libdlm.c | 1483 - dlm/libdlm/libdlm.h | 275 - dlm/libdlm/libdlm_internal.h | 9 - dlm/libdlmcontrol/Makefile | 15 - dlm/libdlmcontrol/libdlmcontrol.h | 89 - dlm/libdlmcontrol/main.c | 414 - dlm/man/Makefile | 24 - dlm/man/dlm_cleanup.3 | 1 - dlm/man/dlm_close_lockspace.3 | 1 - dlm/man/dlm_create_lockspace.3 | 94 - dlm/man/dlm_dispatch.3 | 1 - dlm/man/dlm_get_fd.3 | 1 - dlm/man/dlm_lock.3 | 239 - 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_lockx.3 | 1 - dlm/man/dlm_ls_pthread_init.3 | 1 - dlm/man/dlm_ls_unlock.3 | 1 - dlm/man/dlm_ls_unlock_wait.3 | 1 - dlm/man/dlm_new_lockspace.3 | 1 - dlm/man/dlm_open_lockspace.3 | 1 - dlm/man/dlm_pthread_init.3 | 1 - dlm/man/dlm_release_lockspace.3 | 1 - dlm/man/dlm_tool.8 | 39 - dlm/man/dlm_unlock.3 | 94 - dlm/man/dlm_unlock_wait.3 | 1 - dlm/man/libdlm.3 | 105 - dlm/tests/Makefile | 4 - dlm/tests/usertest/Makefile | 23 - dlm/tests/usertest/alternate-lvb.c | 165 - dlm/tests/usertest/asttest.c | 281 - dlm/tests/usertest/dlmtest.c | 291 - dlm/tests/usertest/dlmtest2.c | 1468 - dlm/tests/usertest/flood.c | 167 - dlm/tests/usertest/joinleave.c | 62 - dlm/tests/usertest/lstest.c | 326 - dlm/tests/usertest/lvb.c | 241 - dlm/tests/usertest/pingtest.c | 343 - dlm/tests/usertest/sublocks.c | 178 - dlm/tests/usertest/threads.c | 323 - dlm/tool/Makefile | 32 - dlm/tool/main.c | 766 - doc/COPYRIGHT | 196 +- doc/Makefile | 26 - doc/cluster.logrotate.in | 8 - doc/cman_notify_template.sh | 57 - doc/gfs2.txt | 45 - doc/journaling.txt | 155 - doc/min-gfs.txt | 159 - doc/usage.txt | 177 - fence/Makefile | 4 - fence/agents/Makefile | 15 - fence/agents/alom/Makefile | 5 - fence/agents/alom/fence_alom.py | 69 - fence/agents/apc/Makefile | 5 - fence/agents/apc/fence_apc.py | 216 - fence/agents/apc_snmp/Makefile | 5 - fence/agents/apc_snmp/README | 45 - fence/agents/apc_snmp/fence_apc_snmp.py | 455 - fence/agents/apc_snmp/powernet369.mib |31109 -------------------- fence/agents/baytech/Makefile | 4 - fence/agents/baytech/fence_baytech.pl | 668 - fence/agents/bladecenter/Makefile | 5 - fence/agents/bladecenter/fence_bladecenter.py | 113 - fence/agents/brocade/Makefile | 4 - fence/agents/brocade/fence_brocade.pl | 246 - fence/agents/bullpap/Makefile | 4 - fence/agents/bullpap/fence_bullpap.pl | 357 - fence/agents/cpint/Makefile | 4 - fence/agents/cpint/fence_cpint.pl | 134 - fence/agents/drac/Makefile | 5 - fence/agents/drac/fence_drac.pl | 656 - fence/agents/drac/fence_drac5.py | 78 - fence/agents/drac/test_drac.sh | 83 - fence/agents/egenera/Makefile | 4 - fence/agents/egenera/fence_egenera.pl | 422 - fence/agents/eps/Makefile | 5 - fence/agents/eps/fence_eps.py | 112 - fence/agents/gnbd/Makefile | 25 - fence/agents/gnbd/main.c | 327 - fence/agents/ibmblade/Makefile | 4 - fence/agents/ibmblade/fence_ibmblade.pl | 264 - fence/agents/ifmib/Makefile | 5 - fence/agents/ifmib/README | 45 - fence/agents/ifmib/fence_ifmib.py | 221 - fence/agents/ilo/Makefile | 5 - fence/agents/ilo/fence_ilo.py | 101 - fence/agents/ipmilan/Makefile | 25 - fence/agents/ipmilan/expect.c | 342 - fence/agents/ipmilan/expect.h | 52 - fence/agents/ipmilan/ipmilan.c | 869 - fence/agents/ldom/Makefile | 5 - fence/agents/ldom/fence_ldom.py | 113 - fence/agents/lib/Makefile | 7 - fence/agents/lib/fencing.py.py | 517 - fence/agents/lib/telnet_ssl.py | 72 - fence/agents/lpar/Makefile | 5 - fence/agents/lpar/fence_lpar.py | 120 - fence/agents/manual/Makefile | 19 - fence/agents/manual/fence_ack_manual.sh | 37 - fence/agents/mcdata/Makefile | 4 - fence/agents/mcdata/fence_mcdata.pl | 282 - fence/agents/rackswitch/Makefile | 24 - fence/agents/rackswitch/do_rack.c | 748 - fence/agents/rackswitch/do_rack.h | 27 - fence/agents/rps10/Makefile | 26 - fence/agents/rps10/rps10.c | 521 - fence/agents/rsa/Makefile | 4 - fence/agents/rsa/fence_rsa.py | 286 - fence/agents/rsb/Makefile | 4 - fence/agents/rsb/fence_rsb.py | 376 - fence/agents/sanbox2/Makefile | 4 - fence/agents/sanbox2/fence_sanbox2.pl | 241 - fence/agents/scsi/Makefile | 17 - fence/agents/scsi/fence_scsi.pl | 481 - fence/agents/scsi/fence_scsi_test.pl | 221 - fence/agents/scsi/scsi_reserve.in | 338 - fence/agents/scsi/scsi_reserve_notify.in | 5 - fence/agents/vixel/Makefile | 4 - fence/agents/vixel/fence_vixel.pl | 203 - fence/agents/vmware/Makefile | 4 - fence/agents/vmware/fence_vmware.py | 143 - fence/agents/vmware_vmrun/Makefile | 4 - fence/agents/vmware_vmrun/fence_vmware_vmrun.py | 154 - fence/agents/wti/Makefile | 5 - fence/agents/wti/fence_wti.py | 116 - fence/agents/xcat/Makefile | 4 - fence/agents/xcat/fence_xcat.pl | 188 - fence/agents/xvm/Makefile | 65 - fence/agents/xvm/README | 182 - fence/agents/xvm/TODO | 33 - fence/agents/xvm/debug.c | 20 - fence/agents/xvm/debug.h | 15 - fence/agents/xvm/fence_xvm.c | 375 - fence/agents/xvm/fence_xvmd.c | 1068 - fence/agents/xvm/ip_lookup.c | 308 - fence/agents/xvm/ip_lookup.h | 22 - fence/agents/xvm/mcast.c | 358 - fence/agents/xvm/mcast.h | 16 - fence/agents/xvm/options-ccs.c | 100 - fence/agents/xvm/options.c | 679 - fence/agents/xvm/options.h | 56 - fence/agents/xvm/simple_auth.c | 397 - fence/agents/xvm/simple_auth.h | 17 - fence/agents/xvm/tcp.c | 283 - fence/agents/xvm/tcp.h | 9 - fence/agents/xvm/tests/hvm.xml | 32 - fence/agents/xvm/tests/linux.xml | 31 - fence/agents/xvm/virt.c | 204 - fence/agents/xvm/virt.h | 62 - fence/agents/xvm/vm_states.c | 410 - fence/agents/xvm/xml.c | 317 - fence/agents/xvm/xvm.h | 65 - fence/agents/zvm/Makefile | 4 - fence/agents/zvm/fence_zvm.pl | 344 - fence/fence_node/Makefile | 37 - fence/fence_node/fence_node.c | 110 - fence/fence_tool/Makefile | 34 - fence/fence_tool/fence_tool.c | 660 - fence/fenced/Makefile | 42 - fence/fenced/config.c | 232 - fence/fenced/config.h | 32 - fence/fenced/cpg.c | 1974 -- fence/fenced/fd.h | 282 - fence/fenced/fenced.h | 36 - fence/fenced/group.c | 474 - fence/fenced/logging.c | 171 - fence/fenced/main.c | 1062 - fence/fenced/member_cman.c | 272 - fence/fenced/recover.c | 314 - fence/include/linux_endian.h | 68 - fence/include/list.h | 336 - fence/libfence/Makefile | 17 - fence/libfence/agent.c | 334 - fence/libfence/libfence.h | 14 - fence/libfenced/Makefile | 16 - fence/libfenced/libfenced.h | 40 - fence/libfenced/main.c | 323 - fence/man/Makefile | 32 - fence/man/fence.8 | 30 - fence/man/fence_ack_manual.8 | 36 - fence/man/fence_alom.8 | 84 - fence/man/fence_apc.8 | 98 - fence/man/fence_baytech.8 | 82 - fence/man/fence_bladecenter.8 | 95 - fence/man/fence_brocade.8 | 82 - fence/man/fence_bullpap.8 | 71 - fence/man/fence_cpint.8 | 52 - fence/man/fence_drac.8 | 97 - fence/man/fence_egenera.8 | 70 - fence/man/fence_eps.8 | 106 - fence/man/fence_gnbd.8 | 84 - fence/man/fence_ibmblade.8 | 61 - fence/man/fence_ifmib.8 | 69 - fence/man/fence_ilo.8 | 94 - fence/man/fence_ipmilan.8 | 80 - fence/man/fence_ldom.8 | 114 - fence/man/fence_manual.8 | 49 - fence/man/fence_mcdata.8 | 82 - fence/man/fence_node.8 | 34 - fence/man/fence_rackswitch.8 | 68 - fence/man/fence_rib.8 | 10 - fence/man/fence_rsa.8 | 69 - fence/man/fence_rsb.8 | 75 - fence/man/fence_sanbox2.8 | 82 - fence/man/fence_scsi.8 | 103 - fence/man/fence_tool.8 | 42 - fence/man/fence_vixel.8 | 70 - fence/man/fence_vmware.8 | 131 - fence/man/fence_vmware_vmrun.8 | 137 - fence/man/fence_wti.8 | 83 - fence/man/fence_xcat.8 | 61 - fence/man/fence_xvm.8 | 135 - fence/man/fence_xvmd.8 | 120 - fence/man/fence_zvm.8 | 62 - fence/man/fenced.8 | 296 - gfs-kernel/src/gfs/Makefile | 70 - gfs-kernel/src/gfs/acl.c | 396 - gfs-kernel/src/gfs/acl.h | 34 - gfs-kernel/src/gfs/bits.c | 211 - gfs-kernel/src/gfs/bits.h | 18 - gfs-kernel/src/gfs/bmap.c | 1393 - gfs-kernel/src/gfs/bmap.h | 35 - gfs-kernel/src/gfs/daemon.c | 181 - gfs-kernel/src/gfs/daemon.h | 11 - gfs-kernel/src/gfs/dio.c | 1342 - gfs-kernel/src/gfs/dio.h | 157 - gfs-kernel/src/gfs/dir.c | 2394 -- gfs-kernel/src/gfs/dir.h | 42 - gfs-kernel/src/gfs/eaops.c | 173 - gfs-kernel/src/gfs/eaops.h | 21 - gfs-kernel/src/gfs/eattr.c | 2008 -- gfs-kernel/src/gfs/eattr.h | 97 - gfs-kernel/src/gfs/file.c | 437 - gfs-kernel/src/gfs/file.h | 42 - gfs-kernel/src/gfs/fixed_div64.h | 107 - gfs-kernel/src/gfs/format.h | 17 - gfs-kernel/src/gfs/gfs.h | 89 - gfs-kernel/src/gfs/gfs_ioctl.h | 31 - gfs-kernel/src/gfs/gfs_ondisk.h | 1904 -- gfs-kernel/src/gfs/glock.c | 2996 -- gfs-kernel/src/gfs/glock.h | 138 - gfs-kernel/src/gfs/glops.c | 664 - gfs-kernel/src/gfs/glops.h | 13 - gfs-kernel/src/gfs/incore.h | 1211 - gfs-kernel/src/gfs/inode.c | 2216 -- gfs-kernel/src/gfs/inode.h | 57 - gfs-kernel/src/gfs/ioctl.c | 1605 - gfs-kernel/src/gfs/ioctl.h | 9 - gfs-kernel/src/gfs/lm.c | 233 - gfs-kernel/src/gfs/lm.h | 32 - gfs-kernel/src/gfs/lm_interface.h | 269 - gfs-kernel/src/gfs/lock_dlm.h | 173 - gfs-kernel/src/gfs/lock_dlm_lock.c | 518 - gfs-kernel/src/gfs/lock_dlm_main.c | 31 - gfs-kernel/src/gfs/lock_dlm_mount.c | 270 - gfs-kernel/src/gfs/lock_dlm_sysfs.c | 216 - gfs-kernel/src/gfs/lock_dlm_thread.c | 358 - gfs-kernel/src/gfs/lock_nolock_main.c | 221 - gfs-kernel/src/gfs/locking.c | 171 - gfs-kernel/src/gfs/log.c | 1440 - gfs-kernel/src/gfs/log.h | 66 - gfs-kernel/src/gfs/lops.c | 1648 -- gfs-kernel/src/gfs/lops.h | 166 - gfs-kernel/src/gfs/lvb.c | 135 - gfs-kernel/src/gfs/lvb.h | 53 - gfs-kernel/src/gfs/main.c | 134 - gfs-kernel/src/gfs/mount.c | 166 - gfs-kernel/src/gfs/mount.h | 6 - gfs-kernel/src/gfs/ondisk.c | 15 - gfs-kernel/src/gfs/ops_address.c | 479 - gfs-kernel/src/gfs/ops_address.h | 6 - gfs-kernel/src/gfs/ops_dentry.c | 111 - gfs-kernel/src/gfs/ops_dentry.h | 6 - gfs-kernel/src/gfs/ops_export.c | 403 - gfs-kernel/src/gfs/ops_export.h | 6 - gfs-kernel/src/gfs/ops_file.c | 1853 -- gfs-kernel/src/gfs/ops_file.h | 9 - gfs-kernel/src/gfs/ops_fstype.c | 816 - gfs-kernel/src/gfs/ops_fstype.h | 13 - gfs-kernel/src/gfs/ops_inode.c | 1679 -- gfs-kernel/src/gfs/ops_inode.h | 9 - gfs-kernel/src/gfs/ops_super.c | 455 - gfs-kernel/src/gfs/ops_super.h | 6 - gfs-kernel/src/gfs/ops_vm.c | 233 - gfs-kernel/src/gfs/ops_vm.h | 7 - gfs-kernel/src/gfs/page.c | 266 - gfs-kernel/src/gfs/page.h | 13 - gfs-kernel/src/gfs/proc.c | 491 - gfs-kernel/src/gfs/proc.h | 14 - gfs-kernel/src/gfs/quota.c | 1139 - gfs-kernel/src/gfs/quota.h | 28 - gfs-kernel/src/gfs/recovery.c | 780 - gfs-kernel/src/gfs/recovery.h | 23 - gfs-kernel/src/gfs/rgrp.c | 2152 -- gfs-kernel/src/gfs/rgrp.h | 75 - gfs-kernel/src/gfs/super.c | 1274 - gfs-kernel/src/gfs/super.h | 53 - gfs-kernel/src/gfs/sys.c | 115 - gfs-kernel/src/gfs/sys.h | 14 - gfs-kernel/src/gfs/trans.c | 453 - gfs-kernel/src/gfs/trans.h | 24 - gfs-kernel/src/gfs/unlinked.c | 432 - gfs-kernel/src/gfs/unlinked.h | 19 - gfs-kernel/src/gfs/util.c | 571 - gfs-kernel/src/gfs/util.h | 330 - gfs/Makefile | 23 - gfs/gfs_debug/Makefile | 32 - gfs/gfs_debug/basic.c | 436 - gfs/gfs_debug/basic.h | 26 - gfs/gfs_debug/block_device.c | 117 - gfs/gfs_debug/block_device.h | 14 - gfs/gfs_debug/gfs_debug.h | 83 - gfs/gfs_debug/main.c | 179 - gfs/gfs_debug/ondisk.c | 18 - gfs/gfs_debug/readfile.c | 236 - gfs/gfs_debug/readfile.h | 14 - gfs/gfs_debug/util.c | 334 - gfs/gfs_debug/util.h | 29 - gfs/gfs_fsck/FEATURES | 25 - gfs/gfs_fsck/Makefile | 72 - gfs/gfs_fsck/TODO | 49 - gfs/gfs_fsck/bio.c | 168 - gfs/gfs_fsck/bio.h | 23 - gfs/gfs_fsck/bitmap.c | 118 - gfs/gfs_fsck/bitmap.h | 20 - gfs/gfs_fsck/block_list.c | 263 - gfs/gfs_fsck/block_list.h | 88 - gfs/gfs_fsck/eattr.c | 100 - gfs/gfs_fsck/eattr.h | 21 - gfs/gfs_fsck/file.c | 229 - gfs/gfs_fsck/file.h | 10 - gfs/gfs_fsck/fs_bits.c | 350 - gfs/gfs_fsck/fs_bits.h | 34 - gfs/gfs_fsck/fs_bmap.c | 529 - gfs/gfs_fsck/fs_bmap.h | 10 - gfs/gfs_fsck/fs_dir.c | 1756 -- gfs/gfs_fsck/fs_dir.h | 33 - gfs/gfs_fsck/fs_inode.c | 600 - gfs/gfs_fsck/fs_inode.h | 22 - gfs/gfs_fsck/fs_recovery.c | 75 - gfs/gfs_fsck/fs_recovery.h | 9 - gfs/gfs_fsck/fsck.h | 35 - gfs/gfs_fsck/fsck_incore.h | 136 - gfs/gfs_fsck/hash.c | 91 - gfs/gfs_fsck/hash.h | 7 - gfs/gfs_fsck/initialize.c | 428 - gfs/gfs_fsck/inode.c | 335 - gfs/gfs_fsck/inode.h | 13 - gfs/gfs_fsck/inode_hash.c | 74 - gfs/gfs_fsck/inode_hash.h | 7 - gfs/gfs_fsck/link.c | 94 - gfs/gfs_fsck/link.h | 8 - gfs/gfs_fsck/log.c | 145 - gfs/gfs_fsck/log.h | 87 - gfs/gfs_fsck/lost_n_found.c | 133 - gfs/gfs_fsck/lost_n_found.h | 8 - gfs/gfs_fsck/main.c | 277 - gfs/gfs_fsck/metawalk.c | 862 - gfs/gfs_fsck/metawalk.h | 65 - gfs/gfs_fsck/ondisk.c | 1342 - gfs/gfs_fsck/ondisk.h | 2045 -- gfs/gfs_fsck/pass1.c | 885 - gfs/gfs_fsck/pass1b.c | 521 - gfs/gfs_fsck/pass1c.c | 274 - gfs/gfs_fsck/pass2.c | 888 - gfs/gfs_fsck/pass3.c | 274 - gfs/gfs_fsck/pass4.c | 181 - gfs/gfs_fsck/pass5.c | 365 - gfs/gfs_fsck/rgrp.c | 627 - gfs/gfs_fsck/rgrp.h | 20 - gfs/gfs_fsck/super.c | 1281 - gfs/gfs_fsck/super.h | 11 - gfs/gfs_fsck/test_bitmap.c | 38 - gfs/gfs_fsck/test_block_list.c | 91 - gfs/gfs_fsck/util.c | 333 - gfs/gfs_fsck/util.h | 27 - gfs/gfs_grow/Makefile | 34 - gfs/gfs_grow/main.c | 915 - gfs/gfs_grow/ondisk.c | 18 - gfs/gfs_jadd/Makefile | 34 - gfs/gfs_jadd/main.c | 908 - gfs/gfs_jadd/ondisk.c | 18 - gfs/gfs_mkfs/Makefile | 44 - gfs/gfs_mkfs/device_geometry.c | 153 - gfs/gfs_mkfs/fs_geometry.c | 180 - gfs/gfs_mkfs/locking.c | 102 - gfs/gfs_mkfs/main.c | 426 - gfs/gfs_mkfs/mkfs_gfs.h | 181 - gfs/gfs_mkfs/ondisk.c | 17 - gfs/gfs_mkfs/structures.c | 845 - gfs/gfs_quota/Makefile | 31 - gfs/gfs_quota/check.c | 633 - gfs/gfs_quota/gfs_quota.h | 94 - gfs/gfs_quota/layout.c | 600 - gfs/gfs_quota/main.c | 734 - gfs/gfs_quota/names.c | 84 - gfs/gfs_quota/ondisk.c | 18 - gfs/gfs_tool/Makefile | 35 - gfs/gfs_tool/counters.c | 202 - gfs/gfs_tool/decipher_lockstate_dump | 172 - gfs/gfs_tool/df.c | 257 - gfs/gfs_tool/gfs_tool.h | 90 - gfs/gfs_tool/layout.c | 842 - gfs/gfs_tool/main.c | 264 - gfs/gfs_tool/misc.c | 731 - gfs/gfs_tool/ondisk.c | 21 - gfs/gfs_tool/parse_lockdump | 158 - gfs/gfs_tool/sb.c | 152 - gfs/gfs_tool/tune.c | 135 - gfs/gfs_tool/util.c | 270 - gfs/include/global.h | 42 - gfs/include/linux_endian.h | 68 - gfs/include/list.h | 325 - gfs/include/osi_list.h | 84 - gfs/include/osi_user.h | 421 - gfs/init.d/Makefile | 17 - gfs/init.d/gfs.in | 149 - gfs/libgfs/Makefile | 33 - gfs/libgfs/bio.c | 167 - gfs/libgfs/bitmap.c | 116 - gfs/libgfs/block_list.c | 267 - gfs/libgfs/file.c | 231 - gfs/libgfs/fs_bits.c | 348 - gfs/libgfs/fs_bmap.c | 522 - gfs/libgfs/fs_dir.c | 1683 -- gfs/libgfs/fs_inode.c | 470 - gfs/libgfs/incore.h | 1271 - gfs/libgfs/inode.c | 322 - gfs/libgfs/libgfs.h | 395 - gfs/libgfs/log.c | 136 - gfs/libgfs/ondisk.c | 1282 - gfs/libgfs/rgrp.c | 593 - gfs/libgfs/size.c | 81 - gfs/libgfs/super.c | 531 - gfs/libgfs/util.c | 271 - gfs/man/Makefile | 12 - gfs/man/gfs.8 | 37 - gfs/man/gfs_edit.8 | 1 - gfs/man/gfs_fsck.8 | 59 - gfs/man/gfs_grow.8 | 63 - gfs/man/gfs_jadd.8 | 75 - gfs/man/gfs_mkfs.8 | 82 - gfs/man/gfs_mount.8 | 193 - gfs/man/gfs_quota.8 | 101 - gfs/man/gfs_tool.8 | 137 - gfs/tests/Makefile | 4 - gfs/tests/filecon2/Makefile | 19 - gfs/tests/filecon2/filecon2.h | 146 - gfs/tests/filecon2/filecon2_client.c | 841 - gfs/tests/filecon2/filecon2_server.c | 597 - gfs/tests/mmdd/Makefile | 25 - gfs/tests/mmdd/mmdd.c | 703 - gfs2/Makefile | 4 - gfs2/convert/Makefile | 33 - gfs2/convert/gfs2_convert.c | 1196 - gfs2/edit/Makefile | 37 - gfs2/edit/gfs2hex.c | 581 - gfs2/edit/gfs2hex.h | 10 - gfs2/edit/hexedit.c | 2808 -- gfs2/edit/hexedit.h | 379 - gfs2/edit/savemeta.c | 1107 - gfs2/fsck/FEATURES | 25 - gfs2/fsck/Makefile | 67 - gfs2/fsck/TODO | 49 - gfs2/fsck/eattr.c | 103 - gfs2/fsck/eattr.h | 21 - gfs2/fsck/fs_bits.h | 34 - gfs2/fsck/fs_recovery.c | 429 - gfs2/fsck/fs_recovery.h | 9 - gfs2/fsck/fsck.h | 81 - gfs2/fsck/hash.c | 91 - gfs2/fsck/hash.h | 7 - gfs2/fsck/initialize.c | 396 - gfs2/fsck/inode_hash.c | 77 - gfs2/fsck/inode_hash.h | 9 - gfs2/fsck/link.c | 98 - gfs2/fsck/link.h | 8 - gfs2/fsck/lost_n_found.c | 146 - gfs2/fsck/lost_n_found.h | 8 - gfs2/fsck/main.c | 379 - gfs2/fsck/metawalk.c | 1011 - gfs2/fsck/metawalk.h | 74 - gfs2/fsck/pass1.c | 903 - gfs2/fsck/pass1b.c | 523 - gfs2/fsck/pass1c.c | 271 - gfs2/fsck/pass2.c | 773 - gfs2/fsck/pass3.c | 282 - gfs2/fsck/pass4.c | 173 - gfs2/fsck/pass5.c | 207 - gfs2/fsck/rgrepair.c | 568 - gfs2/fsck/test.c | 8 - gfs2/fsck/test_bitmap.c | 38 - gfs2/fsck/test_block_list.c | 91 - gfs2/fsck/util.c | 81 - gfs2/fsck/util.h | 14 - gfs2/include/gfs2_disk_hash.h | 73 - gfs2/include/global.h | 42 - gfs2/include/linux_endian.h | 68 - gfs2/include/osi_list.h | 84 - gfs2/include/osi_user.h | 421 - gfs2/init.d/Makefile | 17 - gfs2/init.d/gfs2.in | 149 - gfs2/libgfs2/Makefile | 33 - gfs2/libgfs2/bitmap.c | 145 - gfs2/libgfs2/block_list.c | 175 - gfs2/libgfs2/buf.c | 183 - gfs2/libgfs2/device_geometry.c | 90 - gfs2/libgfs2/fs_bits.c | 273 - gfs2/libgfs2/fs_geometry.c | 233 - gfs2/libgfs2/fs_ops.c | 1610 - gfs2/libgfs2/gfs2_log.c | 203 - gfs2/libgfs2/libgfs2.h | 626 - gfs2/libgfs2/locking.c | 57 - gfs2/libgfs2/misc.c | 641 - gfs2/libgfs2/ondisk.c | 599 - gfs2/libgfs2/ondisk.h | 59 - gfs2/libgfs2/recovery.c | 244 - gfs2/libgfs2/rgrp.c | 161 - gfs2/libgfs2/size.c | 82 - gfs2/libgfs2/structures.c | 597 - gfs2/libgfs2/super.c | 264 - gfs2/man/Makefile | 13 - gfs2/man/gfs2.8 | 40 - gfs2/man/gfs2_convert.8 | 46 - gfs2/man/gfs2_edit.8 | 319 - gfs2/man/gfs2_fsck.8 | 59 - gfs2/man/gfs2_grow.8 | 60 - gfs2/man/gfs2_jadd.8 | 60 - gfs2/man/gfs2_mount.8 | 202 - gfs2/man/gfs2_quota.8 | 105 - gfs2/man/gfs2_tool.8 | 138 - gfs2/man/mkfs.gfs2.8 | 95 - gfs2/mkfs/Makefile | 51 - gfs2/mkfs/README | 25 - gfs2/mkfs/gfs2_mkfs.h | 73 - gfs2/mkfs/main.c | 55 - gfs2/mkfs/main_grow.c | 332 - gfs2/mkfs/main_jadd.c | 510 - gfs2/mkfs/main_mkfs.c | 476 - gfs2/mount/Makefile | 38 - gfs2/mount/mount.gfs2.c | 261 - gfs2/mount/mtab.c | 198 - gfs2/mount/ondisk1.c | 19 - gfs2/mount/ondisk2.c | 23 - gfs2/mount/util.c | 572 - gfs2/mount/util.h | 93 - gfs2/quota/Makefile | 35 - gfs2/quota/check.c | 549 - gfs2/quota/gfs2_quota.h | 88 - gfs2/quota/main.c | 1016 - gfs2/quota/names.c | 81 - gfs2/tool/Makefile | 39 - gfs2/tool/decipher_lockstate_dump | 175 - gfs2/tool/df.c | 182 - gfs2/tool/gfs2_tool.h | 63 - gfs2/tool/iflags.h | 40 - gfs2/tool/layout.c | 848 - gfs2/tool/main.c | 269 - gfs2/tool/misc.c | 721 - gfs2/tool/ondisk.c | 13 - gfs2/tool/parse_lockdump | 158 - gfs2/tool/sb.c | 147 - gfs2/tool/tune.c | 106 - gnbd/Makefile | 2 +- gnbd/fence_gnbd/Makefile | 25 + gnbd/fence_gnbd/main.c | 327 + gnbd/man/Makefile | 3 +- gnbd/man/fence_gnbd.8 | 84 + group/Makefile | 4 - group/daemon/Makefile | 34 - group/daemon/app.c | 1842 -- group/daemon/cman.c | 206 - group/daemon/cpg.c | 1053 - group/daemon/gd_internal.h | 324 - group/daemon/groupd.h | 13 - group/daemon/joinleave.c | 165 - group/daemon/logging.c | 170 - group/daemon/main.c | 1079 - group/dlm_controld/Makefile | 51 - group/dlm_controld/action.c | 936 - group/dlm_controld/config.c | 284 - group/dlm_controld/config.h | 53 - group/dlm_controld/cpg.c | 2290 -- group/dlm_controld/crc.c | 72 - group/dlm_controld/deadlock.c | 1547 - group/dlm_controld/dlm_controld.h | 37 - group/dlm_controld/dlm_daemon.h | 353 - group/dlm_controld/group.c | 351 - group/dlm_controld/logging.c | 171 - group/dlm_controld/main.c | 1351 - group/dlm_controld/member_cman.c | 270 - group/dlm_controld/netlink.c | 225 - group/dlm_controld/plock.c | 2152 -- group/gfs_control/Makefile | 31 - group/gfs_control/main.c | 466 - group/gfs_controld/Makefile | 50 - group/gfs_controld/config.c | 201 - group/gfs_controld/config.h | 38 - group/gfs_controld/cpg-new.c | 3462 --- group/gfs_controld/cpg-old.c | 2435 -- group/gfs_controld/cpg-old.h | 73 - group/gfs_controld/crc.c | 72 - group/gfs_controld/gfs_controld.h | 37 - group/gfs_controld/gfs_daemon.h | 337 - group/gfs_controld/group.c | 347 - group/gfs_controld/logging.c | 171 - group/gfs_controld/main.c | 1525 - group/gfs_controld/member_cman.c | 121 - group/gfs_controld/plock.c | 2320 -- group/gfs_controld/util.c | 288 - group/include/linux_endian.h | 68 - group/include/list.h | 336 - group/lib/Makefile | 14 - group/lib/libgroup.c | 524 - group/lib/libgroup.h | 81 - group/libgfscontrol/Makefile | 16 - group/libgfscontrol/libgfscontrol.h | 122 - group/libgfscontrol/main.c | 426 - group/man/Makefile | 7 - group/man/dlm_controld.8 | 123 - group/man/gfs_controld.8 | 122 - group/man/group_tool.8 | 61 - group/man/groupd.8 | 43 - group/test/Makefile | 16 - group/test/client.c | 45 - group/test/clientd.c | 179 - group/tool/Makefile | 38 - group/tool/main.c | 746 - make/binding-passthrough.mk | 7 - make/cobj.mk | 12 - make/defines.mk.input | 68 +- make/fencebuild.mk | 27 - make/install.mk | 48 - make/libs.mk | 47 - make/official_release_version | 1 - make/perl-binding-common.mk | 30 - make/uninstall.mk | 33 - rgmanager/ChangeLog | 629 - rgmanager/Makefile | 4 - rgmanager/README | 359 - rgmanager/errors.txt | 552 - rgmanager/event-script.txt | 305 - rgmanager/examples/cluster.conf | 106 - rgmanager/include/cman-private.h | 14 - rgmanager/include/depends.h | 134 - rgmanager/include/ds.h | 13 - rgmanager/include/event.h | 128 - rgmanager/include/fdops.h | 14 - rgmanager/include/findproc.h | 11 - rgmanager/include/gettid.h | 7 - rgmanager/include/list.h | 94 - rgmanager/include/lock.h | 22 - rgmanager/include/logging.h | 10 - rgmanager/include/members.h | 38 - rgmanager/include/message.h | 160 - rgmanager/include/msgsimple.h | 64 - rgmanager/include/platform.h | 59 - rgmanager/include/pthread_dbg.h | 41 - rgmanager/include/res-ocf.h | 50 - rgmanager/include/resgroup.h | 282 - rgmanager/include/reslist.h | 222 - rgmanager/include/restart_counter.h | 14 - rgmanager/include/rg_locks.h | 34 - rgmanager/include/rg_queue.h | 48 - rgmanager/include/rg_types.h | 18 - rgmanager/include/rmtab.h | 101 - rgmanager/include/sets.h | 22 - rgmanager/include/signals.h | 9 - rgmanager/include/vf.h | 177 - rgmanager/init.d/Makefile | 19 - rgmanager/init.d/rgmanager.in | 192 - rgmanager/man/Makefile | 12 - 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 | 41 - rgmanager/man/clurmtabd.8 | 37 - rgmanager/man/clustat.8 | 53 - rgmanager/man/clusvcadm.8 | 133 - rgmanager/src/Makefile | 4 - rgmanager/src/clulib/Makefile | 49 - rgmanager/src/clulib/alloc.c | 1233 - rgmanager/src/clulib/ckpt_state.c | 535 - rgmanager/src/clulib/cman.c | 248 - rgmanager/src/clulib/daemon_init.c | 225 - rgmanager/src/clulib/fdops.c | 175 - rgmanager/src/clulib/gettid.c | 24 - rgmanager/src/clulib/lock.c | 297 - rgmanager/src/clulib/locktest.c | 67 - rgmanager/src/clulib/logging.c | 233 - rgmanager/src/clulib/members.c | 569 - rgmanager/src/clulib/message.c | 291 - rgmanager/src/clulib/msg_cluster.c | 1266 - rgmanager/src/clulib/msg_socket.c | 426 - rgmanager/src/clulib/msgsimple.c | 108 - rgmanager/src/clulib/msgtest.c | 280 - rgmanager/src/clulib/rg_strings.c | 204 - rgmanager/src/clulib/sets.c | 353 - rgmanager/src/clulib/signals.c | 68 - rgmanager/src/clulib/tmgr.c | 109 - rgmanager/src/clulib/vft.c | 1803 -- rgmanager/src/clulib/wrap_lock.c | 205 - rgmanager/src/daemons/Makefile | 120 - rgmanager/src/daemons/depends.c | 2512 -- rgmanager/src/daemons/dtest.c | 816 - rgmanager/src/daemons/event_config.c | 520 - rgmanager/src/daemons/fo_domain.c | 640 - rgmanager/src/daemons/groups.c | 1832 -- rgmanager/src/daemons/main.c | 1110 - rgmanager/src/daemons/reslist.c | 872 - rgmanager/src/daemons/resrules.c | 1174 - rgmanager/src/daemons/restart_counter.c | 168 - rgmanager/src/daemons/restree.c | 1682 -- rgmanager/src/daemons/rg_event.c | 585 - rgmanager/src/daemons/rg_forward.c | 279 - rgmanager/src/daemons/rg_locks.c | 318 - rgmanager/src/daemons/rg_queue.c | 67 - rgmanager/src/daemons/rg_state.c | 2189 -- rgmanager/src/daemons/rg_thread.c | 732 - rgmanager/src/daemons/sbuf.c | 85 - rgmanager/src/daemons/service_op.c | 196 - rgmanager/src/daemons/slang_event.c | 1241 - rgmanager/src/daemons/test.c | 490 - .../daemons/tests/delta-test001-test002.expected | 22 - .../daemons/tests/delta-test002-test003.expected | 34 - .../daemons/tests/delta-test003-test004.expected | 46 - .../daemons/tests/delta-test004-test005.expected | 58 - .../daemons/tests/delta-test005-test006.expected | 70 - .../daemons/tests/delta-test006-test007.expected | 70 - .../daemons/tests/delta-test007-test008.expected | 80 - .../daemons/tests/delta-test008-test009.expected | 96 - .../daemons/tests/delta-test009-test010.expected | 110 - .../daemons/tests/delta-test010-test011.expected | 180 - .../daemons/tests/delta-test011-test012.expected | 248 - .../daemons/tests/delta-test012-test013.expected | 254 - .../daemons/tests/delta-test013-test014.expected | 319 - .../daemons/tests/delta-test014-test015.expected | 384 - .../daemons/tests/delta-test015-test016.expected | 385 - .../daemons/tests/delta-test016-test017.expected | 408 - rgmanager/src/daemons/tests/deptest1.conf | 63 - rgmanager/src/daemons/tests/deptest1.in | 11 - rgmanager/src/daemons/tests/deptest2.conf | 50 - rgmanager/src/daemons/tests/deptest2.in | 11 - rgmanager/src/daemons/tests/gentests.sh | 74 - rgmanager/src/daemons/tests/runtests.sh | 122 - rgmanager/src/daemons/tests/test001.conf | 7 - rgmanager/src/daemons/tests/test001.expected | 11 - 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 | 11 - 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 | 23 - 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 | 23 - 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 | 35 - 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 | 35 - 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 | 35 - 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 | 45 - 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 | 51 - 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 | 59 - 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 | 121 - 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 | 127 - 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 | 127 - 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 | 192 - 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 | 192 - 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 | 193 - 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 | 215 - 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.start.expected | 24 - rgmanager/src/daemons/tests/test018.stop.expected | 24 - rgmanager/src/daemons/tests/testlist | 4 - rgmanager/src/daemons/watchdog.c | 79 - rgmanager/src/resources/ASEHAagent.sh | 900 - rgmanager/src/resources/Makefile | 77 - rgmanager/src/resources/SAPDatabase | 700 - rgmanager/src/resources/SAPInstance | 408 - rgmanager/src/resources/apache.metadata | 95 - rgmanager/src/resources/apache.sh | 251 - rgmanager/src/resources/clusterfs.sh | 962 - rgmanager/src/resources/default_event_script.sl | 319 - rgmanager/src/resources/fs.sh.in | 1304 - rgmanager/src/resources/ip.sh | 952 - rgmanager/src/resources/lvm.metadata | 86 - rgmanager/src/resources/lvm.sh | 174 - rgmanager/src/resources/lvm_by_lv.sh | 337 - rgmanager/src/resources/lvm_by_vg.sh | 262 - rgmanager/src/resources/mysql.metadata | 96 - rgmanager/src/resources/mysql.sh | 174 - rgmanager/src/resources/named.metadata | 104 - rgmanager/src/resources/named.sh | 193 - rgmanager/src/resources/netfs.sh | 712 - rgmanager/src/resources/nfsclient.sh | 445 - rgmanager/src/resources/nfsexport.sh | 245 - rgmanager/src/resources/nfsserver.sh | 409 - rgmanager/src/resources/ocf-shellfuncs | 165 - rgmanager/src/resources/openldap.metadata | 98 - rgmanager/src/resources/openldap.sh | 209 - rgmanager/src/resources/oracledb.sh.in | 888 - rgmanager/src/resources/postgres-8.metadata | 95 - rgmanager/src/resources/postgres-8.sh | 204 - rgmanager/src/resources/ra-api-1-modified.dtd | 68 - rgmanager/src/resources/samba.metadata | 89 - rgmanager/src/resources/samba.sh | 223 - rgmanager/src/resources/script.sh | 103 - rgmanager/src/resources/service.sh | 280 - rgmanager/src/resources/smb.sh | 674 - rgmanager/src/resources/svclib_nfslock | 260 - rgmanager/src/resources/tomcat-5.metadata | 104 - rgmanager/src/resources/tomcat-5.sh | 256 - rgmanager/src/resources/utils/config-utils.sh.in | 228 - .../src/resources/utils/httpd-parse-config.pl | 65 - rgmanager/src/resources/utils/member_util.sh | 66 - rgmanager/src/resources/utils/messages.sh | 243 - .../src/resources/utils/named-parse-config.pl | 26 - rgmanager/src/resources/utils/ra-skelet.sh | 70 - .../src/resources/utils/tomcat-parse-config.pl | 45 - rgmanager/src/resources/vm.sh | 576 - rgmanager/src/utils/Makefile | 75 - rgmanager/src/utils/cluarp.c | 158 - rgmanager/src/utils/clubufflush.c | 121 - rgmanager/src/utils/clufindhostname.c | 75 - rgmanager/src/utils/clulog.c | 56 - rgmanager/src/utils/clunfslock.sh | 69 - rgmanager/src/utils/clunfsops.c | 224 - rgmanager/src/utils/clustat.c | 1148 - rgmanager/src/utils/clusvcadm.c | 442 - rgmanager/src/utils/syscall.h | 165 - scripts/fenceparse | 35 - 1035 files changed, 449 insertions(+), 292205 deletions(-) diff --git a/Makefile b/Makefile index 05685c6..c665f5c 100644 --- a/Makefile +++ b/Makefile @@ -1,26 +1,9 @@ include make/defines.mk -REALSUBDIRS = gnbd-kernel/src gfs-kernel/src/gfs \ - common cman/lib config cman dlm fence/libfenced group \ - fence gfs gfs2 gnbd rgmanager bindings doc \ - contrib +REALSUBDIRS = gnbd-kernel/src gnbd SUBDIRS = $(filter-out \ - $(if ${without_common},common) \ $(if ${without_gnbd-kernel/src},gnbd-kernel/src) \ - $(if ${without_gfs-kernel/src/gfs},gfs-kernel/src/gfs) \ - $(if ${without_config},config) \ - $(if ${without_cman},cman/lib) \ - $(if ${without_cman},cman) \ - $(if ${without_dlm},dlm) \ - $(if ${without_fence},fence/libfenced) \ - $(if ${without_group},group) \ - $(if ${without_fence},fence) \ - $(if ${without_gfs},gfs) \ - $(if ${without_gfs2},gfs2) \ - $(if ${without_gnbd},gnbd) \ - $(if ${without_rgmanager},rgmanager) \ - $(if ${without_bindings},bindings) \ , $(REALSUBDIRS)) all: ${SUBDIRS} @@ -31,23 +14,8 @@ ${SUBDIRS}: # Kernel gnbd-kernel: gnbd-kernel/src -gfs-kernel: gfs-kernel/src/gfs -# Dependencies - -common: -config: cman/lib -cman: common config -dlm: config -fence/libfenced: -group: cman dlm fence/libfenced -fence: group -gfs: -gfs2: group -gnbd: cman -rgmanager: cman dlm -bindings: cman -contrib: gfs2 +gnbd: oldconfig: @if [ -f $(OBJDIR)/.configure.sh ]; then \ @@ -64,8 +32,6 @@ uninstall: clean: set -e && for i in ${REALSUBDIRS}; do \ - contrib_code=1 \ - legacy_code=1 \ ${MAKE} -C $$i $@;\ done diff --git a/bindings/Makefile b/bindings/Makefile deleted file mode 100644 index 21085c2..0000000 --- a/bindings/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -include ../make/defines.mk -include $(OBJDIR)/make/passthrough.mk - -SUBDIRS=perl python diff --git a/bindings/perl/Makefile b/bindings/perl/Makefile deleted file mode 100644 index cf3a25a..0000000 --- a/bindings/perl/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -include ../../make/defines.mk -include $(OBJDIR)/make/binding-passthrough.mk - -SUBDIRS=ccs diff --git a/bindings/perl/ccs/CCS.pm.in b/bindings/perl/ccs/CCS.pm.in deleted file mode 100644 index 97a3a87..0000000 --- a/bindings/perl/ccs/CCS.pm.in +++ /dev/null @@ -1,145 +0,0 @@ -package Cluster::CCS; - -use strict; -use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); - -require Exporter; -require DynaLoader; - -@ISA = qw(Exporter DynaLoader); -# Items to export into callers namespace by default. Note: do not export -# names by default without a very good reason. Use EXPORT_OK instead. -# Do not simply export all your public functions/methods/constants. -our %EXPORT_TAGS = ( 'all' => [qw( - -)]); -@EXPORT = qw( - -); -@EXPORT_OK = (@{$EXPORT_TAGS{'all'}}); - -our $VERSION = '@VERSION@'; - -require XSLoader; -XSLoader::load('Cluster::CCS', $VERSION); - -sub new { - my $class = shift; - my $self = bless { - @_ - }; - return $self; -} - -1; -__END__ - -=head1 NAME - -Cluster::CCS - Perl wrapper for the Cluster Configuration Service library - -=head1 SYNOPSIS - - use Cluster::CCS; - - my $ccs = new Cluster::CCS(); - - $ccs->fullxpath(1); - - my $ccshandle = $ccs->connect(); - - if ($ccshandle < 1) { - print "Cannot comunicate with libccs\n"; - exit $ccshandle; - } - - my $rtn; - my $err; - - $err = $ccs->get($ccshandle, '/cluster/@name', $rtn); - - if ($err != 0) { - print "Query is not valid\n"; - } - - print "My Cluster name is $rtn\n"; - - $err = $ccs->disconnect($ccshandle); - - if ($err != 0) { - print "Problems disconnecting from libccs\n"; - } - - exit $err; - -=head1 DESCRIPTION - - Cluster::CCS provides a perl XS wrapper for libccs. - -=head1 METHODS - -=head2 new - - Creates a new Cluster::CCS object. - -=head2 fullxpath(value) - - Enable or disable full xpath queries. Set 1 to enable, 0 to disable. - This has to be set before connect() or force_connect. - In order to change this value, a disconnect operation is required. - -=head2 connect(void) - - Initialize the connection to libccs/libconfdb/corosync objdb. - Returns 1 on success or negative on failure. - -=head2 force_connect(cluster_name, blocking) - - Initialize the connection to libccs/libconfdb/corosync objdb. - If blocking is set, it will retry the operation until it succeed. - Returns 1 on success or negative on failure. - -=head2 disconnect(desc) - - Disconnect and free resources allocated during opertaion. - Returns 0 on success. - -=head2 get(desc, query, rtn) - - Perform a simple xpath query. - Returns 0 on success, negative otherwise. On success rtn will contain the - requested data. - -=head2 get_list(desc, query, rtn) - - Perform a simple xpath query and retain some data to iterate over a list of - results. - Returns 0 on success, negative otherwise. On success rtn will contain the - requested data. - -=head2 set(desc, path, val) - - This operation is not yet implemented in libccs. - -=head2 lookup_nodename(desc, nodename, rtn) - - Perform a nodename lookup using several methods. - Return 0 on success and rtn will contain the requested data. - -=head1 EXPORTS - -Nothing is exported by default. - -=head1 BUGS - - https://bugzilla.redhat.com/ - -=head1 SEE ALSO - - cluster.conf(5), ccs(7), ccs_tool(8) - -=head1 AUTHOR - -Fabio M. Di Nitto - -=cut diff --git a/bindings/perl/ccs/CCS.xs b/bindings/perl/ccs/CCS.xs deleted file mode 100644 index 21a651d..0000000 --- a/bindings/perl/ccs/CCS.xs +++ /dev/null @@ -1,82 +0,0 @@ -#include "EXTERN.h" -#include "perl.h" -#include "XSUB.h" - -#include "ccs.h" - -MODULE = Cluster::CCS PACKAGE = Cluster::CCS - -PROTOTYPES: ENABLE - -void -fullxpath(self, value) - int value; - CODE: - fullxpath = value; - -int -connect(self) - CODE: - RETVAL = ccs_connect(); - OUTPUT: - RETVAL - -int -force_connect(self, cluster_name, blocking) - const char *cluster_name; - int blocking; - CODE: - RETVAL = ccs_force_connect(cluster_name, blocking); - OUTPUT: - RETVAL - -int -disconnect(self, desc) - int desc; - CODE: - RETVAL = ccs_disconnect(desc); - OUTPUT: - RETVAL - -int -get(self, desc, query, rtn) - int desc; - const char *query; - char *rtn; - CODE: - RETVAL = ccs_get(desc, query, &rtn); - OUTPUT: - RETVAL - rtn - -int -get_list(self, desc, query, rtn) - int desc; - const char *query; - char *rtn; - CODE: - RETVAL = ccs_get_list(desc, query, &rtn); - OUTPUT: - RETVAL - rtn - -int -set(self, desc, path, val) - int desc; - char *path; - char *val; - CODE: - RETVAL = ccs_set(desc, path, val); - OUTPUT: - RETVAL - -int -lookup_nodename(self, desc, nodename, rtn) - int desc; - const char *nodename; - char *rtn; - CODE: - RETVAL = ccs_lookup_nodename(desc, nodename, &rtn); - OUTPUT: - RETVAL - rtn diff --git a/bindings/perl/ccs/MANIFEST b/bindings/perl/ccs/MANIFEST deleted file mode 100644 index c089dd7..0000000 --- a/bindings/perl/ccs/MANIFEST +++ /dev/null @@ -1,7 +0,0 @@ -CCS.pm -CCS.xs -Makefile.PL -MANIFEST -test.pl -typemap -META.yml Module meta-data (added by MakeMaker) diff --git a/bindings/perl/ccs/META.yml.in b/bindings/perl/ccs/META.yml.in deleted file mode 100644 index 32ae9a3..0000000 --- a/bindings/perl/ccs/META.yml.in +++ /dev/null @@ -1,13 +0,0 @@ ---- #YAML:1.0 -name: Cluster-CCS -version: @VERSION@ -abstract: ~ -license: ~ -author: - - Fabio M. Di Nitto -generated_by: ExtUtils::MakeMaker version 6.42 -distribution_type: module -requires: -meta-spec: - url: http://module-build.sourceforge.net/META-spec-v1.3.html - version: 1.3 diff --git a/bindings/perl/ccs/Makefile.PL b/bindings/perl/ccs/Makefile.PL deleted file mode 100644 index b5504ea..0000000 --- a/bindings/perl/ccs/Makefile.PL +++ /dev/null @@ -1,28 +0,0 @@ -use ExtUtils::MakeMaker; - -my %INFOS = ( - 'NAME' => 'Cluster::CCS', - 'VERSION_FROM' => 'CCS.pm', # finds $VERSION - 'AUTHOR' => 'Fabio M. Di Nitto ', - 'ABSTRACT' => 'Interface to Cluster Configuration Service library', -); - -# read extra configurations from the commandline -my %params; -@params{qw(DEBUG DEFINE EXTRALIBDIR GDOME INC LIBS SKIP_SAX_INSTALL XMLPREFIX)}=(); - -@ARGV = grep { - my ($key, $val) = split(/=/, $_, 2); - if (exists $params{$key}) { - $config{$key} = $val; 0 - } else { 1 } -} @ARGV; - -$extralibdir = $config{EXTRALIBDIR}; -delete $config{EXTRALIBDIR}; - -WriteMakefile( - %INFOS, - %config, -); - diff --git a/bindings/perl/ccs/Makefile.bindings b/bindings/perl/ccs/Makefile.bindings deleted file mode 100644 index 9818a89..0000000 --- a/bindings/perl/ccs/Makefile.bindings +++ /dev/null @@ -1,13 +0,0 @@ -include ../../../make/defines.mk - -PMTARGET = CCS.pm - -TARGET = $(PMTARGET) - -CFLAGS += -I${ccsincdir} -CFLAGS += -I${incdir} - -LDFLAGS += -L${ccslibdir} -lccs -LDFLAGS += -L${libdir} - -include $(OBJDIR)/make/perl-binding-common.mk diff --git a/bindings/perl/ccs/test.pl b/bindings/perl/ccs/test.pl deleted file mode 100644 index 64d740d..0000000 --- a/bindings/perl/ccs/test.pl +++ /dev/null @@ -1,20 +0,0 @@ -# Before `make install' is performed this script should be runnable with -# `make test'. After `make install' it should work as `perl test.pl' - -######################### We start with some black magic to print on failure. - -# Change 1..1 below to 1..last_test_to_print . -# (It may become useful if the test is moved to ./t subdirectory.) - -BEGIN { $| = 1; print "1..1\n"; } -END {print "not ok 1\n" unless $loaded;} -use Cluster::CCS; -$loaded = 1; -print "ok 1\n"; - -######################### End of black magic. - -# Insert your test code below (better if it prints "ok 13" -# (correspondingly "not ok 13") depending on the success of chunk 13 -# of the test code): - diff --git a/bindings/perl/ccs/typemap b/bindings/perl/ccs/typemap deleted file mode 100644 index 02522e8..0000000 --- a/bindings/perl/ccs/typemap +++ /dev/null @@ -1 +0,0 @@ -TYPEMAP diff --git a/bindings/python/Makefile b/bindings/python/Makefile deleted file mode 100644 index 810b2d4..0000000 --- a/bindings/python/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -include ../../make/defines.mk -include $(OBJDIR)/make/passthrough.mk - -SUBDIRS= diff --git a/cman/Makefile b/cman/Makefile deleted file mode 100644 index ead0baa..0000000 --- a/cman/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -include ../make/defines.mk -include $(OBJDIR)/make/passthrough.mk - -SUBDIRS=lib cman_tool daemon qdisk notifyd init.d man diff --git a/cman/cman_tool/Makefile b/cman/cman_tool/Makefile deleted file mode 100644 index 0dee578..0000000 --- a/cman/cman_tool/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -TARGET= cman_tool - -SBINDIRT=$(TARGET) - -all: depends ${TARGET} - -include ../../make/defines.mk -include $(OBJDIR)/make/cobj.mk -include $(OBJDIR)/make/clean.mk -include $(OBJDIR)/make/install.mk -include $(OBJDIR)/make/uninstall.mk - -OBJS= main.o \ - join.o - -CFLAGS += -DCOROSYNCBIN=\"${corosyncbin}\" -CFLAGS += -I${cmanincdir} -CFLAGS += -I${incdir} - -LDFLAGS += -L${cmanlibdir} -lcman -LDFLAGS += -L${libdir} - -${TARGET}: ${OBJS} - $(CC) -o $@ $^ $(LDFLAGS) - -depends: - $(MAKE) -C ../lib all - -clean: generalclean - --include $(OBJS:.o=.d) diff --git a/cman/cman_tool/cman_tool.h b/cman/cman_tool/cman_tool.h deleted file mode 100644 index 7476e1f..0000000 --- a/cman/cman_tool/cman_tool.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef __CMAN_TOOL_DOT_H__ -#define __CMAN_TOOL_DOT_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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_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 - -#define DEBUG_STARTUP_ONLY 32 - -enum format_opt -{ - FMT_NONE, - FMT_ID, - FMT_NAME, - FMT_TYPE, - FMT_ADDR, -}; - -struct commandline -{ - int operation; - int num_nodenames; - char *multicast_addr; - char *nodenames[MAX_INTERFACES]; - char *interfaces[MAX_INTERFACES]; - char *override_nodename; - char *key_filename; - char *filename; - char *format_opts; - char *config_lcrso; - int votes; - int expected_votes; - int two_node; - int port; - char clustername[MAX_CLUSTER_NAME_LEN]; - int remove; - int force; - int verbose; - int nodeid; - 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; - int fence_opt; - int addresses_opt; - int noconfig_opt; - int nosetpri_opt; - int noopenais_opt; -}; -typedef struct commandline commandline_t; - -int join(commandline_t *comline, char *envp[]); -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 72462d2..0000000 --- a/cman/cman_tool/join.c +++ /dev/null @@ -1,254 +0,0 @@ -#include -#include -#include -#include -#include "libcman.h" -#include "cman_tool.h" - -#define MAX_ARGS 128 - -static char *argv[MAX_ARGS]; -static char *envp[MAX_ARGS]; - -static void be_daemon(int close_stderr) -{ - int devnull = open("/dev/null", O_RDWR); - if (devnull == -1) { - perror("Can't open /dev/null"); - exit(3); - } - - /* Detach ourself from the calling environment */ - if (close(0) || close(1)) { - die("Error closing terminal FDs"); - } - - if (dup2(devnull, 0) < 0 || dup2(devnull, 1) < 0) { - die("Error setting terminal FDs to /dev/null: %m"); - } - - if (close_stderr) { - if (close(2)) { - die("Error closing stderr FD"); - } - if (!dup2(devnull, 2) < 0) { - die("Error setting stderr FD to /dev/null: %m"); - } - } - - setsid(); -} - -int join(commandline_t *comline, char *main_envp[]) -{ - int i, err; - int envptr = 0; - int argvptr = 0; - char scratch[1024]; - cman_handle_t h; - int status; - pid_t corosync_pid; - int p[2]; - - /* - * If we can talk to cman then we're already joined (or joining); - */ - h = cman_admin_init(NULL); - if (h) - die("Node is already active"); - - /* Set up environment variables for override */ - if (comline->multicast_addr) { - snprintf(scratch, sizeof(scratch), "CMAN_MCAST_ADDR=%s", comline->multicast_addr); - envp[envptr++] = strdup(scratch); - } - if (comline->votes_opt) { - snprintf(scratch, sizeof(scratch), "CMAN_VOTES=%d", comline->votes); - envp[envptr++] = strdup(scratch); - } - if (comline->expected_votes_opt) { - snprintf(scratch, sizeof(scratch), "CMAN_EXPECTEDVOTES=%d", comline->expected_votes); - envp[envptr++] = strdup(scratch); - } - if (comline->port) { - snprintf(scratch, sizeof(scratch), "CMAN_IP_PORT=%d", comline->port); - envp[envptr++] = strdup(scratch); - } - if (comline->nodeid) { - snprintf(scratch, sizeof(scratch), "CMAN_NODEID=%d", comline->nodeid); - envp[envptr++] = strdup(scratch); - } - if (comline->clustername_opt) { - snprintf(scratch, sizeof(scratch), "CMAN_CLUSTER_NAME=%s", comline->clustername); - envp[envptr++] = strdup(scratch); - } - if (comline->nodenames[0]) { - snprintf(scratch, sizeof(scratch), "CMAN_NODENAME=%s", comline->nodenames[0]); - envp[envptr++] = strdup(scratch); - } - if (comline->key_filename) { - snprintf(scratch, sizeof(scratch), "CMAN_KEYFILE=%s", comline->key_filename); - envp[envptr++] = strdup(scratch); - } - if (comline->two_node) { - snprintf(scratch, sizeof(scratch), "CMAN_2NODE=true"); - envp[envptr++] = strdup(scratch); - } - if (comline->verbose ^ DEBUG_STARTUP_ONLY) { - snprintf(scratch, sizeof(scratch), "CMAN_DEBUGLOG=%d", comline->verbose); - envp[envptr++] = strdup(scratch); - } - if (comline->noconfig_opt) { - envp[envptr++] = strdup("CMAN_NOCONFIG=true"); - snprintf(scratch, sizeof(scratch), "COROSYNC_DEFAULT_CONFIG_IFACE=cmanpreconfig%s", - comline->noopenais_opt?"":":openaisserviceenable"); - envp[envptr++] = strdup(scratch); - } - else { - snprintf(scratch, sizeof(scratch), "COROSYNC_DEFAULT_CONFIG_IFACE=%s:cmanpreconfig%s", comline->config_lcrso, - comline->noopenais_opt?"":":openaisserviceenable"); - envp[envptr++] = strdup(scratch); - } - - /* Copy any COROSYNC_* env variables to the new daemon */ - i=0; - while (i < MAX_ARGS && main_envp[i]) { - if (strncmp(main_envp[i], "COROSYNC_", 9) == 0) - envp[envptr++] = main_envp[i]; - i++; - } - - - /* Create a pipe to monitor cman startup progress */ - if (pipe(p) < 0) - die("unable to create pipe: %s", strerror(errno)); - fcntl(p[1], F_SETFD, 0); /* Don't close on exec */ - snprintf(scratch, sizeof(scratch), "CMAN_PIPE=%d", p[1]); - envp[envptr++] = strdup(scratch); - envp[envptr++] = NULL; - - argv[0] = "corosync"; - if (comline->verbose & ~DEBUG_STARTUP_ONLY) - argv[++argvptr] = "-f"; - if (comline->nosetpri_opt) - argv[++argvptr] = "-p"; - argv[++argvptr] = NULL; - - /* Fork/exec cman */ - switch ( (corosync_pid = fork()) ) - { - case -1: - die("fork of corosync daemon failed: %s", strerror(errno)); - - case 0: /* child */ - close(p[0]); - if (comline->verbose & DEBUG_STARTUP_ONLY) { - fprintf(stderr, "Starting %s", COROSYNCBIN); - for (i=0; i< argvptr; i++) { - fprintf(stderr, " %s", argv[i]); - } - fprintf(stderr, "\n"); - for (i=0; iverbose & ~DEBUG_STARTUP_ONLY)); - execve(COROSYNCBIN, argv, envp); - - /* exec failed - tell the parent process */ - sprintf(scratch, "execve of " COROSYNCBIN " failed: %s", strerror(errno)); - err = write(p[1], scratch, strlen(scratch)); - exit(1); - break; - - default: /* parent */ - break; - - } - - /* Give the daemon a chance to start up, and monitor the pipe FD for messages */ - i = 0; - close(p[1]); - - /* Wait for the process to start or die */ - sleep(1); - do { - fd_set fds; - struct timeval tv={1, 0}; - char message[1024]; - - FD_ZERO(&fds); - FD_SET(p[0], &fds); - - status = select(p[0]+1, &fds, NULL, NULL, &tv); - - /* Did we get an error? */ - if (status == 1) { - int len; - if ((len = read(p[0], message, sizeof(message)) > 0)) { - - /* Success! get the new PID of double-forked corosync */ - if (sscanf(message, "SUCCESS: %d", &corosync_pid) == 1) { - if (comline->verbose & DEBUG_STARTUP_ONLY) - fprintf(stderr, "corosync running, process ID is %d\n", corosync_pid); - status = 0; - } - else { - fprintf(stderr, "cman not started: %s\n", message); - } - break; - } - else if (len < 0 && errno == EINTR) { - continue; - } - else { /* Error or EOF - check the child status */ - int pidstatus; - status = waitpid(corosync_pid, &pidstatus, WNOHANG); - if (status == -1 && errno == ECHILD) { - fprintf(stderr, "cman not started\n"); - break; - } - if (status == 0 && pidstatus != 0) { - if (WIFEXITED(pidstatus)) - fprintf(stderr, "corosync died with status: %d\n", WEXITSTATUS(pidstatus)); - if (WIFSIGNALED(pidstatus)) - fprintf(stderr, "corosync died with signal: %d\n", WTERMSIG(pidstatus)); - status = -1; - break; - } - else { - status = 0; /* Try to connect */ - } - } - } - - } while (status != 0); - close(p[0]); - - /* If corosync has started, try to connect to cman ... if it's still there */ - if (status == 0) { - do { - if (status == 0) { - if (kill(corosync_pid, 0) < 0) { - die("corosync died during startup\n"); - } - - h = cman_admin_init(NULL); - if (!h && comline->verbose & DEBUG_STARTUP_ONLY) - { - fprintf(stderr, "waiting for corosync to start\n"); - } - } - sleep (1); - } while (!h && ++i < 100); - } - - if (!h) - die("corosync daemon didn't start"); - - if ((comline->verbose & DEBUG_STARTUP_ONLY) && !cman_is_active(h)) - fprintf(stderr, "corosync started, but not joined the cluster yet.\n"); - - cman_finish(h); - return 0; -} diff --git a/cman/cman_tool/main.c b/cman/cman_tool/main.c deleted file mode 100644 index 4c6d667..0000000 --- a/cman/cman_tool/main.c +++ /dev/null @@ -1,1067 +0,0 @@ -#include -#include -#include -#include -#include -#include "copyright.cf" -#include "libcman.h" -#include "cman_tool.h" - -#define DEFAULT_CONFIG_MODULE "xmlconfig" - -#define OPTION_STRING ("m:n:v:e:2p:c:r:i:N:t:o:k:F:C:VAPwfqah?Xd::") -#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 -#define OP_DEBUG 11 -#define OP_DUMP_OBJDB 12 - - -static void print_usage(int subcmd) -{ - printf("Usage:\n"); - printf("\n"); - printf("%s [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"); - - if (!subcmd || subcmd == OP_JOIN) { - printf("join\n"); - printf(" Cluster & node information is taken from configuration modules.\n"); - printf(" These switches are provided to allow those values to be overridden.\n"); - printf(" Use them with extreme care.\n\n"); - - printf(" -m Multicast address to use\n"); - printf(" -v Number of votes this node has\n"); - printf(" -e Number of expected votes for the cluster\n"); - printf(" -p UDP port number for cman communications\n"); - printf(" -n The name of this node (defaults to hostname)\n"); - printf(" -c The name of the cluster to join\n"); - printf(" -N Node id\n"); - printf(" -C Config file reader (default: " DEFAULT_CONFIG_MODULE ")\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(" -k Private key file for AIS communications\n"); - printf(" -P Don't set aisexec to realtime priority\n"); - printf(" -X Use internal cman defaults for configuration\n"); - printf(" -A Don't load openais services\n"); - printf("\n"); - } - - - if (!subcmd || subcmd == OP_WAIT) { - 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"); - } - - if (!subcmd || subcmd == OP_LEAVE) { - 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"); - } - - if (!subcmd || subcmd == OP_KILL) { - printf("kill\n"); - printf(" -n The name of the node to kill (can specify multiple times)\n"); - printf("\n"); - } - - if (!subcmd || subcmd == OP_EXPECTED) { - printf("expected\n"); - printf(" -e New number of expected votes for the cluster\n"); - printf("\n"); - } - - if (!subcmd || subcmd == OP_VOTES) { - printf("votes\n"); - printf(" -v New number of votes for this node\n"); - printf("\n"); - } - - if (!subcmd || subcmd == OP_STATUS) { - printf("status Show local record of cluster status\n"); - printf("\n"); - } - - if (!subcmd || subcmd == OP_NODES) { - printf("nodes Show local record of cluster nodes\n"); - printf(" -f Also show when node was last fenced\n"); - printf(" -a Also show node address(es)\n"); - printf(" -n Only show information for specific node\n"); - printf(" -F Specify output format (see man page)\n"); - printf("\n"); - } - - if (!subcmd || subcmd == OP_SERVICES) { - printf("services Show local record of cluster services\n"); - printf("\n"); - } - - if (!subcmd || subcmd == OP_VERSION) { - printf("version\n"); - printf(" -r 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 cman_handle_t open_cman_handle(int priv) -{ - cman_handle_t h; - - if (priv) - h = cman_admin_init(NULL); - else - h = cman_init(NULL); - if (!h) - { - if (errno == EACCES) - die("Cannot open connection to cman, permission denied."); - else - die("Cannot open connection to cman, is it running ?"); - } - return h; -} - -static void print_address(char *addr) -{ - char buf[INET6_ADDRSTRLEN]; - struct sockaddr_storage *ss = (struct sockaddr_storage *)addr; - struct sockaddr_in *sin = (struct sockaddr_in *)addr; - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr; - void *saddr; - - if (ss->ss_family == AF_INET6) - saddr = &sin6->sin6_addr; - else - saddr = &sin->sin_addr; - - inet_ntop(ss->ss_family, saddr, buf, sizeof(buf)); - printf("%s", buf); -} - -static char *membership_state(char *buf, int buflen, int node_state) -{ - switch (node_state) { - case 1: - strncpy(buf, "Joining", buflen); - break; - case 2: - strncpy(buf, "Cluster-Member", buflen); - break; - case 3: - strncpy(buf, "Not-in-Cluster", buflen); - break; - case 4: - strncpy(buf, "Leaving", buflen); - break; - default: - sprintf(buf, "Unknown: code=%d", node_state); - break; - } - - return buf; -} - -static void show_status(void) -{ - cman_cluster_t info; - cman_version_t v; - cman_handle_t h; - cman_node_t node; - char info_buf[PIPE_BUF]; - char tmpbuf[1024]; - cman_extra_info_t *einfo = (cman_extra_info_t *)info_buf; - cman_qdev_info_t qinfo; - int quorate; - int i; - int j; - int portnum; - char *addrptr; - - h = open_cman_handle(0); - - if (cman_get_cluster(h, &info) < 0) - die("Error getting cluster info: %s\n", cman_error(errno)); - if (cman_get_version(h, &v) < 0) - die("Error getting cluster version: %s\n", cman_error(errno)); - if (cman_get_extra_info(h, einfo, sizeof(info_buf)) < 0) - die("Error getting extra info: %s\n", cman_error(errno)); - - quorate = cman_is_quorate(h); - - printf("Version: %d.%d.%d\n", v.cv_major, v.cv_minor, v.cv_patch); - printf("Config Version: %d\n", v.cv_config); - printf("Cluster Name: %s\n", info.ci_name); - printf("Cluster Id: %d\n", info.ci_number); - printf("Cluster Member: Yes\n"); - printf("Cluster Generation: %d\n", info.ci_generation); - printf("Membership state: %s\n", membership_state(tmpbuf, sizeof(tmpbuf), - einfo->ei_node_state)); - printf("Nodes: %d\n", einfo->ei_members); - printf("Expected votes: %d\n", einfo->ei_expected_votes); - if (cman_get_quorum_device(h, &qinfo) == 0 && qinfo.qi_state == 2) - printf("Quorum device votes: %d\n", qinfo.qi_votes); - printf("Total votes: %d\n", einfo->ei_total_votes); - printf("Node votes: %d\n", einfo->ei_node_votes); - - printf("Quorum: %d %s\n", einfo->ei_quorum, quorate?" ":"Activity blocked"); - printf("Active subsystems: %d\n", cman_get_subsys_count(h)); - printf("Flags:"); - if (einfo->ei_flags & CMAN_EXTRA_FLAG_2NODE) - printf(" 2node"); - if (einfo->ei_flags & CMAN_EXTRA_FLAG_SHUTDOWN) - printf(" Shutdown"); - if (einfo->ei_flags & CMAN_EXTRA_FLAG_ERROR) - printf(" Error"); - if (einfo->ei_flags & CMAN_EXTRA_FLAG_DISALLOWED) - printf(" DisallowedNodes"); - if (einfo->ei_flags & CMAN_EXTRA_FLAG_DIRTY) - printf(" Dirty"); - printf(" \n"); - - printf("Ports Bound: "); - portnum = 0; - for (i=0; i<32; i++) { - for (j=0; j<8; j++) { - if ((einfo->ei_ports[i] >> j) & 1) - printf("%d ", portnum); - portnum++; - } - } - printf(" \n"); - - node.cn_name[0] = 0; - if (cman_get_node(h, CMAN_NODEID_US, &node) == 0) { - printf("Node name: %s\n", node.cn_name); - printf("Node ID: %d\n", node.cn_nodeid); - } - - printf("Multicast addresses: "); - addrptr = einfo->ei_addresses; - for (i=0; i < einfo->ei_num_addresses; i++) { - print_address(addrptr); - printf(" "); - addrptr += sizeof(struct sockaddr_storage); - } - printf("\n"); - - printf("Node addresses: "); - for (i=0; i < einfo->ei_num_addresses; i++) { - print_address(addrptr); - printf(" "); - addrptr += sizeof(struct sockaddr_storage); - } - printf("\n"); - - if (einfo->ei_flags & CMAN_EXTRA_FLAG_DISALLOWED) { - int count; - int numnodes; - cman_node_t *nodes; - - count = cman_get_node_count(h); - nodes = malloc(sizeof(cman_node_t) * count); - - if (cman_get_disallowed_nodes(h, count, &numnodes, nodes) == 0) { - printf("Disallowed nodes: "); - for (i=0; icn_nodeid - b->cn_nodeid; -} - -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 print_node(commandline_t *comline, cman_handle_t h, int *format, struct cman_node *node) -{ - char member_type; - struct tm *ftime; - struct tm *jtime; - char jstring[1024]; - int i,j,k; - - if (comline->num_nodenames > 0) { - if (node_filter(comline, node->cn_name) == 0) { - return; - } - } - - switch (node->cn_member) { - case 0: - member_type = 'X'; - break; - case 1: - member_type = 'M'; - break; - case 2: - member_type = 'd'; - break; - default: - member_type = '?'; - break; - } - - jtime = localtime(&node->cn_jointime.tv_sec); - if (node->cn_jointime.tv_sec && node->cn_member) - strftime(jstring, sizeof(jstring), "%F %H:%M:%S", jtime); - else - strcpy(jstring, " "); - - if (!comline->format_opts) { - printf("%4d %c %5d %s %s\n", - node->cn_nodeid, member_type, - node->cn_incarnation, jstring, node->cn_name); - } - - if (comline->fence_opt && !comline->format_opts) { - char agent[255]; - uint64_t fence_time; - int fenced; - - if (!cman_get_fenceinfo(h, node->cn_nodeid, &fence_time, &fenced, agent)) { - if (fence_time) { - time_t fence_time_t = (time_t)fence_time; - ftime = localtime(&fence_time_t); - strftime(jstring, sizeof(jstring), "%F %H:%M:%S", ftime); - printf(" Last fenced: %-15s by %s\n", jstring, agent); - } - if (!node->cn_member && node->cn_incarnation && !fenced) { - printf(" Node has not been fenced since it went down\n"); - } - } - } - - int numaddrs; - struct cman_node_address addrs[MAX_INTERFACES]; - - if (comline->addresses_opt || comline->format_opts) { - if (!cman_get_node_addrs(h, node->cn_nodeid, MAX_INTERFACES, &numaddrs, addrs) && - numaddrs) - { - if (!comline->format_opts) { - printf(" Addresses: "); - for (i = 0; i < numaddrs; i++) - { - print_address(addrs[i].cna_address); - printf(" "); - } - printf("\n"); - } - } - } - - if (comline->format_opts) { - for (j = 0; j < MAX_FORMAT_OPTS; j++) { - switch (format[j]) { - case FMT_NONE: - break; - case FMT_ID: - printf("%d ", node->cn_nodeid); - break; - case FMT_NAME: - printf("%s ", node->cn_name); - break; - case FMT_TYPE: - printf("%c ", member_type); - break; - case FMT_ADDR: - for (k = 0; k < numaddrs; k++) { - print_address(addrs[k].cna_address); - if (k != (numaddrs - 1)) { - printf(","); - } - } - printf(" "); - break; - default: - break; - } - } - printf("\n"); - } -} - -static void show_nodes(commandline_t *comline) -{ - cman_handle_t h; - int count; - int i; - int j; - int numnodes; - int dis_count; - int format[MAX_FORMAT_OPTS]; - cman_node_t *dis_nodes; - cman_node_t *nodes; - - h = open_cman_handle(0); - - count = cman_get_node_count(h); - if (count < 0) - die("cman_get_node_count failed: %s", cman_error(errno)); - - count += 2; /* Extra space! */ - - 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)); - - - /* Get Disallowed nodes, so we can show them as such */ - dis_nodes = malloc(sizeof(cman_node_t) * count); - - if (cman_get_disallowed_nodes(h, count, &dis_count, dis_nodes) == 0) { - for (i = 0; i < numnodes; i++) { - for (j = 0; j < dis_count; j++) { - if (dis_nodes[j].cn_nodeid == nodes[i].cn_nodeid) - nodes[i].cn_member = 2; - } - } - } - - /* Sort by nodeid to be friendly */ - qsort(nodes, numnodes, sizeof(cman_node_t), node_compare); - - if (dis_count) { - printf("NOTE: There are %d disallowed nodes,\n", dis_count); - printf(" members list may seem inconsistent across the cluster\n"); - } - - if (!comline->format_opts) { - printf("Node Sts Inc Joined Name\n"); - } - - /* Print nodes */ - for (i = 0; i < numnodes; i++) { - print_node(comline, h, format, &nodes[i]); - } - - free(nodes); - free(dis_nodes); - cman_finish(h); -} - -static int show_services(void) -{ - return system("group_tool ls"); -} - - -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; - default: - die_error = strerror(errno); - break; - } - return die_error; -} - -static void leave(commandline_t *comline) -{ - cman_handle_t h; - int result; - int flags = 0; - - h = open_cman_handle(1); - - /* "cman_tool leave remove" adjusts quorum downward */ - - if (comline->remove) - flags |= CMAN_SHUTDOWN_REMOVED; - - if (comline->force) - flags |= CMAN_SHUTDOWN_ANYWAY; - - if (comline->wait_opt && comline->timeout) { - signal(SIGALRM, sigalarm_handler); - alarm(comline->timeout); - } - - result = cman_shutdown(h, flags); - if (result) { - die("Error leaving cluster: %s", cman_error(errno)); - } - - cman_finish(h); -} - -static void set_expected(commandline_t *comline) -{ - cman_handle_t h; - int result; - - h = open_cman_handle(1); - - if ((result = cman_set_expected_votes(h, comline->expected_votes))) - die("can't set expected votes: %s", cman_error(errno)); - - cman_finish(h); -} - -static void set_votes(commandline_t *comline) -{ - cman_handle_t h; - int result; - int nodeid; - struct cman_node node; - - - h = open_cman_handle(1); - - if (!comline->num_nodenames) { - nodeid = 0; /* This node */ - } - else { - /* Resolve node name into a number */ - node.cn_nodeid = 0; - strcpy(node.cn_name, comline->nodenames[0]); - if (cman_get_node(h, node.cn_nodeid, &node)) - die("Can't set votes for node %s : %s\n", node.cn_name, strerror(errno)); - nodeid = node.cn_nodeid; - } - - if ((result = cman_set_votes(h, comline->votes, nodeid))) - die("can't set votes: %s", cman_error(errno)); - - cman_finish(h); -} - -static void version(commandline_t *comline) -{ - struct cman_version ver; - cman_handle_t h; - int result; - - h = open_cman_handle(1); - - if ((result = cman_get_version(h, &ver))) - die("can't get version: %s", cman_error(errno)); - - if (!comline->config_version) { - printf("%d.%d.%d config %d\n", ver.cv_major, ver.cv_minor, ver.cv_patch, - ver.cv_config); - goto out; - } - - ver.cv_config = comline->config_version; - - if ((result = cman_set_version(h, &ver))) - die("can't set version: %s", cman_error(errno)); - out: - cman_finish(h); -} - -static int cluster_wait(commandline_t *comline) -{ - cman_handle_t h; - int ret = 0; - - h = open_cman_handle(0); - - if (comline->wait_quorate_opt) { - while (cman_is_quorate(h) <= 0) { - sleep(1); - } - } - else { - while (cman_get_node_count(h) < 0) { - sleep(1); - } - } - - cman_finish(h); - - return ret; -} - -static void kill_node(commandline_t *comline) -{ - cman_handle_t h; - int i; - struct cman_node node; - - if (!comline->num_nodenames) { - die("No node name specified\n"); - } - - h = open_cman_handle(1); - - for (i=0; inum_nodenames; i++) { - - /* Resolve node name into a number */ - node.cn_nodeid = 0; - strcpy(node.cn_name, comline->nodenames[i]); - if (cman_get_node(h, node.cn_nodeid, &node)) { - fprintf(stderr, "Can't kill node %s : %s\n", node.cn_name, strerror(errno)); - continue; - } - - - if (cman_kill_node(h, node.cn_nodeid)) - perror("kill node failed"); - } - - cman_finish(h); -} - -static void set_debuglog(commandline_t *comline) -{ - cman_handle_t h; - - h = open_cman_handle(1); - - if (cman_set_debuglog(h, comline->verbose)) - perror("setting debuglog failed"); - - cman_finish(h); -} - -#ifdef DEBUG -static void dump_objdb(commandline_t *comline) -{ - cman_handle_t h; - - h = open_cman_handle(1); - - if (cman_dump_objdb(h, comline->filename)) - perror("dump objdb failed"); - - cman_finish(h); -} -#endif - -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; - int show_help = 0; - - comline->config_lcrso=DEFAULT_CONFIG_MODULE; - - while (cont) { - optchar = getopt(argc, argv, OPTION_STRING); - - switch (optchar) { - - case 'm': - comline->multicast_addr = strdup(optarg); - break; - - case 'f': - comline->fence_opt = 1; - break; - - case 'a': - comline->addresses_opt = 1; - 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 'o': - comline->override_nodename = strdup(optarg); - break; - - case 'k': - comline->key_filename = strdup(optarg); - break; - - case 'C': - comline->config_lcrso = strdup(optarg); - 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_NODE_NAME_LEN-1) - die("maximum cluster name length is %d", - MAX_CLUSTER_NAME_LEN-1); - strcpy(comline->clustername, optarg); - comline->clustername_opt = TRUE; - break; - - case 'F': - comline->format_opts = strdup(optarg); - break; - - case 'V': - printf("cman_tool %s (built %s %s)\n", - RELEASE_VERSION, __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(EXIT_SUCCESS); - break; - - case 'h': - show_help = 1; - break; - - case ':': - case '?': - fprintf(stderr, "Please use '-h' for usage.\n"); - exit(EXIT_FAILURE); - break; - - case 'd': - if (optarg) - comline->verbose = atoi(optarg); - else - comline->verbose = 255; - 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; - - case 'X': - comline->noconfig_opt = TRUE; - break; - - case 'A': - comline->noopenais_opt = TRUE; - break; - - case 'P': - comline->nosetpri_opt = TRUE; - 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], "debug") == 0) { - if (comline->operation) - die("can't specify two operations"); - comline->operation = OP_DEBUG; -#ifdef DEBUG - } else if (strcmp(argv[optind], "dump-db") == 0) { - if (comline->operation) - die("can't specify two operations"); - comline->operation = OP_DUMP_OBJDB; - if (!argv[optind+1]) - die("no filename given"); - comline->filename = strdup(argv[optind+1]); - if (comline->filename[0] != '/') - die("dump filename must be an absolute path"); - optind++; -#endif - } 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 (show_help) { - print_usage(comline->operation); - exit(EXIT_SUCCESS); - } - - if (!comline->operation) - die("no operation specified"); -} - -static void check_arguments(commandline_t *comline) -{ - if (comline->two_node && comline->expected_votes != 1) - die("expected_votes value (%d) invalid in two node mode", - comline->expected_votes); - - if (comline->port_opt && - (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"); - - if (strlen(comline->clustername) > MAX_CLUSTER_NAME_LEN) { - 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[], char *envp[]) -{ - commandline_t comline; - int ret; - - prog_name = argv[0]; - - memset(&comline, 0, sizeof(commandline_t)); - - decode_arguments(argc, argv, &comline); - - switch (comline.operation) { - case OP_JOIN: - check_arguments(&comline); - - if (comline.timeout) { - signal(SIGALRM, sigalarm_handler); - alarm(comline.timeout); - } - - join(&comline, envp); - if (comline.wait_opt || comline.wait_quorate_opt) { - do { - ret = cluster_wait(&comline); - if (ret == ENOTCONN) - join(&comline, envp); - - } 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: - show_nodes(&comline); - break; - - case OP_SERVICES: - if (show_services() < 0) { - fprintf(stderr, "Unable to invoke group_tool\n"); - exit(EXIT_FAILURE); - } - break; - - case OP_DEBUG: - set_debuglog(&comline); - break; -#ifdef DEBUG - case OP_DUMP_OBJDB: - dump_objdb(&comline); - break; -#endif - } - - exit(EXIT_SUCCESS); -} - -char *prog_name; diff --git a/cman/daemon/Makefile b/cman/daemon/Makefile deleted file mode 100644 index f97c56f..0000000 --- a/cman/daemon/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -TARGET1= service_cman.lcrso -TARGET2= config_cmanpre.lcrso - -LCRSOT=$(TARGET1) $(TARGET2) - -all: depends ${TARGET1} ${TARGET2} - -include ../../make/defines.mk -include $(OBJDIR)/make/cobj.mk -include $(OBJDIR)/make/clean.mk -include $(OBJDIR)/make/install.mk -include $(OBJDIR)/make/uninstall.mk - -CFLAGS += -fPIC -CFLAGS += -I${openaisincdir} -I${corosyncincdir} -CFLAGS += -I${incdir} - -LDFLAGS += -L${libdir} - -OBJS1= daemon.o \ - logging.o \ - ais.o \ - commands.o \ - barrier.o \ - cmanconfig.o - -OBJS2= cman-preconfig.o - -${TARGET1}: ${OBJS1} - $(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS) - -${TARGET2}: ${OBJS2} - $(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS) - -depends: - $(MAKE) -C ../lib all - -clean: generalclean - --include $(OBJS1:.o=.d) --include $(OBJS2:.o=.d) diff --git a/cman/daemon/ais.c b/cman/daemon/ais.c deleted file mode 100644 index bce0f9f..0000000 --- a/cman/daemon/ais.c +++ /dev/null @@ -1,318 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* corosync headers */ -#include -#include -#include -#include - -#include "list.h" -#include "cnxman-socket.h" -#include "cnxman-private.h" -#include "commands.h" -#include "logging.h" - -#include "ais.h" -#include "cman.h" -#define OBJDB_API struct corosync_api_v1 -#include "nodelist.h" -#include "cmanconfig.h" -#include "daemon.h" - -extern int our_nodeid(); -extern char cluster_name[MAX_CLUSTER_NAME_LEN+1]; -extern unsigned int quorumdev_poll; -extern unsigned int ccsd_poll_interval; -extern unsigned int shutdown_timeout; -extern int init_config(struct corosync_api_v1 *api); - -struct totem_ip_address mcast_addr[MAX_INTERFACES]; -struct totem_ip_address ifaddrs[MAX_INTERFACES]; -int num_interfaces; -uint64_t incarnation; -int num_ais_nodes; -extern unsigned int config_version; -static unsigned int cluster_parent_handle; - -static int startup_pipe; -static unsigned int debug_mask; -static int first_trans = 1; -struct corosync_api_v1 *corosync; - -static corosync_tpg_handle group_handle; -static struct corosync_tpg_group cman_group[1] = { - { .group = "CMAN", .group_len = 4}, -}; - -LOGSYS_DECLARE_SUBSYS (CMAN_NAME, LOG_INFO); - -/* 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 (originating) port number */ - unsigned short pad; - unsigned int flags; - int srcid; /* Node ID of the sender */ - int tgtid; /* Node ID of the target */ -}; - -/* Plugin-specific code */ -/* Need some better way of determining these.... */ -#define CMAN_SERVICE 9 - -static int cman_exit_fn(void *conn_info); -static int cman_exec_init_fn(struct corosync_api_v1 *api); -static void cman_confchg_fn(enum totem_configuration_type configuration_type, - unsigned int *member_list, int member_list_entries, - unsigned int *left_list, int left_list_entries, - unsigned int *joined_list, int joined_list_entries, - struct memb_ring_id *ring_id); -static void cman_deliver_fn(unsigned int nodeid, struct iovec *iovec, int iov_len, - int endian_conversion_required); - -/* - * Exports the interface for the service - */ -static struct corosync_service_engine cman_service_handler = { - .name = (char *)"corosync CMAN membership service 2.90", - .id = CMAN_SERVICE, - .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED, - .lib_exit_fn = cman_exit_fn, - .exec_init_fn = cman_exec_init_fn, - .config_init_fn = NULL, -}; - -static struct corosync_service_engine *cman_get_handler_ver0(void) -{ - return (&cman_service_handler); -} - -static struct corosync_service_engine_iface_ver0 cman_service_handler_iface = { - .corosync_get_service_engine_ver0 = cman_get_handler_ver0 -}; - -static struct lcr_iface ifaces_ver0[1] = { - { - .name = "corosync_cman", - .version = 0, - .versions_replace = 0, - .versions_replace_count = 0, - .dependencies = 0, - .dependency_count = 0, - .constructor = NULL, - .destructor = NULL, - .interfaces = NULL, - } -}; - -static struct lcr_comp cman_comp_ver0 = { - .iface_count = 1, - .ifaces = ifaces_ver0, -}; - - - -__attribute__ ((constructor)) static void cman_comp_register(void) { - lcr_interfaces_set(&ifaces_ver0[0], &cman_service_handler_iface); - lcr_component_register(&cman_comp_ver0); -} - -/* ------------------------------- */ - - -static int cman_exec_init_fn(struct corosync_api_v1 *api) -{ - unsigned int object_handle; - unsigned int find_handle; - char pipe_msg[256]; - - corosync = api; - - if (getenv("CMAN_PIPE")) - startup_pipe = atoi(getenv("CMAN_PIPE")); - - /* Get our config variables */ - corosync->object_find_create(OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"), &find_handle); - corosync->object_find_next(find_handle, &cluster_parent_handle); - corosync->object_find_destroy(find_handle); - - corosync->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle); - if (corosync->object_find_next(find_handle, &object_handle) == 0) - { - objdb_get_int(api, object_handle, "quorum_dev_poll", &quorumdev_poll, DEFAULT_QUORUMDEV_POLL); - objdb_get_int(api, object_handle, "shutdown_timeout", &shutdown_timeout, DEFAULT_SHUTDOWN_TIMEOUT); - objdb_get_int(api, object_handle, "ccsd_poll", &ccsd_poll_interval, DEFAULT_CCSD_POLL); - objdb_get_int(api, object_handle, "debug_mask", &debug_mask, 0); - - /* All other debugging options should already have been set in preconfig */ - set_debuglog(debug_mask); - } - corosync->object_find_destroy(find_handle); - P_DAEMON(CMAN_NAME " starting"); - - /* Open local sockets and initialise I/O queues */ - if (read_cman_config(api, &config_version)) { - /* An error message will have been written to cman_pipe */ - exit(9); - } - cman_init(); - - /* Let cman_tool know we are running and our PID */ - sprintf(pipe_msg,"SUCCESS: %d", getpid()); - write_cman_pipe(pipe_msg); - close(startup_pipe); - startup_pipe = 0; - - /* Start totem */ - api->tpg_init(&group_handle, cman_deliver_fn, cman_confchg_fn); - api->tpg_join(group_handle, cman_group, 1); - - return 0; -} - - -int cman_exit_fn(void *conn_info) -{ - cman_finish(); - return 0; -} - -/* END Plugin-specific code */ - -int comms_send_message(void *buf, int len, - unsigned char toport, unsigned char fromport, - int nodeid, - unsigned int flags) -{ - struct iovec iov[2]; - struct cl_protheader header; - int totem_flags = TOTEM_AGREED; - - P_AIS("comms send message %p len = %d\n", buf,len); - header.tgtport = toport; - header.srcport = fromport; - header.flags = flags; - header.srcid = our_nodeid(); - header.tgtid = nodeid; - - iov[0].iov_base = &header; - iov[0].iov_len = sizeof(header); - iov[1].iov_base = buf; - iov[1].iov_len = len; - - if (flags & MSG_TOTEM_SAFE) - totem_flags = TOTEM_SAFE; - - return corosync->tpg_joined_mcast(group_handle, iov, 2, totem_flags); -} - -// This assumes the iovec has only one element ... is it true ?? -static void cman_deliver_fn(unsigned int nodeid, struct iovec *iovec, int iov_len, - int endian_conversion_required) -{ - struct cl_protheader *header = iovec->iov_base; - char *buf = iovec->iov_base; - - P_AIS("deliver_fn source nodeid = %d, len=%d, endian_conv=%d\n", - nodeid, (int)iovec->iov_len, endian_conversion_required); - - if (endian_conversion_required) { - header->srcid = swab32(header->srcid); - header->tgtid = swab32(header->tgtid); - header->flags = swab32(header->flags); - } - - /* Only pass on messages for us or everyone */ - if (header->tgtid == our_nodeid() || - header->tgtid == 0) { - send_to_userport(header->srcport, header->tgtport, - header->srcid, header->tgtid, - buf + sizeof(struct cl_protheader), iovec->iov_len - sizeof(struct cl_protheader), - endian_conversion_required); - } -} - -static void cman_confchg_fn(enum totem_configuration_type configuration_type, - unsigned int *member_list, int member_list_entries, - unsigned int *left_list, int left_list_entries, - unsigned int *joined_list, int joined_list_entries, - struct memb_ring_id *ring_id) -{ - int i; - static int last_memb_count = 0; - static int saved_left_list_entries; - static int saved_left_list_size; - static unsigned int *saved_left_list = NULL; - - P_AIS("confchg_fn called type = %d, seq=%lld\n", configuration_type, ring_id->seq); - - incarnation = ring_id->seq; - num_ais_nodes = member_list_entries; - - /* Tell the cman membership layer */ - for (i=0; i 1) - first_trans = 0; - - cman_send_confchg(member_list, member_list_entries, - saved_left_list, saved_left_list_entries, - joined_list, joined_list_entries); - } -} - -/* Write an error message down the CMAN startup pipe so - that cman_tool can display it */ -int write_cman_pipe(char *message) -{ - if (startup_pipe) - return write(startup_pipe, message, strlen(message)+1); - - return 0; -} diff --git a/cman/daemon/ais.h b/cman/daemon/ais.h deleted file mode 100644 index 4b3e846..0000000 --- a/cman/daemon/ais.h +++ /dev/null @@ -1,10 +0,0 @@ -/* DLM Currently maxes out at 3 ! */ -#define MAX_INTERFACES 8 - -extern int ais_add_ifaddr(char *mcast, char *ifaddr, int portnum); -extern int comms_send_message(void *buf, int len, - unsigned char toport, unsigned char fromport, - int nodeid, - unsigned int flags); -extern uint64_t incarnation; -extern int num_ais_nodes; diff --git a/cman/daemon/barrier.c b/cman/daemon/barrier.c deleted file mode 100644 index 54df19a..0000000 --- a/cman/daemon/barrier.c +++ /dev/null @@ -1,468 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "list.h" -#include "cnxman-socket.h" -#include "cnxman-private.h" -#include "daemon.h" -#include "commands.h" -#include "logging.h" -#include "barrier.h" -#include "cman.h" -#include "ais.h" - -extern int we_are_a_cluster_member; - -LOGSYS_DECLARE_SUBSYS (CMAN_NAME, LOG_INFO); - -/* A barrier */ -struct cl_barrier { - struct list list; - - char name[MAX_BARRIER_NAME_LEN]; - unsigned int flags; - enum { BARRIER_STATE_WAITING, BARRIER_STATE_INACTIVE, - BARRIER_STATE_COMPLETE } state; - unsigned int expected_nodes; - unsigned int got_nodes; - unsigned int waitsent; - unsigned int phase; /* Completion phase */ - unsigned int endreason; /* Reason we were woken, usually 0 */ - unsigned int client_complete; - unsigned long timeout; /* In seconds */ - - struct connection *con; - corosync_timer_handle_t timer; -}; -extern struct corosync_api_v1 *corosync; - -/* A list of all current barriers */ -static struct list barrier_list; - -static void send_barrier_complete_msg(struct cl_barrier *barrier) -{ - if (barrier->timeout) { - corosync->timer_delete(barrier->timer); - barrier->timeout = 0; - } - - if (!barrier->client_complete) { - if (barrier->con) - send_status_return(barrier->con, CMAN_CMD_BARRIER, barrier->endreason); - barrier->client_complete = 1; - } -} - -static struct cl_barrier *find_barrier(char *name) -{ - struct list *blist; - struct cl_barrier *bar; - - list_iterate(blist, &barrier_list) { - bar = list_item(blist, struct cl_barrier); - - if (strcmp(name, bar->name) == 0) - return bar; - } - return NULL; -} - -/* 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 (barrier->got_nodes == ((barrier->expected_nodes != 0) - ? barrier->expected_nodes : - cluster_members)) { - - struct cl_barriermsg bmsg; - - barrier->phase = 2; /* Wait for complete phase II */ - - bmsg.cmd = CLUSTER_MSG_BARRIER; - bmsg.subcmd = BARRIER_COMPLETE; - strcpy(bmsg.name, barrier->name); - - P_BARRIER("Sending COMPLETE for %s\n", barrier->name); - comms_send_message((char *) &bmsg, sizeof (bmsg), - 0, 0, - 0, - MSG_TOTEM_SAFE); - } -} - -/* Do the stuff we need to do when the barrier has been reached */ -/* Return 1 if we deleted the barrier */ -static int barrier_complete_phase2(struct cl_barrier *barrier, int status) -{ - P_BARRIER("complete_phase2 for %s\n", barrier->name); - - barrier->endreason = status; - - /* Wake up listener */ - if (barrier->state == BARRIER_STATE_WAITING) { - send_barrier_complete_msg(barrier); - } - barrier->state = BARRIER_STATE_COMPLETE; - - /* Delete barrier if autodelete */ - if (barrier->flags & BARRIER_ATTR_AUTODELETE) { - list_del(&barrier->list); - free(barrier); - return 1; - } - - return 0; -} - -/* Called if a barrier timeout happens */ -static void barrier_timer_fn(void *arg) -{ - struct cl_barrier *barrier = arg; - - P_BARRIER("Barrier timer_fn called for %s\n", barrier->name); - - /* Ignore any futher messages, they are too late. */ - barrier->phase = 0; - - /* and cause it to timeout */ - barrier_complete_phase2(barrier, -ETIMEDOUT); -} - -static struct cl_barrier *alloc_barrier(char *name, int nodes) -{ - struct cl_barrier *barrier; - - /* Build a new struct and add it to the list */ - barrier = malloc(sizeof (struct cl_barrier)); - if (barrier == NULL) { - return NULL; - } - memset(barrier, 0, sizeof (*barrier)); - - strcpy(barrier->name, name); - barrier->flags = 0; - barrier->expected_nodes = nodes; - barrier->got_nodes = 0; - barrier->endreason = 0; - barrier->state = BARRIER_STATE_INACTIVE; - - list_add(&barrier_list, &barrier->list); - return barrier; -} - -/* Process BARRIER messages from other nodes */ -void process_barrier_msg(struct cl_barriermsg *msg, - struct cluster_node *node) -{ - struct cl_barrier *barrier; - - barrier = find_barrier(msg->name); - - /* Ignore other peoples' messages */ - if (!we_are_a_cluster_member) - 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: - if (barrier->phase == 0) - barrier->phase = 1; - - if (barrier->phase == 1) { - barrier->got_nodes++; - check_barrier_complete_phase1(barrier); - } - break; - - case BARRIER_COMPLETE: - if (!barrier) - return; - /* Once we receive COMPLETE, we know that everyone has completed. - I love VS */ - barrier_complete_phase2(barrier, 0); - break; - } -} - - -/* Barrier API */ -static int barrier_register(struct connection *con, 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 -ENOTCONN; - - /* 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 -EINVAL; - - P_BARRIER("barrier_register %s, nodes = %d, flags =%x\n", name, nodes, flags); - - /* See if it already exists */ - if ((barrier = find_barrier(name))) { - if (nodes != barrier->expected_nodes) { - log_printf(LOG_ERR, "Barrier registration failed for '%s', expected nodes=%d, requested=%d\n", - name, barrier->expected_nodes, nodes); - return -EINVAL; - } - else { - /* Fill this is as it may have been remote registered */ - barrier->con = con; - return 0; - } - } - - barrier = alloc_barrier(name, nodes); - if (!barrier) - return -ENOMEM; - - barrier->flags = flags; - barrier->con = con; - 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) { - return -EINVAL; - } - - /* We need to send WAIT now because the user may not - * actually call barrier_wait() */ - if (!barrier->waitsent) { - struct cl_barriermsg bmsg; - - /* Send it to the rest of the cluster */ - bmsg.cmd = CLUSTER_MSG_BARRIER; - bmsg.subcmd = BARRIER_WAIT; - strcpy(bmsg.name, barrier->name); - - barrier->waitsent = 1; - barrier->phase = 1; - - /* Start the timer if one was wanted */ - if (barrier->timeout) { - corosync->timer_add_duration((unsigned long long)barrier->timeout*1000000000ULL, barrier, - barrier_timer_fn, &barrier->timer); - } - - P_BARRIER("Sending WAIT for %s\n", barrier->name); - status = comms_send_message((char *)&bmsg, sizeof(bmsg), 0,0, 0, MSG_TOTEM_SAFE); - if (status < 0) { - return status; - } - } - if (barrier && barrier->state == BARRIER_STATE_COMPLETE) { - return barrier->endreason; - } - return 0; /* Nothing to propogate */ -} - -static int barrier_setattr(char *name, unsigned int attr, unsigned long arg) -{ - struct cl_barrier *barrier; - - /* See if it already exists */ - if (!(barrier = find_barrier(name))) { - return -ENOENT; - } - - if (barrier->state == BARRIER_STATE_COMPLETE) { - return 0; - } - - switch (attr) { - case BARRIER_SETATTR_AUTODELETE: - if (arg) - barrier->flags |= BARRIER_ATTR_AUTODELETE; - else - barrier->flags &= ~BARRIER_ATTR_AUTODELETE; - return 0; - break; - - case BARRIER_SETATTR_TIMEOUT: - /* Can only change the timout of an inactive barrier */ - if (barrier->state == BARRIER_STATE_WAITING - || barrier->waitsent) { - return -EINVAL; - } - barrier->timeout = arg; - return 0; - - case BARRIER_SETATTR_MULTISTEP: - return -EINVAL; - - 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; - } - - return 0; -} - -static int barrier_delete(char *name) -{ - struct cl_barrier *barrier; - - /* See if it exists */ - if (!(barrier = find_barrier(name))) { - return -ENOENT; - } - - /* Delete it */ - list_del(&barrier->list); - free(barrier); - return 0; -} - -static int barrier_wait(char *name) -{ - struct cl_barrier *barrier; - - /* Enable it */ - barrier_setattr(name, BARRIER_SETATTR_ENABLED, 1L); - - /* See if it still exists - enable may have deleted it! */ - if (!(barrier = find_barrier(name))) { - return -ENOENT; - } - - /* If it has already completed then return the status */ - if (barrier->state == BARRIER_STATE_COMPLETE) { - send_barrier_complete_msg(barrier); - } - else { - barrier->state = BARRIER_STATE_WAITING; - } - - /* User will wait */ - return -EWOULDBLOCK; -} - -/* 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 *blist; - struct cl_barrier *barrier; - int status = 0; - - list_iterate(blist, &barrier_list) { - barrier = list_item(blist, struct cl_barrier); - - if (barrier->waitsent) { - int wakeit = 0; - - /* Check for a dynamic member barrier */ - if (barrier->expected_nodes == 0) { - 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; - send_barrier_complete_msg(barrier); - } - } - } - } -} - -/* Remote command */ -int do_cmd_barrier(struct connection *con, char *cmdbuf, int *retlen) -{ - struct cl_barrier_info info; - - if (!we_are_a_cluster_member) - return -ENOENT; - - memcpy(&info, cmdbuf, sizeof(info)); - - switch (info.cmd) { - case BARRIER_CMD_REGISTER: - return barrier_register(con, - info.name, - info.flags, - info.arg); - case BARRIER_CMD_CHANGE: - return barrier_setattr(info.name, - info.flags, - info.arg); - case BARRIER_CMD_WAIT: - return barrier_wait(info.name); - case BARRIER_CMD_DELETE: - return barrier_delete(info.name); - default: - return -EINVAL; - } -} - -/* Remove any barriers associated with this connection */ -void remove_barriers(struct connection *con) -{ - struct list *blist, *tmp; - struct cl_barrier *bar; - - list_iterate_safe(blist, tmp, &barrier_list) { - bar = list_item(blist, struct cl_barrier); - - if (con == bar->con) { - list_del(&bar->list); - free(bar); - } - } -} - -void barrier_init() -{ - list_init(&barrier_list); -} diff --git a/cman/daemon/barrier.h b/cman/daemon/barrier.h deleted file mode 100644 index 102d8b1..0000000 --- a/cman/daemon/barrier.h +++ /dev/null @@ -1,6 +0,0 @@ -void process_barrier_msg(struct cl_barriermsg *msg, - struct cluster_node *node); -int do_cmd_barrier(struct connection *con, char *cmdbuf, int *retlen); -void barrier_init(void); -void check_barrier_returns(void); -void remove_barriers(struct connection *con); diff --git a/cman/daemon/cman-preconfig.c b/cman/daemon/cman-preconfig.c deleted file mode 100644 index dc20f74..0000000 --- a/cman/daemon/cman-preconfig.c +++ /dev/null @@ -1,1150 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define SYSLOG_NAMES -#include -#include -#include - -/* corosync headers */ -#include -#include -#include -#include - -#include "cman.h" -#define OBJDB_API struct objdb_iface_ver0 -#include "cnxman-socket.h" -#include "nodelist.h" -#include "logging.h" - -#define MAX_PATH_LEN PATH_MAX - -static unsigned int debug_mask; -static int cmanpre_readconfig(struct objdb_iface_ver0 *objdb, char **error_string); -static int cmanpre_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, char **error_string); - -static char *nodename_env; -static int expected_votes; -static int votes; -static int num_interfaces; -static int startup_pipe; -static unsigned int cluster_id; -static char nodename[MAX_CLUSTER_MEMBER_NAME_LEN]; -static int nodeid; -static int two_node; -static unsigned int disable_openais; -static unsigned int portnum; -static int num_nodenames; -static char *key_filename=NULL; -static char *mcast_name; -static char *cluster_name; -static char error_reason[1024] = { '\0' }; -static unsigned int cluster_parent_handle; - -/* - * Exports the interface for the service - */ -static struct config_iface_ver0 cmanpreconfig_iface_ver0 = { - .config_readconfig = cmanpre_readconfig, - .config_reloadconfig = cmanpre_reloadconfig -}; - -static struct lcr_iface ifaces_ver0[2] = { - { - .name = "cmanpreconfig", - .version = 0, - .versions_replace = 0, - .versions_replace_count = 0, - .dependencies = 0, - .dependency_count = 0, - .constructor = NULL, - .destructor = NULL, - .interfaces = NULL, - } -}; - -static struct lcr_comp cmanpre_comp_ver0 = { - .iface_count = 1, - .ifaces = ifaces_ver0, -}; - - - -__attribute__ ((constructor)) static void cmanpre_comp_register(void) { - lcr_interfaces_set(&ifaces_ver0[0], &cmanpreconfig_iface_ver0); - lcr_component_register(&cmanpre_comp_ver0); -} - -static char *facility_name_get (unsigned int facility) -{ - unsigned int i; - - for (i = 0; facilitynames[i].c_name != NULL; i++) { - if (facility == facilitynames[i].c_val) { - return (facilitynames[i].c_name); - } - } - return (NULL); -} - -static char *priority_name_get (unsigned int priority) -{ - unsigned int i; - - for (i = 0; prioritynames[i].c_name != NULL; i++) { - if (priority == prioritynames[i].c_val) { - return (prioritynames[i].c_name); - } - } - return (NULL); -} - - -#define LOCALHOST_IPV4 "127.0.0.1" -#define LOCALHOST_IPV6 "::1" - -/* Compare two addresses */ -static int ipaddr_equal(struct sockaddr_storage *addr1, struct sockaddr_storage *addr2) -{ - int addrlen = 0; - struct sockaddr *saddr1 = (struct sockaddr *)addr1; - struct sockaddr *saddr2 = (struct sockaddr *)addr2; - - if (saddr1->sa_family != saddr2->sa_family) - return 0; - - if (saddr1->sa_family == AF_INET) { - addrlen = sizeof(struct sockaddr_in); - } - if (saddr1->sa_family == AF_INET6) { - addrlen = sizeof(struct sockaddr_in6); - } - assert(addrlen); - - if (memcmp(saddr1, saddr2, addrlen) == 0) - return 1; - else - return 0; - -} - -/* Build a localhost ip_address */ -static int get_localhost(int family, struct sockaddr_storage *localhost) -{ - char *addr_text; - struct addrinfo *ainfo; - struct addrinfo ahints; - int ret; - - if (family == AF_INET) { - addr_text = LOCALHOST_IPV4; - } else { - addr_text = LOCALHOST_IPV6; - } - - memset(&ahints, 0, sizeof(ahints)); - ahints.ai_socktype = SOCK_DGRAM; - ahints.ai_protocol = IPPROTO_UDP; - ahints.ai_family = family; - - /* Lookup the nodename address */ - ret = getaddrinfo(addr_text, NULL, &ahints, &ainfo); - if (ret) - return -1; - - memset(localhost, 0, sizeof(struct sockaddr_storage)); - memcpy(localhost, ainfo->ai_addr, ainfo->ai_addrlen); - - freeaddrinfo(ainfo); - return 0; -} - -/* Return the address family of an IP[46] name */ -static int address_family(char *addr, struct sockaddr_storage *ssaddr) -{ - struct addrinfo *ainfo; - struct addrinfo ahints; - int family; - int ret; - - memset(&ahints, 0, sizeof(ahints)); - ahints.ai_socktype = SOCK_DGRAM; - ahints.ai_protocol = IPPROTO_UDP; - - /* Lookup the nodename address */ - ret = getaddrinfo(addr, NULL, &ahints, &ainfo); - if (ret) - return -1; - - memset(ssaddr, 0, sizeof(struct sockaddr_storage)); - memcpy(ssaddr, ainfo->ai_addr, ainfo->ai_addrlen); - family = ainfo->ai_family; - - freeaddrinfo(ainfo); - return family; -} - - -/* Find the "CMAN" logger_subsys object. Or create one if it does not - exist -*/ -static unsigned int find_cman_logger(struct objdb_iface_ver0 *objdb, unsigned int object_handle) -{ - unsigned int subsys_handle; - unsigned int find_handle; - char *str; - - objdb->object_find_create(object_handle, "logger_subsys", strlen("logger_subsys"), &find_handle); - while (!objdb->object_find_next(object_handle, &subsys_handle)) { - - if (objdb_get_string(objdb, subsys_handle, "subsys", &str)) { - continue; - } - if (strcmp(str, CMAN_NAME) == 0) - return subsys_handle; - } - objdb->object_find_destroy(find_handle); - - /* We can't find it ... create one */ - if (objdb->object_create(object_handle, &subsys_handle, - "logger_subsys", strlen("logger_subsys")) == 0) { - - objdb->object_key_create(subsys_handle, "subsys", strlen("subsys"), - CMAN_NAME, strlen(CMAN_NAME)+1); - } - - return subsys_handle; - -} - - -static int add_ifaddr(struct objdb_iface_ver0 *objdb, char *mcast, char *ifaddr, int portnum) -{ - unsigned int totem_object_handle; - unsigned int find_handle; - unsigned int interface_object_handle; - struct sockaddr_storage if_addr, localhost, mcast_addr; - char tmp[132]; - int ret = 0; - - /* Check the families match */ - if (address_family(mcast, &mcast_addr) != - address_family(ifaddr, &if_addr)) { - sprintf(error_reason, "Node address family does not match multicast address family"); - return -1; - } - - /* Check it's not bound to localhost, sigh */ - get_localhost(if_addr.ss_family, &localhost); - if (ipaddr_equal(&localhost, &if_addr)) { - sprintf(error_reason, "Node address is localhost, please choose a real host address"); - return -1; - } - - objdb->object_find_create(OBJECT_PARENT_HANDLE, "totem", strlen("totem"), &find_handle); - if (objdb->object_find_next(find_handle, &totem_object_handle)) { - - objdb->object_create(OBJECT_PARENT_HANDLE, &totem_object_handle, - "totem", strlen("totem")); - } - objdb->object_find_destroy(find_handle); - - if (objdb->object_create(totem_object_handle, &interface_object_handle, - "interface", strlen("interface")) == 0) { - - sprintf(tmp, "%d", num_interfaces); - objdb->object_key_create(interface_object_handle, "ringnumber", strlen("ringnumber"), - tmp, strlen(tmp)+1); - - objdb->object_key_create(interface_object_handle, "bindnetaddr", strlen("bindnetaddr"), - ifaddr, strlen(ifaddr)+1); - - objdb->object_key_create(interface_object_handle, "mcastaddr", strlen("mcastaddr"), - mcast, strlen(mcast)+1); - - sprintf(tmp, "%d", portnum); - objdb->object_key_create(interface_object_handle, "mcastport", strlen("mcastport"), - tmp, strlen(tmp)+1); - - num_interfaces++; - } - return ret; -} - -static uint16_t generate_cluster_id(char *name) -{ - int i; - int value = 0; - - for (i=0; iai_family; - freeaddrinfo(ainfo); - - if (family == AF_INET) { - snprintf(addr, sizeof(addr), "239.192.%d.%d", cluster_id >> 8, cluster_id % 0xFF); - return addr; - } - if (family == AF_INET6) { - snprintf(addr, sizeof(addr), "ff15::%x", cluster_id); - return addr; - } - - return NULL; -} - -static int verify_nodename(struct objdb_iface_ver0 *objdb, char *nodename) -{ - char nodename2[MAX_CLUSTER_MEMBER_NAME_LEN+1]; - char nodename3[MAX_CLUSTER_MEMBER_NAME_LEN+1]; - char *str, *dot = NULL; - struct ifaddrs *ifa, *ifa_list; - struct sockaddr *sa; - unsigned int nodes_handle; - unsigned int find_handle = 0; - int error; - - /* nodename is either from commandline or from uname */ - if (nodelist_byname(objdb, cluster_parent_handle, nodename)) - return 0; - - /* If nodename was from uname, try a domain-less version of it */ - strcpy(nodename2, nodename); - dot = strchr(nodename2, '.'); - if (dot) { - *dot = '\0'; - - if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) { - strcpy(nodename, nodename2); - return 0; - } - } - - /* If nodename (from uname) is domain-less, try to match against - cluster.conf names which may have domainname specified */ - nodes_handle = nodeslist_init(objdb, cluster_parent_handle, &find_handle); - do { - int len; - - if (objdb_get_string(objdb, nodes_handle, "name", &str)) { - sprintf(error_reason, "Cannot get node name"); - nodes_handle = nodeslist_next(objdb, find_handle); - continue; - } - - strcpy(nodename3, str); - dot = strchr(nodename3, '.'); - if (dot) - len = dot-nodename3; - else - len = strlen(nodename3); - - if (strlen(nodename2) == len && - !strncmp(nodename2, nodename3, len)) { - strcpy(nodename, str); - return 0; - } - nodes_handle = nodeslist_next(objdb, find_handle); - } while (nodes_handle); - objdb->object_find_destroy(find_handle); - - - /* The cluster.conf names may not be related to uname at all, - they may match a hostname on some network interface. - NOTE: This is IPv4 only */ - error = getifaddrs(&ifa_list); - if (error) - return -1; - - for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) { - /* Restore this */ - strcpy(nodename2, nodename); - 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; - - if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) { - strcpy(nodename, nodename2); - goto out; - } - - /* truncate this name and try again */ - - dot = strchr(nodename2, '.'); - if (!dot) - continue; - *dot = '\0'; - - if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) { - strcpy(nodename, nodename2); - goto out; - } - - /* See if it's the IP address that's in cluster.conf */ - error = getnameinfo(sa, sizeof(*sa), nodename2, - sizeof(nodename2), NULL, 0, NI_NUMERICHOST); - if (error) - goto out; - - if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) { - strcpy(nodename, nodename2); - goto out; - } - } - - error = -1; - out: - freeifaddrs(ifa_list); - return error; -} - -/* Get any environment variable overrides */ -static int get_env_overrides() -{ - if (getenv("CMAN_CLUSTER_NAME")) { - cluster_name = strdup(getenv("CMAN_CLUSTER_NAME")); - } - - nodename_env = getenv("CMAN_NODENAME"); - - expected_votes = 0; - if (getenv("CMAN_EXPECTEDVOTES")) { - expected_votes = atoi(getenv("CMAN_EXPECTEDVOTES")); - if (expected_votes < 1) { - expected_votes = 0; - } - } - - /* optional port */ - if (getenv("CMAN_IP_PORT")) { - portnum = atoi(getenv("CMAN_IP_PORT")); - } - - /* optional security key filename */ - if (getenv("CMAN_KEYFILE")) { - key_filename = strdup(getenv("CMAN_KEYFILE")); - if (key_filename == NULL) { - write_cman_pipe("Cannot allocate memory for key filename"); - return -1; - } - } - - /* find our own number of votes */ - if (getenv("CMAN_VOTES")) { - votes = atoi(getenv("CMAN_VOTES")); - } - - /* nodeid */ - if (getenv("CMAN_NODEID")) { - nodeid = atoi(getenv("CMAN_NODEID")); - } - - if (getenv("CMAN_MCAST_ADDR")) { - mcast_name = getenv("CMAN_MCAST_ADDR"); - } - - if (getenv("CMAN_2NODE")) { - two_node = 1; - expected_votes = 1; - votes = 1; - } - if (getenv("CMAN_DEBUGLOG")) { - debug_mask = atoi(getenv("CMAN_DEBUGLOG")); - } - - return 0; -} - - -static int get_nodename(struct objdb_iface_ver0 *objdb) -{ - char *nodeid_str = NULL; - unsigned int object_handle; - unsigned int find_handle; - unsigned int node_object_handle; - unsigned int alt_object; - int error; - - if (!getenv("CMAN_NOCONFIG")) { - /* our nodename */ - if (nodename_env != NULL) { - if (strlen(nodename_env) >= sizeof(nodename)) { - sprintf(error_reason, "Overridden node name %s is too long", nodename); - write_cman_pipe("Overridden node name is too long"); - error = -1; - goto out; - } - - strcpy(nodename, nodename_env); - - if (!(node_object_handle = nodelist_byname(objdb, cluster_parent_handle, nodename))) { - sprintf(error_reason, "Overridden node name %s is not in CCS", nodename); - write_cman_pipe("Overridden node name is not in CCS"); - error = -1; - goto out; - } - - } else { - struct utsname utsname; - - error = uname(&utsname); - if (error) { - sprintf(error_reason, "cannot get node name, uname failed"); - write_cman_pipe("Can't determine local node name"); - error = -1; - goto out; - } - - if (strlen(utsname.nodename) >= sizeof(nodename)) { - sprintf(error_reason, "node name from uname is too long"); - write_cman_pipe("Can't determine local node name"); - error = -1; - goto out; - } - - strcpy(nodename, utsname.nodename); - } - if (verify_nodename(objdb, nodename)) - return -1; - - } - - /* Add bits to pass down to the main module*/ - if ( (node_object_handle = nodelist_byname(objdb, cluster_parent_handle, nodename))) { - if (objdb_get_string(objdb, node_object_handle, "nodeid", &nodeid_str)) { - sprintf(error_reason, "This node has no nodeid in cluster.conf"); - write_cman_pipe("This node has no nodeid in cluster.conf"); - return -1; - } - } - - objdb->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle); - - if (objdb->object_find_next(find_handle, &object_handle) == 0) { - - unsigned int mcast_handle; - unsigned int find_handle2; - - if (!mcast_name) { - - objdb->object_find_create(object_handle, "multicast", strlen("multicast"), &find_handle2); - if (objdb->object_find_next(find_handle2, &mcast_handle) == 0) { - - objdb_get_string(objdb, mcast_handle, "addr", &mcast_name); - } - objdb->object_find_destroy(find_handle2); - } - - if (!mcast_name) { - mcast_name = default_mcast(nodename, cluster_id); - } - - /* See if the user wants our default set of openais services (default=yes) */ - objdb_get_int(objdb, object_handle, "disable_openais", &disable_openais, 0); - - objdb->object_key_create(object_handle, "nodename", strlen("nodename"), - nodename, strlen(nodename)+1); - } - objdb->object_find_destroy(find_handle); - - nodeid = atoi(nodeid_str); - error = 0; - - /* optional port */ - if (!portnum) { - objdb_get_int(objdb, object_handle, "port", &portnum, DEFAULT_PORT); - } - - if (add_ifaddr(objdb, mcast_name, nodename, portnum)) - return -1; - - /* Get all alternative node names */ - num_nodenames = 1; - objdb->object_find_create(node_object_handle,"altname", strlen("altname"), &find_handle); - while (objdb->object_find_next(find_handle, &alt_object) == 0) { - unsigned int port; - char *nodename; - char *mcast; - - if (objdb_get_string(objdb, alt_object, "name", &nodename)) { - continue; - } - - objdb_get_int(objdb, alt_object, "port", &port, portnum); - - if (objdb_get_string(objdb, alt_object, "mcast", &mcast)) { - mcast = mcast_name; - } - - if (add_ifaddr(objdb, mcast, nodename, portnum)) - return -1; - - num_nodenames++; - } - objdb->object_find_destroy(find_handle); - -out: - return error; -} - -/* These are basically cman overrides to the totem config bits */ -static void add_cman_overrides(struct objdb_iface_ver0 *objdb) -{ - unsigned int logger_object_handle; - char *logstr; - char *logfacility; - unsigned int object_handle; - unsigned int find_handle; - char tmp[256]; - - /* "totem" key already exists, because we have added the interfaces by now */ - objdb->object_find_create(OBJECT_PARENT_HANDLE,"totem", strlen("totem"), &find_handle); - if (objdb->object_find_next(find_handle, &object_handle) == 0) - { - char *value; - - objdb->object_key_create(object_handle, "version", strlen("version"), - "2", 2); - - sprintf(tmp, "%d", nodeid); - objdb->object_key_create(object_handle, "nodeid", strlen("nodeid"), - tmp, strlen(tmp)+1); - - objdb->object_key_create(object_handle, "vsftype", strlen("vsftype"), - "none", strlen("none")+1); - - /* Set the token timeout is 10 seconds, but don't overrride anything that - might be in cluster.conf */ - if (objdb_get_string(objdb, object_handle, "token", &value)) { - objdb->object_key_create(object_handle, "token", strlen("token"), - "10000", strlen("10000")+1); - } - if (objdb_get_string(objdb, object_handle, "token_retransmits_before_loss_const", &value)) { - objdb->object_key_create(object_handle, "token_retransmits_before_loss_const", - strlen("token_retransmits_before_loss_const"), - "20", strlen("20")+1); - } - - /* Extend consensus & join timeouts per bz#214290 */ - if (objdb_get_string(objdb, object_handle, "join", &value)) { - objdb->object_key_create(object_handle, "join", strlen("join"), - "60", strlen("60")+1); - } - if (objdb_get_string(objdb, object_handle, "consensus", &value)) { - objdb->object_key_create(object_handle, "consensus", strlen("consensus"), - "4800", strlen("4800")+1); - } - - /* Set RRP mode appropriately */ - if (objdb_get_string(objdb, object_handle, "rrp_mode", &value)) { - if (num_interfaces > 1) { - objdb->object_key_create(object_handle, "rrp_mode", strlen("rrp_mode"), - "active", strlen("active")+1); - } - else { - objdb->object_key_create(object_handle, "rrp_mode", strlen("rrp_mode"), - "none", strlen("none")+1); - } - } - - if (objdb_get_string(objdb, object_handle, "secauth", &value)) { - sprintf(tmp, "%d", 1); - objdb->object_key_create(object_handle, "secauth", strlen("secauth"), - tmp, strlen(tmp)+1); - } - - /* optional security key filename */ - if (!key_filename) { - objdb_get_string(objdb, object_handle, "keyfile", &key_filename); - } - else { - objdb->object_key_create(object_handle, "keyfile", strlen("keyfile"), - key_filename, strlen(key_filename)+1); - } - if (!key_filename) { - /* Use the cluster name as key, - * This isn't a good isolation strategy but it does make sure that - * clusters on the same port/multicast by mistake don't actually interfere - * and that we have some form of encryption going. - */ - - int keylen; - memset(tmp, 0, sizeof(tmp)); - - strcpy(tmp, cluster_name); - - /* Key length must be a multiple of 4 */ - keylen = (strlen(cluster_name)+4) & 0xFC; - objdb->object_key_create(object_handle, "key", strlen("key"), - tmp, keylen); - } - } - objdb->object_find_destroy(find_handle); - - /* Make sure mainconfig doesn't stomp on our logging options */ - objdb->object_find_create(OBJECT_PARENT_HANDLE, "logging", strlen("logging"), &find_handle); - if (objdb->object_find_next(find_handle, &object_handle)) { - - objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle, - "logging", strlen("logging")); - } - objdb->object_find_destroy(find_handle); - - logfacility = facility_name_get(SYSLOGFACILITY); - - logger_object_handle = find_cman_logger(objdb, object_handle); - - if (objdb_get_string(objdb, object_handle, "syslog_facility", &logstr)) { - objdb->object_key_create(object_handle, "syslog_facility", strlen("syslog_facility"), - logfacility, strlen(logfacility)+1); - } - - if (objdb_get_string(objdb, object_handle, "to_file", &logstr)) { - objdb->object_key_create(object_handle, "to_file", strlen("to_file"), - "yes", strlen("yes")+1); - } - - if (objdb_get_string(objdb, object_handle, "logfile", &logstr)) { - objdb->object_key_create(object_handle, "logfile", strlen("logfile"), - LOGDIR "/cman.log", strlen(LOGDIR "/cman.log")+1); - } - - if (debug_mask) { - objdb->object_key_create(object_handle, "to_stderr", strlen("to_stderr"), - "yes", strlen("yes")+1); - objdb->object_key_create(logger_object_handle, "debug", strlen("debug"), - "on", strlen("on")+1); - objdb->object_key_create(logger_object_handle, "syslog_level", strlen("syslog_level"), - "debug", strlen("debug")+1); - - } - else { - char *loglevel; - loglevel = priority_name_get(SYSLOGLEVEL); - objdb->object_key_create(logger_object_handle, "syslog_level", strlen("syslog_level"), - loglevel, strlen(loglevel)+1); - } - - - /* Don't run under user "ais" */ - objdb->object_find_create(OBJECT_PARENT_HANDLE, "aisexec", strlen("aisexec"), &find_handle); - if (objdb->object_find_next(find_handle, &object_handle) != 0) { - objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle, - "aisexec", strlen("aisexec")); - - } - objdb->object_find_destroy(find_handle); - objdb->object_key_create(object_handle, "user", strlen("user"), - "root", strlen("root") + 1); - objdb->object_key_create(object_handle, "group", strlen("group"), - "root", strlen("root") + 1); - - objdb->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle); - if (objdb->object_find_next(find_handle, &object_handle) == 0) - { - char str[255]; - - sprintf(str, "%d", cluster_id); - - objdb->object_key_create(object_handle, "cluster_id", strlen("cluster_id"), - str, strlen(str) + 1); - - if (two_node) { - sprintf(str, "%d", 1); - objdb->object_key_create(object_handle, "two_node", strlen("two_node"), - str, strlen(str) + 1); - } - if (debug_mask) { - sprintf(str, "%d", debug_mask); - objdb->object_key_create(object_handle, "debug_mask", strlen("debug_mask"), - str, strlen(str) + 1); - } - } - objdb->object_find_destroy(find_handle); - - /* Make sure we load our alter-ego - the main cman module */ - objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle, - "service", strlen("service")); - objdb->object_key_create(object_handle, "name", strlen("name"), - "corosync_cman", strlen("corosync_cman") + 1); - objdb->object_key_create(object_handle, "ver", strlen("ver"), - "0", 2); -} - -/* If ccs is not available then use some defaults */ -static int set_noccs_defaults(struct objdb_iface_ver0 *objdb) -{ - char tmp[255]; - unsigned int object_handle; - unsigned int find_handle; - - /* Enforce key */ - key_filename = NOCCS_KEY_FILENAME; - - if (!cluster_name) - cluster_name = DEFAULT_CLUSTER_NAME; - - if (!cluster_id) - cluster_id = generate_cluster_id(cluster_name); - - if (!nodename_env) { - int error; - struct utsname utsname; - - error = uname(&utsname); - if (error) { - sprintf(error_reason, "cannot get node name, uname failed"); - write_cman_pipe("Can't determine local node name"); - return -1; - } - - nodename_env = (char *)&utsname.nodename; - } - strcpy(nodename, nodename_env); - num_nodenames = 1; - - if (!mcast_name) { - mcast_name = default_mcast(nodename, cluster_id); - } - - /* This will increase as nodes join the cluster */ - if (!expected_votes) - expected_votes = 1; - if (!votes) - votes = 1; - - if (!portnum) - portnum = DEFAULT_PORT; - - /* Invent a node ID */ - if (!nodeid) { - struct addrinfo *ainfo; - struct addrinfo ahints; - int ret; - - memset(&ahints, 0, sizeof(ahints)); - ret = getaddrinfo(nodename, NULL, &ahints, &ainfo); - if (ret) { - sprintf(error_reason, "Can't determine address family of nodename %s\n", nodename); - write_cman_pipe("Can't determine address family of nodename"); - return -1; - } - - if (ainfo->ai_family == AF_INET) { - struct sockaddr_in *addr = (struct sockaddr_in *)ainfo->ai_addr; - memcpy(&nodeid, &addr->sin_addr, sizeof(int)); - } - if (ainfo->ai_family == AF_INET6) { - struct sockaddr_in6 *addr = (struct sockaddr_in6 *)ainfo->ai_addr; - memcpy(&nodeid, &addr->sin6_addr.s6_addr32[3], sizeof(int)); - } - freeaddrinfo(ainfo); - } - - /* Write a local entry to keep the rest of the code happy */ - objdb->object_create(cluster_parent_handle, &object_handle, - "clusternodes", strlen("clusternodes")); - objdb->object_create(object_handle, &object_handle, - "clusternode", strlen("clusternode")); - objdb->object_key_create(object_handle, "name", strlen("name"), - nodename, strlen(nodename)+1); - - sprintf(tmp, "%d", votes); - objdb->object_key_create(object_handle, "votes", strlen("votes"), - tmp, strlen(tmp)+1); - - sprintf(tmp, "%d", nodeid); - objdb->object_key_create(object_handle, "nodeid", strlen("nodeid"), - tmp, strlen(tmp)+1); - - /* Write the default cluster name & ID in here too */ - objdb->object_key_create(cluster_parent_handle, "name", strlen("name"), - cluster_name, strlen(cluster_name)+1); - - - objdb->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle); - if (objdb->object_find_next(find_handle, &object_handle) == 0) { - - objdb->object_create(cluster_parent_handle, &object_handle, - "cman", strlen("cman")); - } - sprintf(tmp, "%d", cluster_id); - objdb->object_key_create(object_handle, "cluster_id", strlen("cluster_id"), - tmp, strlen(tmp)+1); - - sprintf(tmp, "%d", expected_votes); - objdb->object_key_create(object_handle, "expected_votes", strlen("expected_votes"), - tmp, strlen(tmp)+1); - - objdb->object_find_destroy(find_handle); - return 0; -} - -/* Move an object/key tree */ -static int copy_config_tree(struct objdb_iface_ver0 *objdb, unsigned int source_object, unsigned int target_parent_object, int always_create) -{ - unsigned int object_handle; - unsigned int new_object; - unsigned int find_handle; - char object_name[1024]; - int object_name_len; - void *key_name; - int key_name_len; - void *key_value; - int key_value_len; - int res; - - /* Create new parent object if necessary */ - objdb->object_name_get(source_object, object_name, &object_name_len); - - objdb->object_find_create(target_parent_object, object_name, strlen(object_name), &find_handle); - if (always_create || objdb->object_find_next(find_handle, &object_handle)) - objdb->object_create(target_parent_object, &new_object, object_name, object_name_len); - objdb->object_find_destroy(find_handle); - - /* Copy the keys */ - objdb->object_key_iter_reset(new_object); - - while (!objdb->object_key_iter(source_object, &key_name, &key_name_len, - &key_value, &key_value_len)) { - - objdb->object_key_create(new_object, key_name, key_name_len, - key_value, key_value_len); - } - - /* Create sub-objects */ - res = objdb->object_find_create(source_object, NULL, 0, &find_handle); - if (res) { - sprintf(error_reason, "error resetting object iterator for object %d: %d\n", source_object, res); - return -1; - } - - while ( (res = objdb->object_find_next(find_handle, &object_handle) == 0)) { - - /* Down we go ... */ - copy_config_tree(objdb, object_handle, new_object, 0); - } - objdb->object_find_destroy(find_handle); - - return 0; -} - -/* - * Copy trees from /cluster where they live in cluster.conf, into the root - * of the config tree where corosync expects to find them. - */ -static int copy_tree_to_root(struct objdb_iface_ver0 *objdb, char *name, int always_create) -{ - unsigned int find_handle; - unsigned int object_handle; - int res=0; - - objdb->object_find_create(cluster_parent_handle, name, strlen(name), &find_handle); - while (objdb->object_find_next(find_handle, &object_handle) == 0) { - res = copy_config_tree(objdb, object_handle, OBJECT_PARENT_HANDLE, always_create); - } - objdb->object_find_destroy(find_handle); - - return res; -} - -static int get_cman_globals(struct objdb_iface_ver0 *objdb) -{ - unsigned int object_handle; - unsigned int find_handle; - - objdb_get_string(objdb, cluster_parent_handle, "name", &cluster_name); - - /* Get the bits that override bits */ - objdb->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle); - if (objdb->object_find_next(find_handle, &object_handle) == 0) { - if (!portnum) - objdb_get_int(objdb, object_handle, "port", &portnum, DEFAULT_PORT); - - if (!key_filename) - objdb_get_string(objdb, object_handle, "keyfile", &key_filename); - - if (!cluster_id) - objdb_get_int(objdb, object_handle, "cluster_id", &cluster_id, 0); - - if (!cluster_id) - cluster_id = generate_cluster_id(cluster_name); - } - objdb->object_find_destroy(find_handle); - return 0; -} - -static int cmanpre_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, char **error_string) -{ - int ret = -1; - unsigned int object_handle; - unsigned int find_handle; - unsigned int cluster_parent_handle_new; - - /* don't reload if we've been told to run configless */ - if (getenv("CMAN_NOCONFIG")) { - sprintf(error_reason, "Config not updated because we were run with cman_tool -X"); - ret = 0; - goto err; - } - - /* find both /cluster entries */ - objdb->object_find_create(OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"), &find_handle); - objdb->object_find_next(find_handle, &cluster_parent_handle); - if (!cluster_parent_handle) { - sprintf (error_reason, "%s", "Cannot find old /cluster/ key in configuration\n"); - goto err; - } - objdb->object_find_next(find_handle, &cluster_parent_handle_new); - if (!cluster_parent_handle_new) { - sprintf (error_reason, "%s", "Cannot find new /cluster/ key in configuration\n"); - goto err; - } - objdb->object_find_destroy(find_handle); - - /* destroy the old one */ - objdb->object_destroy(cluster_parent_handle); - - /* update the reference to the new config */ - cluster_parent_handle = cluster_parent_handle_new; - - /* destroy top level /logging */ - objdb->object_find_create(OBJECT_PARENT_HANDLE, "logging", strlen("logging"), &find_handle); - objdb->object_find_next(find_handle, &object_handle); - objdb->object_find_destroy(find_handle); - if (object_handle) { - objdb->object_destroy(object_handle); - } - - /* copy /cluster/logging to /logging */ - ret = copy_tree_to_root(objdb, "logging", 0); - - return 0; - -err: - *error_string = error_reason; - return ret; -} - -static int cmanpre_readconfig(struct objdb_iface_ver0 *objdb, char **error_string) -{ - int ret = 0; - unsigned int object_handle; - unsigned int find_handle; - - if (getenv("CMAN_PIPE")) - startup_pipe = atoi(getenv("CMAN_PIPE")); - - objdb->object_find_create(OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"), &find_handle); - objdb->object_find_next(find_handle, &cluster_parent_handle); - objdb->object_find_destroy(find_handle); - if (!cluster_parent_handle) { - objdb->object_create(OBJECT_PARENT_HANDLE, &cluster_parent_handle, - "cluster", strlen("cluster")); - } - else { - /* Move these to a place where corosync expects to find them */ - ret = copy_tree_to_root(objdb, "totem", 0); - ret = copy_tree_to_root(objdb, "logging", 0); - ret = copy_tree_to_root(objdb, "event", 0); - ret = copy_tree_to_root(objdb, "amf", 0); - ret = copy_tree_to_root(objdb, "aisexec", 0); - ret = copy_tree_to_root(objdb, "service", 1); - } - - objdb->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle); - if (objdb->object_find_next(find_handle, &object_handle)) { - objdb->object_create(cluster_parent_handle, &object_handle, - "cman", strlen("cman")); - } - objdb->object_find_destroy(find_handle); - - /* This will create /libccs/@next_handle. - * next_handle will be atomically incremented by corosync to return ccs_handle down the pipe. - * We create it in cman-preconfig to avoid an "init" race in libccs. - */ - - objdb->object_find_create(OBJECT_PARENT_HANDLE, "libccs", strlen("libccs"), &find_handle); - if (objdb->object_find_next(find_handle, &object_handle)) { - int next_handle = 0; - - objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle, - "libccs", strlen("libccs")); - - objdb->object_key_create(object_handle, "next_handle", strlen("next_handle"), - &next_handle, sizeof(int)); - } - objdb->object_find_destroy(find_handle); - - get_env_overrides(); - if (getenv("CMAN_NOCONFIG")) - ret = set_noccs_defaults(objdb); - else - ret = get_cman_globals(objdb); - - if (!ret) { - ret = get_nodename(objdb); - add_cman_overrides(objdb); - } - - - if (!ret) { - sprintf (error_reason, "%s", "Successfully parsed cman config\n"); - } - else { - if (error_reason[0] == '\0') - sprintf (error_reason, "%s", "Error parsing cman config\n"); - } - *error_string = error_reason; - - return ret; -} - -/* Write an error message down the CMAN startup pipe so - that cman_tool can display it */ -int write_cman_pipe(char *message) -{ - if (startup_pipe) - return write(startup_pipe, message, strlen(message)+1); - - return 0; -} diff --git a/cman/daemon/cman.h b/cman/daemon/cman.h deleted file mode 100644 index bba91aa..0000000 --- a/cman/daemon/cman.h +++ /dev/null @@ -1,15 +0,0 @@ -/* General cman bits */ -extern int write_cman_pipe(char *message); -extern void close_cman_pipe(void); - -/* How we announce ourself in syslog */ -#define CMAN_NAME "CMAN" - -/* Defaults for configuration variables */ -#define NOCCS_KEY_FILENAME "/etc/cluster/cman_authkey" -#define DEFAULT_PORT 5405 -#define DEFAULT_CLUSTER_NAME "RHCluster" -#define DEFAULT_MAX_QUEUED 128 -#define DEFAULT_QUORUMDEV_POLL 10000 -#define DEFAULT_SHUTDOWN_TIMEOUT 5000 -#define DEFAULT_CCSD_POLL 1000 diff --git a/cman/daemon/cmanconfig.c b/cman/daemon/cmanconfig.c deleted file mode 100644 index cf0cfd2..0000000 --- a/cman/daemon/cmanconfig.c +++ /dev/null @@ -1,297 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "list.h" -#include "cnxman-socket.h" -#include "cnxman-private.h" -#include "logging.h" -#include "commands.h" -#include "cman.h" -#define OBJDB_API struct corosync_api_v1 -#include "cmanconfig.h" -#include "nodelist.h" -#include "ais.h" - -LOGSYS_DECLARE_SUBSYS (CMAN_NAME, LOG_INFO); - -/* Local vars - things we get from ccs */ - int two_node; -static int nodeid; -static unsigned int cluster_id; -static char cluster_name[MAX_CLUSTER_NAME_LEN + 1]; -static unsigned int expected_votes; -static char *our_nodename; -static int our_votes; - -/* Get all the cluster node names from objdb and - * add them to our node list. - * Called when we start up and on "cman_tool version". - */ -int read_cman_nodes(struct corosync_api_v1 *corosync, unsigned int *config_version, int check_nodeids) -{ - int error; - unsigned int expected = 0; - unsigned int votes = 0; - int nodeid; - unsigned int object_handle; - unsigned int nodes_handle; - unsigned int find_handle; - char *nodename; - unsigned int cluster_parent_handle; - - corosync->object_find_create(OBJECT_PARENT_HANDLE, - "cluster", strlen("cluster"), &find_handle); - - corosync->object_find_next(find_handle, &cluster_parent_handle); - corosync->object_find_destroy(find_handle); - - /* New config version */ - objdb_get_int(corosync, cluster_parent_handle, "config_version", config_version,0); - - corosync->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle); - - if (corosync->object_find_next(find_handle, &object_handle) == 0) - { - /* This overrides any other expected votes calculation /except/ for - one specified on a join command-line */ - objdb_get_int(corosync, object_handle, "expected_votes", &expected, 0); - objdb_get_int(corosync, object_handle, "two_node", (unsigned int *)&two_node, 0); - objdb_get_int(corosync, object_handle, "cluster_id", &cluster_id, 0); - objdb_get_string(corosync, object_handle, "nodename", &our_nodename); - objdb_get_int(corosync, object_handle, "max_queued", &max_outstanding_messages, DEFAULT_MAX_QUEUED); - } - corosync->object_find_destroy(find_handle); - - clear_reread_flags(); - - /* Get the nodes list */ - nodes_handle = nodeslist_init(corosync, cluster_parent_handle, &find_handle); - do { - if (objdb_get_string(corosync, nodes_handle, "name", &nodename)) { - nodes_handle = nodeslist_next(corosync, find_handle); - continue; - } - - objdb_get_int(corosync, nodes_handle, "votes", (unsigned int *)&votes, 1); - objdb_get_int(corosync, nodes_handle, "nodeid", (unsigned int *)&nodeid, 0); - if (check_nodeids && nodeid == 0) { - char message[132]; - - snprintf(message, sizeof(message), - "No node ID for %s, run 'ccs_tool addnodeids' to fix", - nodename); - log_printf(LOG_ERR, "%s", message); - write_cman_pipe(message); - error = -EINVAL; - goto out_err; - } - - P_MEMB("Got node %s from ccs (id=%d, votes=%d)\n", nodename, nodeid, votes); - add_ccs_node(nodename, nodeid, votes, expected); - nodes_handle = nodeslist_next(corosync, find_handle); - } while (nodes_handle); - corosync->object_find_destroy(find_handle); - - if (expected) - override_expected(expected); - - remove_unread_nodes(); - error = 0; - -out_err: - return error; -} - -static int join(struct corosync_api_v1 *corosync) -{ - int error; - error = cman_set_nodename(our_nodename); - error = cman_set_nodeid(nodeid); - - /* - * Setup join information - */ - error = cman_join_cluster(corosync, cluster_name, cluster_id, - two_node, our_votes, expected_votes); - if (error == -EINVAL) { - write_cman_pipe("Cannot start, cluster name is too long or other CCS error"); - return error; - } - if (error) { - write_cman_pipe("Cannot start, ais may already be running"); - return error; - } - - return 0; -} - -static int get_cman_join_info(struct corosync_api_v1 *corosync) -{ - char *cname = NULL; - int error, vote_sum = 0, node_count = 0; - int votes=0; - unsigned int object_handle; - unsigned int node_object; - unsigned int nodes_handle; - unsigned int find_handle; - unsigned int cluster_parent_handle; - - corosync->object_find_create(OBJECT_PARENT_HANDLE, - "cluster", strlen("cluster"), &find_handle); - - corosync->object_find_next(find_handle, &cluster_parent_handle); - corosync->object_find_destroy(find_handle); - - /* Cluster name */ - if (objdb_get_string(corosync, cluster_parent_handle, "name", &cname)) { - log_printf(LOG_ERR, "cannot find cluster name in config file"); - write_cman_pipe("Can't find cluster name in CCS"); - error = -ENOENT; - goto out; - } - - strcpy(cluster_name, cname); - - expected_votes = 0; - if (getenv("CMAN_EXPECTEDVOTES")) { - expected_votes = atoi(getenv("CMAN_EXPECTEDVOTES")); - if (expected_votes < 1) { - log_printf(LOG_ERR, "CMAN_EXPECTEDVOTES environment variable is invalid, ignoring"); - expected_votes = 0; - } - else { - log_printf(LOG_INFO, "Using override expected votes %d\n", expected_votes); - } - } - - /* Sum node votes for expected. Even if we already know expected_votes, we need vote_sum - later */ - nodes_handle = nodeslist_init(corosync, cluster_parent_handle, &find_handle); - do { - int votes; - - node_count++; - - objdb_get_int(corosync, nodes_handle, "votes", (unsigned int *)&votes, 1); - if (votes < 0) { - log_printf(LOG_ERR, "negative votes not allowed"); - write_cman_pipe("Found negative votes for this node in CCS"); - error = -EINVAL; - goto out; - } - vote_sum += votes; - nodes_handle = nodeslist_next(corosync, find_handle); - } while (nodes_handle); - corosync->object_find_destroy(find_handle); - - if (expected_votes == 0) { - corosync->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle); - if (corosync->object_find_next(find_handle, &object_handle) == 0) - { - - /* optional expected_votes supercedes vote sum */ - objdb_get_int(corosync, object_handle, "expected_votes", (unsigned int *)&expected_votes, 0); - if (!expected_votes) - expected_votes = vote_sum; - } - corosync->object_find_destroy(find_handle); - } - - /* find our own number of votes */ - if (getenv("CMAN_VOTES")) { - votes = atoi(getenv("CMAN_VOTES")); - log_printf(LOG_INFO, "Using override votes %d\n", votes); - } - - node_object = nodelist_byname(corosync, cluster_parent_handle, our_nodename); - if (!node_object) { - log_printf(LOG_ERR, "unable to find votes for %s", our_nodename); - write_cman_pipe("Unable to find votes for node in CCS"); - return -E2BIG; - } - - if (!votes) { - unsigned int votestmp=-1; - objdb_get_int(corosync, node_object, "votes", &votestmp, 1); - if (votestmp < 0 || votestmp > 255) { - log_printf(LOG_ERR, "invalid votes value %d", votestmp); - write_cman_pipe("Found invalid votes for node in CCS"); - return -EINVAL; - } - votes = votestmp; - } - our_votes = votes; - - /* nodeid */ - if (getenv("CMAN_NODEID")) { - nodeid = atoi(getenv("CMAN_NODEID")); - log_printf(LOG_INFO, "Using override nodeid %d\n", nodeid); - } - - if (!nodeid) { - objdb_get_int(corosync, node_object, "nodeid", (unsigned int *)&nodeid, 0); - } - - if (!nodeid) { - log_printf(LOG_ERR, "No nodeid specified in cluster.conf"); - write_cman_pipe("CCS does not have a nodeid for this node, run 'ccs_tool addnodeids' to fix"); - return -EINVAL; - } - - /* two_node mode */ - if (two_node) { - if (node_count != 2 || vote_sum != 2) { - log_printf(LOG_ERR, "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); - write_cman_pipe("two_node set but there are more than 2 nodes"); - error = -EINVAL; - goto out; - } - - if (votes != 1) { - log_printf(LOG_ERR, "the two-node option requires exactly two " - "nodes with one vote each and expected " - "votes of 1 (votes=%d)", votes); - write_cman_pipe("two_node set but votes not set to 1"); - error = -EINVAL; - goto out; - } - } - - error = 0; - -out: - return error; -} - - - -/* Read the stuff we need to get started. - This does what 'cman_tool join' used to to */ -int read_cman_config(struct corosync_api_v1 *corosync, unsigned int *config_version) -{ - int error; - - read_cman_nodes(corosync, config_version, 1); - error = get_cman_join_info(corosync); - if (error) { - log_printf(LOG_ERR, "Error reading configuration, cannot start"); - return error; - } - - error = join(corosync); - - return error; -} diff --git a/cman/daemon/cmanconfig.h b/cman/daemon/cmanconfig.h deleted file mode 100644 index 2d66add..0000000 --- a/cman/daemon/cmanconfig.h +++ /dev/null @@ -1,3 +0,0 @@ -int read_cman_nodes(struct corosync_api_v1 *api, unsigned int *config_version, int check_nodeids); -int read_cman_config(struct corosync_api_v1 *api, unsigned int *config_version); - diff --git a/cman/daemon/cnxman-private.h b/cman/daemon/cnxman-private.h deleted file mode 100644 index 002480d..0000000 --- a/cman/daemon/cnxman-private.h +++ /dev/null @@ -1,183 +0,0 @@ -#ifndef __CNXMAN_PRIVATE_H -#define __CNXMAN_PRIVATE_H - -/* Protocol Version triplet */ -#define CNXMAN_MAJOR_VERSION 6 -#define CNXMAN_MINOR_VERSION 2 -#define CNXMAN_PATCH_VERSION 0 - -struct cman_timer -{ - struct list list; - struct timeval tv; - int active; - void (*callback)(void *arg); - void *arg; -}; - -/* A cluster internal protocol message - port number 0 */ -struct cl_protmsg { - unsigned char cmd; -}; - - -/* A Cluster PORT OPENED/CLOSED message */ -struct cl_portmsg { - unsigned char cmd; /* CLUSTER_CMD_PORTOPENED/CLOSED */ - unsigned char port; -}; - -/* 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; - - char name[MAX_BARRIER_NAME_LEN]; -}; - -struct cl_transmsg { - unsigned char cmd; - unsigned char first_trans; - uint16_t cluster_id; - int votes; - int expected_votes; - - 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 flags; - uint64_t fence_time; - uint64_t join_time; - char clustername[16]; - char fence_agent[]; -}; - -struct cl_killmsg { - unsigned char cmd; - unsigned char pad1; - uint16_t reason; - int nodeid; -}; - -struct cl_leavemsg { - unsigned char cmd; - unsigned char pad1; - uint16_t reason; -}; - - -/* Reconfigure a cluster parameter */ -struct cl_reconfig_msg { - unsigned char cmd; - unsigned char param; - unsigned short pad; - int nodeid; - unsigned int value; -}; - -struct cl_fencemsg { - unsigned char cmd; - unsigned char fenced; - uint16_t pad; - int nodeid; - uint64_t timesec; - char agent[0]; -}; - -typedef enum {CON_COMMS, CON_CLIENT_RENDEZVOUS, CON_ADMIN_RENDEZVOUS, - CON_CLIENT, CON_ADMIN} con_type_t; - -/* One of these for every connection we have open - and need to select() on */ -struct connection -{ - int fd; - con_type_t type; - uint32_t port; /* If bound client */ - enum {SHUTDOWN_REPLY_UNK=0, SHUTDOWN_REPLY_YES, SHUTDOWN_REPLY_NO} shutdown_reply; - uint32_t events; /* Registered for events */ - uint32_t confchg; /* Registered for confchg */ - struct list write_msgs; /* Queued messages to go to data clients */ - uint32_t num_write_msgs; /* Count of messages */ - struct connection *next; - struct list list; /* when on the client_list */ -}; - -/* Parameters for RECONFIG command */ -#define RECONFIG_PARAM_EXPECTED_VOTES 1 -#define RECONFIG_PARAM_NODE_VOTES 2 -#define RECONFIG_PARAM_CONFIG_VERSION 3 -#define RECONFIG_PARAM_CCS 4 - -/* NODE_FLAGS_BEENDOWN - This node has been down. - NODE_FLAGS_FENCED - This node has been fenced since it last went down. - NODE_FLAGS_FENCEDWHILEUP - This node was fenced manually (probably). - NODE_FLAGS_SEESDISALLOWED - Only set in a transition message - NODE_FLAGS_DIRTY - This node has internal state and must not join - a cluster that also has state. - NODE_FLAGS_REREAD - Set when the node is re-read from config, so - we can spot deleted nodes -*/ -#define NODE_FLAGS_BEENDOWN 1 -#define NODE_FLAGS_FENCED 2 -#define NODE_FLAGS_FENCEDWHILEUP 4 -#define NODE_FLAGS_SEESDISALLOWED 8 -#define NODE_FLAGS_DIRTY 16 -#define NODE_FLAGS_REREAD 32 - -/* There's one of these for each node in the cluster */ -struct cluster_node { - struct list list; - char *name; /* Node/host name of node */ - struct list addr_list; - int us; /* This node is us */ - unsigned int node_id; /* Unique node ID */ - int flags; - nodestate_t state; - struct timeval join_time; - - /* When & how this node was last fenced */ - uint64_t fence_time; /* A time_t */ - char *fence_agent; - - uint64_t cman_join_time; /* A time_t */ - - struct timeval last_hello; /* Only used for quorum devices */ - - unsigned int votes; - unsigned int expected_votes; - unsigned int leave_reason; - uint64_t incarnation; - - /* 32 bytes gives us enough for 256 bits (8 bit port number) */ -#define PORT_BITS_SIZE 32 - unsigned char port_bits[PORT_BITS_SIZE]; /* bitmap of ports open on this node */ -}; - -/* Cluster protocol commands sent to port 0 */ -#define CLUSTER_MSG_ACK 1 -#define CLUSTER_MSG_PORTOPENED 2 -#define CLUSTER_MSG_PORTCLOSED 3 -#define CLUSTER_MSG_BARRIER 4 -#define CLUSTER_MSG_TRANSITION 5 -#define CLUSTER_MSG_KILLNODE 6 -#define CLUSTER_MSG_LEAVE 7 -#define CLUSTER_MSG_RECONFIGURE 8 -#define CLUSTER_MSG_PORTENQ 9 -#define CLUSTER_MSG_PORTSTATUS 10 -#define CLUSTER_MSG_FENCESTATUS 11 - -/* Kill reasons */ -#define CLUSTER_KILL_REJECTED 1 -#define CLUSTER_KILL_CMANTOOL 2 -#define CLUSTER_KILL_REJOIN 3 - -#endif diff --git a/cman/daemon/cnxman-socket.h b/cman/daemon/cnxman-socket.h deleted file mode 100644 index 798fa02..0000000 --- a/cman/daemon/cnxman-socket.h +++ /dev/null @@ -1,275 +0,0 @@ -/* - * CMAN socket interface header - * Should only be used by libcman - if you want to call CMAN then use the library! - */ - -#ifndef __CNXMAN_SOCKET_H -#define __CNXMAN_SOCKET_H - -/* - * Commands on the socket. - * if the top bit is set then it is only allowed - * on the ADMIN socket. - */ -#define CMAN_CMD_NOTIFY 0x00000001 -#define CMAN_CMD_REMOVENOTIFY 0x00000002 -#define CMAN_CMD_SETEXPECTED_VOTES 0x80000004 -#define CMAN_CMD_ISQUORATE 0x00000005 -#define CMAN_CMD_ISLISTENING 0x00000006 -#define CMAN_CMD_GETALLMEMBERS 0x00000007 -#define CMAN_CMD_SET_VOTES 0x80000008 -#define CMAN_CMD_GET_VERSION 0x00000009 -#define CMAN_CMD_SET_VERSION 0x8000000a -#define CMAN_CMD_ISACTIVE 0x0000000b -#define CMAN_CMD_KILLNODE 0x8000000c -#define CMAN_CMD_GET_JOINCOUNT 0x0000000d -#define CMAN_CMD_GETNODECOUNT 0x0000000e -#define CMAN_CMD_GETNODE 0x00000090 -#define CMAN_CMD_GETCLUSTER 0x00000091 -#define CMAN_CMD_GETEXTRAINFO 0x00000092 -#define CMAN_CMD_BARRIER 0x000000a0 -#define CMAN_CMD_LEAVE_CLUSTER 0x800000b4 -#define CMAN_CMD_REG_QUORUMDEV 0x800000b5 -#define CMAN_CMD_UNREG_QUORUMDEV 0x800000b6 -#define CMAN_CMD_POLL_QUORUMDEV 0x800000b7 -#define CMAN_CMD_TRY_SHUTDOWN 0x800000bb -#define CMAN_CMD_SHUTDOWN_REPLY 0x000000bc -#define CMAN_CMD_UPDATE_FENCE_INFO 0x800000bd -#define CMAN_CMD_GET_FENCE_INFO 0x000000be -#define CMAN_CMD_GET_NODEADDRS 0x000000bf -#define CMAN_CMD_START_CONFCHG 0x000000c0 -#define CMAN_CMD_STOP_CONFCHG 0x000000c1 -#define CMAN_CMD_SET_DIRTY 0x800000c2 -#define CMAN_CMD_SET_DEBUGLOG 0x800000c3 -#define CMAN_CMD_DUMP_OBJDB 0x800000c4 - -#define CMAN_CMD_DATA 0x00000100 -#define CMAN_CMD_BIND 0x00000101 -#define CMAN_CMD_EVENT 0x00000102 -#define CMAN_CMD_CONFCHG 0x00000103 - -#define CMAN_CMDFLAG_PRIV 0x80000000 -#define CMAN_CMDFLAG_REPLY 0x40000000 -#define CMAN_CMDMASK_CMD 0x0000FFFF - - -/* 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_CLUSTER_NAME_LEN 16 -#define MAX_FENCE_AGENT_NAME_LEN 255 - -/* 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 */ - -/* Port numbers above this will be blocked when the cluster is inquorate or in - * transition */ -#define HIGH_PROTECTED_PORT 9 - -/* Nodeid passed to CMD_GETNODE to return the quorum device info */ -#define CLUSTER_GETNODE_QUORUMDEV -1 - -/* 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 */ - -/* CMAN_CMD_EVENT reason codes */ -#define EVENT_REASON_PORTCLOSED 0 -#define EVENT_REASON_STATECHANGE 1 -#define EVENT_REASON_PORTOPENED 2 -#define EVENT_REASON_TRY_SHUTDOWN 3 -#define EVENT_REASON_CONFIG_UPDATE 4 - -/* Shutdown flags */ -#define SHUTDOWN_ANYWAY 1 -#define SHUTDOWN_REMOVE 2 - -/* - * Sendmsg flags, these are above the normal sendmsg flags so they don't - * interfere - */ -#define MSG_TOTEM_AGREED 0x1000000 -#define MSG_TOTEM_SAFE 0x2000000 -#define MSG_BCASTSELF 0x4000000 - -typedef enum { NODESTATE_JOINING=1, NODESTATE_MEMBER, - NODESTATE_DEAD, NODESTATE_LEAVING, NODESTATE_AISONLY } nodestate_t; - -static const char CLIENT_SOCKNAME[]= "/var/run/cman_client"; -static const char ADMIN_SOCKNAME[]= "/var/run/cman_admin"; - -/* This struct should be in front of all messages - * passed down the client and admin sockets. - */ -#define CMAN_MAGIC 0x434d414e -#define CMAN_VERSION 0x10000003 -struct sock_header { - uint32_t magic; - uint32_t version; - uint32_t length; - uint32_t command; - uint32_t flags; -}; - -/* Data message header */ -struct sock_data_header { - struct sock_header header; - int nodeid; - uint32_t port; - /* Data follows */ -}; - -/* Reply message */ -struct sock_reply_header { - struct sock_header header; - int status; - /* Any returned information follows */ -}; - -/* Event message */ -struct sock_event_message { - struct sock_header header; - int reason; - int arg; -}; - -/* confchg message */ -struct sock_confchg_message { - struct sock_header header; - int member_entries; - int left_entries; - int joined_entries; - unsigned int entries[]; // In above order. -}; - -/* Flags */ -#define CMAN_EXTRA_FLAG_2NODE 1 -#define CMAN_EXTRA_FLAG_ERROR 2 -#define CMAN_EXTRA_FLAG_SHUTDOWN 4 -#define CMAN_EXTRA_FLAG_UNCOUNTED 8 -#define CMAN_EXTRA_FLAG_DIRTY 16 - -struct cl_extra_info { - int node_state; - uint32_t flags; - int node_votes; - int total_votes; - int expected_votes; - int quorum; - int members; - char ports[32]; - int num_addresses; /* Number of real addresses, so the array below has - *2 addresses in it */ - char addresses[1]; /* Array of num_addresses sockaddr_storage - 1st n are multicast addresses */ -}; - -/* This is the structure, per node, returned from the membership call */ -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]; - char addr[sizeof(struct sockaddr_storage)]; - unsigned int addrlen; - struct timeval jointime; - unsigned char votes; -}; - -/* Structure passed to CMAN_CMD_ISLISTENING */ -struct cl_listen_request { - unsigned char port; - int nodeid; -}; - -/* 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 command */ -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; - uint32_t generation; -}; - -struct cl_set_votes { - int nodeid; - int newvotes; -}; - -/* An array of these is returned */ -struct cl_node_addrs { - int addrlen; - struct sockaddr_storage addr; -}; - -struct cl_get_node_addrs { - int numaddrs; - struct cl_node_addrs addrs[]; -}; - -#define FENCE_FLAGS_FENCED 2 -struct cl_fence_info { - int nodeid; - int flags; - uint64_t fence_time; - char fence_agent[MAX_FENCE_AGENT_NAME_LEN]; -}; - -struct cl_qdev_info { - char name[MAX_CLUSTER_MEMBER_NAME_LEN]; - int state; - int votes; -}; - -/* Commands to the barrier cmd */ -#define BARRIER_CMD_REGISTER 1 -#define BARRIER_CMD_CHANGE 2 -#define BARRIER_CMD_DELETE 3 -#define BARRIER_CMD_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/daemon/commands.c b/cman/daemon/commands.c deleted file mode 100644 index a9570cf..0000000 --- a/cman/daemon/commands.c +++ /dev/null @@ -1,2217 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "list.h" -#include "cman.h" -#include "cnxman-socket.h" -#include "cnxman-private.h" -#include "daemon.h" -#include "barrier.h" -#include "logging.h" -#define OBJDB_API struct corosync_api_v1 -#include "cmanconfig.h" -#include "nodelist.h" -#include "commands.h" -#include "ais.h" - -#define max(a,b) (((a) > (b)) ? (a) : (b)) -LOGSYS_DECLARE_SUBSYS (CMAN_NAME, LOG_INFO); - -/* Reference counting for cluster applications */ -static int use_count; - -/* Array of "ports" allocated. This is just a list of pointers to the connection that - * has this port bound. Port 0 is reserved for protocol messages */ -static struct connection *port_array[256]; - -// Stuff that was more global -static LIST_INIT(cluster_members_list); - int cluster_members; - int we_are_a_cluster_member; - unsigned int config_version; -static struct cluster_node *us; -static int quorum; -extern int two_node; - unsigned int quorumdev_poll=DEFAULT_QUORUMDEV_POLL; - unsigned int shutdown_timeout=DEFAULT_SHUTDOWN_TIMEOUT; - unsigned int ccsd_poll_interval=DEFAULT_CCSD_POLL; -static int cluster_is_quorate; - char cluster_name[MAX_CLUSTER_NAME_LEN+1]; -static char nodename[MAX_CLUSTER_MEMBER_NAME_LEN+1]; -static int wanted_nodeid; -static struct cluster_node *quorum_device; -static uint16_t cluster_id; -static int ais_running; -static time_t join_time; -static corosync_timer_handle_t quorum_device_timer; -static struct corosync_api_v1 *corosync; - -/* If CCS gets out of sync, we poll it until it isn't */ -static corosync_timer_handle_t ccsd_timer; -static unsigned int wanted_config_version; -static int config_error; - -static corosync_timer_handle_t shutdown_timer; -static struct connection *shutdown_con; -static uint32_t shutdown_flags; -static int shutdown_yes; -static int shutdown_no; -static int shutdown_expected; - -static struct cluster_node *find_node_by_nodeid(int nodeid); -static struct cluster_node *find_node_by_name(char *name); -static int get_node_count(void); -static int get_highest_nodeid(void); -static int send_port_open_msg(unsigned char port); -static int send_port_enquire(int nodeid); -static void process_internal_message(char *data, int nodeid, int byteswap); -static void recalculate_quorum(int allow_decrease, int by_current_nodes); -static void send_kill(int nodeid, uint16_t reason); -static char *killmsg_reason(int reason); -static void ccsd_timer_fn(void *arg); - - -static void set_port_bit(struct cluster_node *node, uint8_t port) -{ - int byte; - int bit; - - byte = port/8; - bit = port%8; - - node->port_bits[byte] |= 1<port_bits[byte] &= ~(1<port_bits[byte] & (1<state == NODESTATE_AISONLY) - return 1; - } - - return 0; -} - -/* Make a totem_ip_address into a usable sockaddr_storage */ -static int totemip_to_sockaddr(struct totem_ip_address *ip_addr, - uint16_t port, struct sockaddr_storage *saddr, int *addrlen) -{ - int ret = -1; - - if (ip_addr->family == AF_INET) { - struct sockaddr_in *sin = (struct sockaddr_in *)saddr; - - memset(sin, 0, sizeof(struct sockaddr_in)); - sin->sin_family = ip_addr->family; - sin->sin_port = port; - memcpy(&sin->sin_addr, ip_addr->addr, sizeof(struct in_addr)); - *addrlen = sizeof(struct sockaddr_in); - ret = 0; - } - - if (ip_addr->family == AF_INET6) { - struct sockaddr_in6 *sin = (struct sockaddr_in6 *)saddr; - - memset(sin, 0, sizeof(struct sockaddr_in6)); - sin->sin6_family = ip_addr->family; - sin->sin6_port = port; - sin->sin6_scope_id = 2; - memcpy(&sin->sin6_addr, ip_addr->addr, sizeof(struct in6_addr)); - - *addrlen = sizeof(struct sockaddr_in6); - ret = 0; - } - - return ret; -} - -/* If "cluster_is_quorate" is 0 then all activity apart from protected ports is - * blocked. */ -static void set_quorate(int total_votes) -{ - int quorate; - - if (quorum > total_votes || config_error) { - quorate = 0; - } - else { - quorate = 1; - } - - if (cluster_is_quorate && !quorate) - log_printf(LOG_INFO, "quorum lost, blocking activity\n"); - if (!cluster_is_quorate && quorate) - log_printf(LOG_INFO, "quorum regained, resuming activity\n"); - - /* If we are newly quorate, then kill any AISONLY nodes */ - if (!cluster_is_quorate && quorate) { - struct cluster_node *node = NULL; - struct list *tmp; - - list_iterate(tmp, &cluster_members_list) { - node = list_item(tmp, struct cluster_node); - if (node->state == NODESTATE_AISONLY) - send_kill(node->node_id, CLUSTER_KILL_REJOIN); - } - } - - cluster_is_quorate = quorate; - -} - -static void node_add_ordered(struct cluster_node *newnode) -{ - struct cluster_node *node = NULL; - struct list *tmp; - struct list *newlist = &newnode->list; - - list_iterate(tmp, &cluster_members_list) { - node = list_item(tmp, struct cluster_node); - - if (newnode->node_id < node->node_id) - break; - } - - if (!node) - list_add(&cluster_members_list, &newnode->list); - else { - newlist->p = tmp->p; - newlist->n = tmp; - tmp->p->n = newlist; - tmp->p = newlist; - } -} - -static struct cluster_node *add_new_node(char *name, int nodeid, int votes, int expected_votes, - nodestate_t state) -{ - struct cluster_node *newnode = NULL; - int newalloc = 0; - - if (nodeid) - newnode = find_node_by_nodeid(nodeid); - - if (!newnode) { - newnode = malloc(sizeof(struct cluster_node)); - if (!newnode) { - log_printf(LOG_ERR, "Unable to allocate memory for node %s\n", name); - return NULL; - } - memset(newnode, 0, sizeof(struct cluster_node)); - newalloc = 1; - newnode->state = state; - if (state == NODESTATE_MEMBER) - newnode->incarnation = incarnation; - } - if (!newnode->name) { - newnode->name = malloc(strlen(name)+1); - if (!newnode->name) { - if (newalloc) - free(newnode); - return NULL; - } - strcpy(newnode->name, name); - } - - if (!newnode->node_id) /* Don't clobber existing nodeid */ - newnode->node_id = nodeid; - if (votes >= 0) - newnode->votes = votes; - if (expected_votes) - newnode->expected_votes = expected_votes; - - /* If this node has a name passed in then use that rather than a previous generated one */ - if (name && newnode->name && strcmp(name, newnode->name)) { - char *newname; - - newname = strdup(name); - if (newname) { - P_MEMB("replacing old node name %s with %s\n", newnode->name, name); - free(newnode->name); - newnode->name = newname; - } - } - - if (newalloc) - node_add_ordered(newnode); - - newnode->flags |= NODE_FLAGS_REREAD; - - P_MEMB("add_new_node: %s, (id=%d, votes=%d) newalloc=%d\n", - name, nodeid, votes, newalloc); - - return newnode; -} - -static void send_reconfigure(int nodeid, int param, int value) -{ - struct cl_reconfig_msg msg; - - msg.cmd = CLUSTER_MSG_RECONFIGURE; - msg.param = param; - msg.nodeid = nodeid; - msg.value = value; - - comms_send_message((char *)&msg, sizeof(msg), - 0,0, - 0, /* multicast */ - 0); /* flags */ -} - -static int calculate_quorum(int allow_decrease, int max_expected, unsigned int *ret_total_votes) -{ - struct list *nodelist; - struct cluster_node *node; - unsigned int total_votes = 0; - unsigned int highest_expected = 0; - unsigned int newquorum, q1, q2; - unsigned int total_nodes = 0; - - list_iterate(nodelist, &cluster_members_list) { - node = list_item(nodelist, struct cluster_node); - - if (node->state == NODESTATE_MEMBER) { - if (max_expected) - node->expected_votes = max_expected; - else - highest_expected = max(highest_expected, node->expected_votes); - total_votes += node->votes; - total_nodes++; - } - } - 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.) - * Also: if there are more than two nodes, force us inquorate to avoid - * any damage or confusion. - */ - if (two_node && total_nodes <= 2) - newquorum = 1; - - if (ret_total_votes) - *ret_total_votes = total_votes; - return newquorum; -} - -/* Recalculate cluster quorum, set quorate and notify changes */ -static void recalculate_quorum(int allow_decrease, int by_current_nodes) -{ - unsigned int total_votes; - - quorum = calculate_quorum(allow_decrease, by_current_nodes?cluster_members:0, &total_votes); - set_quorate(total_votes); - notify_listeners(NULL, EVENT_REASON_STATECHANGE, cluster_is_quorate); -} - -/* Copy internal node format to userland format */ -static void copy_to_usernode(struct cluster_node *node, - struct cl_cluster_node *unode) -{ - struct sockaddr_storage ss; - int addrlen=0; - unsigned int numaddrs=1; - char **status; - struct totem_ip_address node_ifs[INTERFACE_MAX]; - /* totempg_ifaces_get always copies INTERFACE_MAX addresses */ - - strcpy(unode->name, node->name); - unode->jointime = node->join_time; - 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; - - /* Just send the first address. If the user wants the full set they - must ask for them */ - corosync->totem_ifaces_get(node->node_id, node_ifs, &status, &numaddrs); - - totemip_to_sockaddr(&node_ifs[0], 0, &ss, &addrlen); - memcpy(unode->addr, &ss, addrlen); - unode->addrlen = addrlen; -} - - -int cman_set_nodename(char *name) -{ - if (ais_running) - return -EALREADY; - - strncpy(nodename, name, MAX_CLUSTER_MEMBER_NAME_LEN); - return 0; -} - -int cman_set_nodeid(int nodeid) -{ - if (ais_running) - return -EALREADY; - - wanted_nodeid = nodeid; - return 0; -} - -int cman_join_cluster(struct corosync_api_v1 *api, - char *name, unsigned short cl_id, - int two_node_flag, int votes, int expected_votes) -{ - if (ais_running) - return -EALREADY; - - if (strlen(name) > MAX_CLUSTER_NAME_LEN) - return -EINVAL; - - cluster_id = cl_id; - strncpy(cluster_name, name, MAX_CLUSTER_NAME_LEN); - two_node = two_node_flag; - corosync = api; - - quit_threads = 0; - ais_running = 1; - - /* Make sure we have a node name */ - if (nodename[0] == '\0') { - struct utsname un; - uname(&un); - strcpy(nodename, un.nodename); - } - - time(&join_time); - us = add_new_node(nodename, wanted_nodeid, votes, expected_votes, - NODESTATE_DEAD); - set_port_bit(us, 0); - us->us = 1; - - return 0; -} - -/* command processing functions */ - -static int do_cmd_set_version(char *cmdbuf, int *retlen) -{ - struct cl_version *version = (struct cl_version *)cmdbuf; - - if (!we_are_a_cluster_member) - return -ENOENT; - - 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; - - /* We will re-read CCS when we get our own message back */ - send_reconfigure(us->node_id, RECONFIG_PARAM_CONFIG_VERSION, version->config); - return 0; -} - -static int do_cmd_get_extrainfo(char *cmdbuf, char **retbuf, int retsize, int *retlen, int offset) -{ - char *outbuf = *retbuf + offset; - struct cl_extra_info *einfo = (struct cl_extra_info *)outbuf; - struct totem_ip_address node_ifs[MAX_INTERFACES]; - int total_votes = 0; - int max_expected = 0; - int addrlen; - int uncounted = 0; - unsigned int num_interfaces; - unsigned int totem_object_handle; - unsigned int object_handle; - unsigned int totem_find_handle; - unsigned int iface_find_handle; - char **status; - struct cluster_node *node; - struct sockaddr_storage *ss; - char *ptr; - int i; - - if (!we_are_a_cluster_member) - return -ENOENT; - - corosync->totem_ifaces_get(us->node_id, node_ifs, &status, &num_interfaces); - - list_iterate_items(node, &cluster_members_list) { - if (node->state == NODESTATE_MEMBER) { - total_votes += node->votes; - max_expected = max(max_expected, node->expected_votes); - } - if (node->state == NODESTATE_AISONLY) - uncounted = 1; - } - if (quorum_device && quorum_device->state == NODESTATE_MEMBER) - total_votes += quorum_device->votes; - - /* Enough room for addresses ? */ - if (retsize < (sizeof(struct cl_extra_info) + - sizeof(struct sockaddr_storage) * (MAX_INTERFACES*2))) { - - *retbuf = malloc(sizeof(struct cl_extra_info) + sizeof(struct sockaddr_storage) * (MAX_INTERFACES*2)); - outbuf = *retbuf + offset; - einfo = (struct cl_extra_info *)outbuf; - - P_MEMB("get_extrainfo: allocated new buffer\n"); - } - - einfo->node_state = us->state; - einfo->node_votes = us->votes; - einfo->total_votes = total_votes; - einfo->expected_votes = max_expected; - einfo->quorum = quorum; - einfo->members = cluster_members; - einfo->num_addresses = num_interfaces; - memcpy(einfo->ports, us->port_bits, 32); - einfo->flags = 0; - if (two_node) - einfo->flags |= CMAN_EXTRA_FLAG_2NODE; - if (config_error) - einfo->flags |= CMAN_EXTRA_FLAG_ERROR; - if (shutdown_con) - einfo->flags |= CMAN_EXTRA_FLAG_SHUTDOWN; - if (uncounted) - einfo->flags |= CMAN_EXTRA_FLAG_UNCOUNTED; - if (us->flags & NODE_FLAGS_DIRTY) - einfo->flags |= CMAN_EXTRA_FLAG_DIRTY; - - ptr = einfo->addresses; - - corosync->object_find_create(OBJECT_PARENT_HANDLE, "totem", strlen("totem"), &totem_find_handle); - if (corosync->object_find_next(totem_find_handle, &totem_object_handle) == 0) { - - corosync->object_find_destroy(totem_find_handle); - - corosync->object_find_create(totem_object_handle, "interface", strlen("interface"), &iface_find_handle); - while (corosync->object_find_next(iface_find_handle, &object_handle) == 0) { - - char *mcast; - struct sockaddr_in *saddr4; - struct sockaddr_in6 *saddr6; - - objdb_get_string(corosync, object_handle, "mcastaddr", &mcast); - memset(ptr, 0, sizeof(struct sockaddr_storage)); - - saddr4 = (struct sockaddr_in *)ptr; - saddr6 = (struct sockaddr_in6 *)ptr; - if ( inet_pton(AF_INET, mcast, &saddr4->sin_addr) >0) { - saddr4->sin_family = AF_INET; - } - else { - if (inet_pton(AF_INET6, mcast, &saddr6->sin6_addr) > 0) - saddr4->sin_family = AF_INET6; - } - ptr += sizeof(struct sockaddr_storage); - } - } - corosync->object_find_destroy(iface_find_handle); - - for (i=0; inumber = cluster_id; - info->generation = incarnation; - memcpy(&info->name, cluster_name, strlen(cluster_name)+1); - *retlen = sizeof(struct cl_cluster_info); - - return 0; -} - -static int do_cmd_get_node(char *cmdbuf, char *retbuf, int *retlen) -{ - struct cluster_node *node; - struct cl_cluster_node *u_node = (struct cl_cluster_node *)cmdbuf; - struct cl_cluster_node *r_node = (struct cl_cluster_node *)retbuf; - - if (!we_are_a_cluster_member) - return -ENOENT; - - if (u_node->node_id == CLUSTER_GETNODE_QUORUMDEV) { - if (quorum_device) - node = quorum_device; - else - return -ENOENT; - } - else { - if (!u_node->name[0]) { - if (u_node->node_id == 0) - u_node->node_id = us->node_id; - node = find_node_by_nodeid(u_node->node_id); - } - else - node = find_node_by_name(u_node->name); - - if (!node) { - P_MEMB("cmd_get_node failed: id=%d, name='%s'\n", u_node->node_id, u_node->name); - return -ENOENT; - } - } - - copy_to_usernode(node, r_node); - *retlen = sizeof(struct cl_cluster_node); - - return 0; -} - -static int do_cmd_set_expected(char *cmdbuf, int *retlen) -{ - unsigned int total_votes; - unsigned int newquorum; - unsigned int newexp; - struct cluster_node *node = NULL; - struct list *tmp; - - if (!we_are_a_cluster_member) - return -ENOENT; - - /* If there are any AISONLY nodes then we can't allow - the user to set expected votes as it may destroy data */ - list_iterate(tmp, &cluster_members_list) { - node = list_item(tmp, struct cluster_node); - if (node->state == NODESTATE_AISONLY) { - log_printf(LOG_NOTICE, "Attempt to set expected votes when cluster has AISONLY nodes in it."); - return -EINVAL; - } - } - - memcpy(&newexp, cmdbuf, sizeof(int)); - newquorum = calculate_quorum(1, newexp, &total_votes); - - if (newquorum < total_votes / 2 - || newquorum > total_votes) { - return -EINVAL; - } - - override_expected(newexp); - send_reconfigure(us->node_id, RECONFIG_PARAM_EXPECTED_VOTES, newexp); - - /* We will recalculate quorum when we get our own message back */ - return 0; -} - -static void send_kill(int nodeid, uint16_t reason) -{ - struct cl_killmsg msg; - - P_MEMB("Sending KILL to node %d\n", nodeid); - - msg.cmd = CLUSTER_MSG_KILLNODE; - msg.reason = reason; - msg.nodeid = nodeid; - - comms_send_message((char *)&msg, sizeof(msg), - 0,0, - nodeid, - 0); /* flags */ -} - -static void send_leave(uint16_t reason) -{ - struct cl_leavemsg msg; - - P_MEMB("Sending LEAVE, reason %d\n", reason); - - msg.cmd = CLUSTER_MSG_LEAVE; - msg.reason = reason; - - comms_send_message((char *)&msg, sizeof(msg), - 0,0, - 0, /* multicast */ - 0); /* flags */ -} - -static int do_cmd_kill_node(char *cmdbuf, int *retlen) -{ - struct cluster_node *node; - int nodeid; - - if (!we_are_a_cluster_member) - return -ENOENT; - - memcpy(&nodeid, cmdbuf, sizeof(int)); - - if ((node = find_node_by_nodeid(nodeid)) == NULL) - return -EINVAL; - - if (node->state != NODESTATE_MEMBER && node->state != NODESTATE_AISONLY) - return -EINVAL; - - node->leave_reason = CLUSTER_LEAVEFLAG_KILLED; - node->state = NODESTATE_LEAVING; - - /* Send a KILL message */ - send_kill(nodeid, CLUSTER_KILL_CMANTOOL); - - return 0; -} - - -static int do_cmd_islistening(struct connection *con, char *cmdbuf, int *retlen) -{ - struct cl_listen_request rq; - struct cluster_node *rem_node; - int nodeid; - - if (!we_are_a_cluster_member) - return -ENOENT; - - memcpy(&rq, cmdbuf, sizeof(rq)); - - 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; - - - /* If we don't know the node's port status then ask it. - This should only need to be done when we are the new node in - a cluster that has been running for a while - */ - if (!get_port_bit(rem_node, 0)) { - P_MEMB("islistening, no data for node %d, sending PORTENQ\n", nodeid); - send_port_enquire(rem_node->node_id); - - /* Admit our ignorance */ - return -EBUSY; - } - else { - P_MEMB("islistening, for node %d, low bytes are %x %x\n", nodeid, rem_node->port_bits[0], rem_node->port_bits[1]); - return get_port_bit(rem_node, rq.port); - } -} - - -static int do_cmd_set_votes(char *cmdbuf, int *retlen) -{ - unsigned int total_votes; - unsigned int newquorum; - int saved_votes; - struct cl_set_votes arg; - struct cluster_node *node; - - if (!we_are_a_cluster_member) - return -ENOTCONN; - - memcpy(&arg, cmdbuf, sizeof(arg)); - - if (!arg.nodeid) - arg.nodeid = us->node_id; - - P_MEMB("Setting votes for node %d to %d\n", arg.nodeid, arg.newvotes); - - node = find_node_by_nodeid(arg.nodeid); - if (!node) - return -ENOENT; - - /* Check votes is valid */ - saved_votes = node->votes; - node->votes = arg.newvotes; - - newquorum = calculate_quorum(1, 0, &total_votes); - - if (newquorum < total_votes / 2 || newquorum > total_votes) { - node->votes = saved_votes; - return -EINVAL; - } - - recalculate_quorum(1, 0); - - send_reconfigure(arg.nodeid, RECONFIG_PARAM_NODE_VOTES, arg.newvotes); - - return 0; -} - -static int do_cmd_bind(struct connection *con, char *cmdbuf) -{ - unsigned int port; - int ret = -EADDRINUSE; - - memcpy(&port, cmdbuf, sizeof(int)); - - P_MEMB("requested bind to port %d, (us=%p)\n", port, con); - - if (port == 0 || port > 255) - return -EINVAL; - - if (port_array[port]) - goto out; - - ret = 0; - port_array[port] = con; - con->port = port; - - set_port_bit(us, con->port); - send_port_open_msg(con->port); - - out: - return ret; -} - -static int do_cmd_leave_cluster(char *cmdbuf, int *retlen) -{ - int leave_flags; - - if (!ais_running) - return -ENOTCONN; - - memcpy(&leave_flags, cmdbuf, sizeof(int)); - - /* Ignore the use count if FORCE is set */ - if (!(leave_flags & CLUSTER_LEAVEFLAG_FORCE)) { - if (use_count) - return -ENOTCONN; - } - - us->leave_reason = leave_flags; - quit_threads = 1; - - /* No messaging available yet, just die */ - if (!we_are_a_cluster_member) - exit(0); - - send_leave(leave_flags); - use_count = 0; - - /* When we get our leave message back, then quit */ - return 0; -} - -static void check_shutdown_status() -{ - int reply; - int leaveflags = CLUSTER_LEAVEFLAG_DOWN; - - /* All replies safely gathered in ? */ - if (shutdown_yes + shutdown_no >= shutdown_expected) { - - corosync->timer_delete(shutdown_timer); - - if (shutdown_yes >= shutdown_expected || - shutdown_flags & SHUTDOWN_ANYWAY) { - quit_threads = 1; - if (shutdown_flags & SHUTDOWN_REMOVE) - leaveflags |= CLUSTER_LEAVEFLAG_REMOVED; - send_leave(leaveflags); - reply = 0; - } - else { - reply = -EBUSY; - - /* Tell originator that shutdown was cancelled */ - send_status_return(shutdown_con, CMAN_CMD_TRY_SHUTDOWN, reply); - shutdown_con = NULL; - } - - P_MEMB("shutdown decision is: %d (yes=%d, no=%d) flags=%x\n", reply, shutdown_yes, shutdown_no, shutdown_flags); - } -} - -/* Not all nodes responded to the shutdown */ -static void shutdown_timer_fn(void *arg) -{ - P_MEMB("Shutdown timer fired. flags = %x\n", shutdown_flags); - - /* Mark undecideds as "NO" */ - shutdown_no = shutdown_expected; - check_shutdown_status(); -} - -/* A service's response to a TRY_SHUTDOWN event. This NEVER returns a response */ -static int do_cmd_shutdown_reply(struct connection *con, char *cmdbuf) -{ - int response = *(int *)cmdbuf; - - /* Not shutting down, but don't respond. */ - if (!shutdown_con) - return -EWOULDBLOCK; - - P_MEMB("Shutdown reply is %d\n", response); - - /* We only need to keep a track of a client's response in - case it pulls the connection before the shutdown process - has completed */ - if (response) { - shutdown_yes++; - con->shutdown_reply = SHUTDOWN_REPLY_YES; - } - else { - shutdown_no++; - con->shutdown_reply = SHUTDOWN_REPLY_NO; - } - check_shutdown_status(); - - /* No response needed to this message */ - return -EWOULDBLOCK; -} - -/* User requested shutdown. We poll all listening clients and see if they are - willing to shutdown */ -static int do_cmd_try_shutdown(struct connection *con, char *cmdbuf) -{ - int flags = *(int *)cmdbuf; - - /* Are we already in shutdown ? */ - if (shutdown_con) - return -EALREADY; - - shutdown_con = con; - shutdown_flags = flags; - shutdown_yes = 0; - shutdown_no = 0; - shutdown_expected = num_listeners(); - - /* If no-one is listening for events then we can just go down now */ - if (shutdown_expected == 0) { - send_leave(CLUSTER_LEAVEFLAG_DOWN); - return 0; - } - else { - - /* Start the timer. If we don't get a full set of replies before this goes - off we'll cancel the shutdown */ - corosync->timer_add_duration((unsigned long long)shutdown_timeout*1000000, NULL, - shutdown_timer_fn, &shutdown_timer); - - notify_listeners(NULL, EVENT_REASON_TRY_SHUTDOWN, flags); - - return -EWOULDBLOCK; - } -} - -static int do_cmd_register_quorum_device(char *cmdbuf, int *retlen) -{ - int votes; - char *name = cmdbuf+sizeof(int); - - if (!ais_running) - return -ENOTCONN; - - if (!we_are_a_cluster_member) - return -ENOENT; - - if (quorum_device) - return -EBUSY; - - if (strlen(name) > MAX_CLUSTER_MEMBER_NAME_LEN) - return -EINVAL; - - if (find_node_by_name(name)) - return -EALREADY; - - memcpy(&votes, cmdbuf, sizeof(int)); - - quorum_device = malloc(sizeof(struct cluster_node)); - if (!quorum_device) - return -ENOMEM; - memset(quorum_device, 0, sizeof(struct cluster_node)); - - quorum_device->name = malloc(strlen(name) + 1); - if (!quorum_device->name) { - free(quorum_device); - quorum_device = NULL; - return -ENOMEM; - } - - strcpy(quorum_device->name, name); - quorum_device->votes = votes; - quorum_device->state = NODESTATE_DEAD; - gettimeofday(&quorum_device->join_time, NULL); - - /* Keep this list valid so it doesn't confuse other code */ - list_init(&quorum_device->addr_list); - - log_printf(LOG_INFO, "quorum device registered\n"); - return 0; -} - -static int do_cmd_unregister_quorum_device(char *cmdbuf, int *retlen) -{ - if (!quorum_device) - return -EINVAL; - - if (quorum_device->state == NODESTATE_MEMBER) - return -EBUSY; - - free(quorum_device->name); - free(quorum_device); - - quorum_device = NULL; - - log_printf(LOG_INFO, "quorum device unregistered\n"); - return 0; -} - -static int reread_config(int new_version) -{ - int read_err; - char *reload_err = NULL; - - wanted_config_version = new_version; - - /* Tell objdb to reload */ - read_err = corosync->object_reload_config(1, &reload_err); - - /* Now get our bits */ - if (!read_err) - read_err = read_cman_nodes(corosync, &config_version, 0); - - if (read_err) { - config_error = 1; - log_printf(LOG_ERR, "Can't get updated config version %d: %s. Activity suspended on this node\n", - wanted_config_version, reload_err?reload_err:"version mismatch on this node"); - } - - /* Still too old?? */ - if (config_version < wanted_config_version) { - log_printf(LOG_ERR, "Can't get updated config version %d, config file is version %d.\n", - wanted_config_version, config_version); - } - - /* Keep looking */ - if (read_err || config_version < wanted_config_version) { - corosync->timer_add_duration((unsigned long long)ccsd_poll_interval*1000000, NULL, - ccsd_timer_fn, &ccsd_timer); - } - - return read_err; -} - -static void ccsd_timer_fn(void *arg) -{ - log_printf(LOG_DEBUG, "Polling configuration for updated information\n"); - if (!reread_config(wanted_config_version) && config_version >= wanted_config_version) { - log_printf(LOG_ERR, "Now got config information version %d, continuing\n", config_version); - config_error = 0; - recalculate_quorum(0, 0); - notify_listeners(NULL, EVENT_REASON_CONFIG_UPDATE, config_version); - } -} - - -static void quorum_device_timer_fn(void *arg) -{ - struct timeval now; - if (!quorum_device || quorum_device->state == NODESTATE_DEAD) - return; - - P_MEMB("quorum_device_timer_fn\n"); - gettimeofday(&now, NULL); - if (quorum_device->last_hello.tv_sec + quorumdev_poll/1000 < now.tv_sec) { - quorum_device->state = NODESTATE_DEAD; - log_printf(LOG_INFO, "lost contact with quorum device\n"); - recalculate_quorum(0, 0); - } - else { - corosync->timer_add_duration((unsigned long long)quorumdev_poll*1000000, quorum_device, - quorum_device_timer_fn, &quorum_device_timer); - } -} - -static int do_cmd_poll_quorum_device(char *cmdbuf, int *retlen) -{ - int yesno; - - if (!quorum_device) - return -EINVAL; - - memcpy(&yesno, cmdbuf, sizeof(int)); - - if (yesno) { - gettimeofday(&quorum_device->last_hello, NULL); - if (quorum_device->state == NODESTATE_DEAD) { - quorum_device->state = NODESTATE_MEMBER; - recalculate_quorum(0, 0); - - corosync->timer_add_duration((unsigned long long)quorumdev_poll*1000000, quorum_device, - quorum_device_timer_fn, &quorum_device_timer); - } - } - else { - if (quorum_device->state == NODESTATE_MEMBER) { - quorum_device->state = NODESTATE_DEAD; - recalculate_quorum(0, 0); - corosync->timer_delete(quorum_device_timer); - } - } - - return 0; -} - -/* fence_tool tells us it has fenced a node */ -static int do_cmd_update_fence_info(char *cmdbuf) -{ - struct cl_fence_info *f = (struct cl_fence_info *)cmdbuf; - struct cluster_node *node; - char msg[sizeof(struct cl_fencemsg)+strlen(f->fence_agent)+1]; - struct cl_fencemsg *fence_msg = (struct cl_fencemsg *)msg; - - node = find_node_by_nodeid(f->nodeid); - if (!node) - return -EINVAL; - - if (strlen(f->fence_agent) >= MAX_FENCE_AGENT_NAME_LEN) - return -EINVAL; - - node->flags |= NODE_FLAGS_FENCED; - if (node->state == NODESTATE_MEMBER) - node->flags |= NODE_FLAGS_FENCEDWHILEUP; - - /* Tell the rest of the cluster (and us!) */ - fence_msg->cmd = CLUSTER_MSG_FENCESTATUS; - fence_msg->nodeid = f->nodeid; - fence_msg->timesec = f->fence_time; - fence_msg->fenced = 1; - strcpy(fence_msg->agent, f->fence_agent); - comms_send_message(msg, sizeof(msg), 0,0, 0, 0); - - P_MEMB("node %d fenced by %s\n", f->nodeid, f->fence_agent); - return 0; -} - -static int do_cmd_get_fence_info(char *cmdbuf, char **retbuf, int retsize, int *retlen, int offset) -{ - int nodeid; - char *outbuf = *retbuf + offset; - struct cl_fence_info *f = (struct cl_fence_info *)outbuf; - struct cluster_node *node; - - if (retsize < sizeof(struct cl_fence_info)) - return -EINVAL; - memcpy(&nodeid, cmdbuf, sizeof(nodeid)); - - node = find_node_by_nodeid(nodeid); - if (!node) - return -EINVAL; - - f->nodeid = nodeid; - f->fence_time = node->fence_time; - f->flags = node->flags&NODE_FLAGS_FENCED; - - if (node->fence_agent) - strcpy(f->fence_agent, node->fence_agent); - else - f->fence_agent[0] = '\0'; - *retlen = sizeof(struct cl_fence_info); - return 0; -} - -static int do_cmd_get_node_addrs(char *cmdbuf, char **retbuf, int retsize, int *retlen, int offset) -{ - int nodeid; - int i; - char *outbuf = *retbuf + offset; - struct cl_get_node_addrs *addrs = (struct cl_get_node_addrs *)outbuf; - struct totem_ip_address node_ifs[INTERFACE_MAX]; /* totempg_ifaces_get always copies INTERFACE_MAX addresses */ - struct cluster_node *node; - char **status; - - if (retsize < sizeof(struct cl_node_addrs)) - return -EINVAL; - memcpy(&nodeid, cmdbuf, sizeof(nodeid)); - - node = find_node_by_nodeid(nodeid); - if (!node) - return -EINVAL; - - memset(outbuf, 0, retsize - offset); - - /* AIS doesn't know about nodes that are not members */ - if (node->state != NODESTATE_MEMBER) - return 0; - - if (corosync->totem_ifaces_get(nodeid, node_ifs, &status, (unsigned int *)&addrs->numaddrs)) - return -errno; - - for (i=0; inumaddrs; i++) { - totemip_to_sockaddr(&node_ifs[i], 0, - &addrs->addrs[i].addr, - &addrs->addrs[i].addrlen); - } - *retlen = sizeof(struct cl_get_node_addrs) + - addrs->numaddrs * sizeof(struct cl_node_addrs); - - return 0; -} - -int process_command(struct connection *con, int cmd, char *cmdbuf, - char **retbuf, int *retlen, int retsize, int offset) -{ - int err = -EINVAL; - struct cl_version cnxman_version; - char *outbuf = *retbuf; - int value; -#ifdef DEBUG - FILE *dumpfile; -#endif - - P_MEMB("command to process is %x\n", cmd); - - switch (cmd) { - - case CMAN_CMD_NOTIFY: - con->events = 1; - err = 0; - /* If a shutdown is in progress, ask the newcomer what it thinks... */ - if (shutdown_con) { - notify_listeners(con, EVENT_REASON_TRY_SHUTDOWN, shutdown_flags); - shutdown_expected++; - } - break; - - case CMAN_CMD_REMOVENOTIFY: - con->events = 0; - err = 0; - break; - - case CMAN_CMD_SET_DIRTY: - us->flags |= NODE_FLAGS_DIRTY; - err = 0; - break; - - case CMAN_CMD_SET_DEBUGLOG: - memcpy(&value, cmdbuf, sizeof(int)); - set_debuglog(value); - err = 0; - break; -#ifdef DEBUG - case CMAN_CMD_DUMP_OBJDB: - dumpfile = fopen(cmdbuf, "w+"); - if (dumpfile) { - corosync->object_dump(OBJECT_PARENT_HANDLE, dumpfile); - fclose(dumpfile); - err = 0; - } - else { - err = -errno; - } - break; -#endif - case CMAN_CMD_START_CONFCHG: - con->confchg = 1; - err = 0; - break; - - case CMAN_CMD_STOP_CONFCHG: - con->confchg = 0; - err = 0; - break; - - /* Return the cnxman version number */ - case CMAN_CMD_GET_VERSION: - 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; - memcpy(outbuf+offset, &cnxman_version, sizeof(struct cl_version)); - *retlen = sizeof(struct cl_version); - break; - - /* Set the cnxman config version number */ - case CMAN_CMD_SET_VERSION: - err = do_cmd_set_version(cmdbuf, retlen); - break; - - /* Bind to a "port" */ - case CMAN_CMD_BIND: - err = do_cmd_bind(con, cmdbuf); - break; - - /* Return the full membership list including dead nodes */ - case CMAN_CMD_GETALLMEMBERS: - err = do_cmd_get_all_members(cmdbuf, retbuf, retsize, retlen, offset); - break; - - case CMAN_CMD_GETNODECOUNT: - err = get_node_count(); - break; - - case CMAN_CMD_GETNODE: - err = do_cmd_get_node(cmdbuf, outbuf+offset, retlen); - break; - - case CMAN_CMD_GETCLUSTER: - err = do_cmd_get_cluster(cmdbuf, outbuf+offset, retlen); - break; - - case CMAN_CMD_GETEXTRAINFO: - err = do_cmd_get_extrainfo(cmdbuf, retbuf, retsize, retlen, offset); - break; - - case CMAN_CMD_ISQUORATE: - return cluster_is_quorate; - - case CMAN_CMD_ISACTIVE: - return ais_running; - - case CMAN_CMD_SETEXPECTED_VOTES: - err = do_cmd_set_expected(cmdbuf, retlen); - break; - - /* Change the number of votes for this node */ - case CMAN_CMD_SET_VOTES: - err = do_cmd_set_votes(cmdbuf, retlen); - break; - - /* Return 1 if the specified node is listening on a given port */ - case CMAN_CMD_ISLISTENING: - err = do_cmd_islistening(con, cmdbuf, retlen); - break; - - /* Forcibly kill a node */ - case CMAN_CMD_KILLNODE: - err = do_cmd_kill_node(cmdbuf, retlen); - break; - - case CMAN_CMD_BARRIER: - err = do_cmd_barrier(con, cmdbuf, retlen); - break; - - case CMAN_CMD_LEAVE_CLUSTER: - err = do_cmd_leave_cluster(cmdbuf, retlen); - break; - - case CMAN_CMD_GET_JOINCOUNT: - err = num_connections; - break; - - case CMAN_CMD_TRY_SHUTDOWN: - err = do_cmd_try_shutdown(con, cmdbuf); - break; - - case CMAN_CMD_SHUTDOWN_REPLY: - err = do_cmd_shutdown_reply(con, cmdbuf); - break; - - case CMAN_CMD_REG_QUORUMDEV: - err = do_cmd_register_quorum_device(cmdbuf, retlen); - break; - - case CMAN_CMD_UNREG_QUORUMDEV: - err = do_cmd_unregister_quorum_device(cmdbuf, retlen); - break; - - case CMAN_CMD_POLL_QUORUMDEV: - err = do_cmd_poll_quorum_device(cmdbuf, retlen); - break; - - case CMAN_CMD_UPDATE_FENCE_INFO: - err = do_cmd_update_fence_info(cmdbuf); - break; - - case CMAN_CMD_GET_FENCE_INFO: - err = do_cmd_get_fence_info(cmdbuf, retbuf, retsize, retlen, offset); - break; - - case CMAN_CMD_GET_NODEADDRS: - err = do_cmd_get_node_addrs(cmdbuf, retbuf, retsize, retlen, offset); - break; - } - P_MEMB("command return code is %d\n", err); - return err; -} - - -int send_to_userport(unsigned char fromport, unsigned char toport, - int nodeid, int tgtid, - char *recv_buf, int len, - int endian_conv) -{ - int ret = -1; - - if (toport == 0) { - process_internal_message(recv_buf, nodeid, endian_conv); - ret = 0; - } - else { - /* Send to external listener */ - if (port_array[toport]) { - struct connection *c = port_array[toport]; - - P_MEMB("send_to_userport. cmd=%d, endian_conv=%d\n", recv_buf[0],endian_conv); - - send_data_reply(c, nodeid, fromport, recv_buf, len); - ret = 0; - } - } - return ret; -} - -void cman_send_confchg(unsigned int *member_list, int member_list_entries, - unsigned int *left_list, int left_list_entries, - unsigned int *joined_list, int joined_list_entries) -{ - char buf[sizeof(struct sock_confchg_message) + - (member_list_entries+left_list_entries+joined_list_entries) * sizeof(int)]; - struct sock_confchg_message *msg = (struct sock_confchg_message *)buf; - - msg->header.magic = CMAN_MAGIC; - msg->header.command = CMAN_CMD_CONFCHG; - msg->header.length = sizeof(buf); - msg->header.flags = 0; - - msg->member_entries = member_list_entries; - msg->joined_entries = joined_list_entries; - msg->left_entries = left_list_entries; - - memcpy(msg->entries, member_list, sizeof(int)*member_list_entries); - memcpy(msg->entries+member_list_entries, left_list, sizeof(int)*left_list_entries); - memcpy(msg->entries+member_list_entries+left_list_entries, joined_list, sizeof(int)*joined_list_entries); - - notify_confchg((struct sock_header *)msg); -} - - -/* Send a port closedown message to all cluster nodes - this tells them that a - * port listener has gone away */ -static int send_port_close_msg(unsigned char port) -{ - struct cl_portmsg portmsg; - - /* Build the header */ - portmsg.cmd = CLUSTER_MSG_PORTCLOSED; - portmsg.port = port; - - return comms_send_message(&portmsg, sizeof(portmsg), 0,0, 0, 0); -} - -static int send_port_enquire(int nodeid) -{ - char msg[1]; - - /* Build the header */ - msg[0] = CLUSTER_MSG_PORTENQ; - - return comms_send_message(msg, 1, 0,0, nodeid, 0); -} - -static int send_port_open_msg(unsigned char port) -{ - struct cl_portmsg portmsg; - - /* Build the header */ - portmsg.cmd = CLUSTER_MSG_PORTOPENED; - portmsg.port = port; - - return comms_send_message(&portmsg, sizeof(portmsg), 0,0, 0, 0); -} - -void unbind_con(struct connection *con) -{ - if (con->port) { - P_MEMB("Unbinding con for port %d\n", con->port); - port_array[con->port] = NULL; - send_port_close_msg(con->port); - clear_port_bit(us, con->port); - con->port = 0; - } - - /* If we're in shutdown and this client was listening for events - then we take its closedown as a "Yes" to the "can we shutdown" - question. If it previously answered "No", we need to change its vote */ - if (shutdown_con && con->events) { - if (con->shutdown_reply) { - if (con->shutdown_reply == SHUTDOWN_REPLY_YES) - shutdown_yes--; - if (con->shutdown_reply == SHUTDOWN_REPLY_NO) - shutdown_no--; - } - con->shutdown_reply = SHUTDOWN_REPLY_YES; /* I'll take that as a "Yes" then */ - shutdown_yes++; - - check_shutdown_status(); - } - - /* If the controlling shutdown process has quit, then cancel the - shutdown session */ - if (con == shutdown_con) - shutdown_con = NULL; -} - -/* Post a PORT OPEN/CLOSE event to anyone listening on this end */ -static void post_port_event(int reason, unsigned char port, int nodeid) -{ - struct connection *con = port_array[port]; - - if (con) - notify_listeners(con, reason, nodeid); -} - -int our_nodeid() -{ - if (us) - return us->node_id; - else - return 0; -} - -/* Sanity check TRANSITION message */ -static int valid_transition_msg(int nodeid, struct cl_transmsg *msg) -{ - if (strcmp(msg->clustername, cluster_name) != 0) { - log_printf(LOG_ERR, "Node %d conflict, remote cluster name='%s', local='%s'\n", - nodeid, msg->clustername, cluster_name); - return -1; - } - - if (msg->cluster_id != cluster_id) { - log_printf(LOG_ERR, "Node %d conflict, remote cluster id=%d, local=%d\n", - nodeid, msg->cluster_id, cluster_id); - return -1; - } - - if (msg->major_version != CNXMAN_MAJOR_VERSION) { - - log_printf(LOG_ERR, "Node %d conflict, remote version id=%d, local=%d\n", - nodeid, msg->major_version, CNXMAN_MAJOR_VERSION); - return -1; - } - - /* New config version - try to read new file */ - if (msg->config_version > config_version) { - - reread_config(msg->config_version); - - if (config_version > msg->config_version) { - /* Tell everyone else to update */ - send_reconfigure(us->node_id, RECONFIG_PARAM_CONFIG_VERSION, config_version); - } - recalculate_quorum(0, 0); - notify_listeners(NULL, EVENT_REASON_CONFIG_UPDATE, config_version); - } - - - if (msg->config_version != config_version) { - log_printf(LOG_ERR, "Node %d conflict, remote config version id=%d, local=%d\n", - nodeid, msg->config_version, config_version); - return -1; - } - - return 0; -} - - -void send_transition_msg(int last_memb_count, int first_trans) -{ - char buf[sizeof(struct cl_transmsg)+1024] __attribute__((aligned(8))); - struct cl_transmsg *msg = (struct cl_transmsg *)buf; - int len = sizeof(struct cl_transmsg); - - we_are_a_cluster_member = 1; - - P_MEMB("sending TRANSITION message. cluster_name = %s\n", cluster_name); - msg->cmd = CLUSTER_MSG_TRANSITION; - msg->first_trans = first_trans; - msg->votes = us->votes; - msg->expected_votes = us->expected_votes; - msg->cluster_id = cluster_id; - msg->major_version = CNXMAN_MAJOR_VERSION; - msg->minor_version = CNXMAN_MINOR_VERSION; - msg->patch_version = CNXMAN_PATCH_VERSION; - msg->config_version = config_version; - msg->flags = us->flags; - msg->fence_time = us->fence_time; - msg->join_time = join_time; - strcpy(msg->clustername, cluster_name); - if (us->fence_agent) - { - strcpy(msg->fence_agent, us->fence_agent); - len += strlen(us->fence_agent)+1; - } - else - { - msg->fence_agent[0] = '\0'; - len += 1; - } - - if (have_disallowed()) - msg->flags |= NODE_FLAGS_SEESDISALLOWED; - - comms_send_message(msg, len, - 0,0, - 0, /* multicast */ - 0); /* flags */ -} - -static void byteswap_internal_message(char *data) -{ - struct cl_protmsg *msg = (struct cl_protmsg *)data; - struct cl_barriermsg *barriermsg; - struct cl_killmsg *killmsg; - struct cl_leavemsg *leavemsg; - struct cl_transmsg *transmsg; - struct cl_fencemsg *fencemsg; - struct cl_reconfig_msg *reconfmsg; - - switch (msg->cmd) { - case CLUSTER_MSG_PORTOPENED: - case CLUSTER_MSG_PORTCLOSED: - /* Just a byte */ - break; - - case CLUSTER_MSG_TRANSITION: - transmsg = (struct cl_transmsg *)data; - transmsg->cluster_id = swab16(transmsg->cluster_id); - transmsg->votes = swab32(transmsg->votes); - transmsg->expected_votes = swab32(transmsg->expected_votes); - transmsg->major_version = swab32(transmsg->major_version); - transmsg->minor_version = swab32(transmsg->minor_version); - transmsg->patch_version = swab32(transmsg->patch_version); - transmsg->config_version = swab32(transmsg->config_version); - transmsg->flags = swab32(transmsg->flags); - transmsg->fence_time = swab64(transmsg->fence_time); - break; - - case CLUSTER_MSG_KILLNODE: - killmsg = (struct cl_killmsg *)data; - killmsg->reason = swab16(killmsg->reason); - killmsg->nodeid = swab32(killmsg->nodeid); - break; - - case CLUSTER_MSG_LEAVE: - leavemsg = (struct cl_leavemsg *)data; - leavemsg->reason = swab16(leavemsg->reason); - break; - - case CLUSTER_MSG_BARRIER: - barriermsg = (struct cl_barriermsg *)data; - break; - - case CLUSTER_MSG_RECONFIGURE: - reconfmsg = (struct cl_reconfig_msg *)data; - reconfmsg->nodeid = swab32(reconfmsg->nodeid); - reconfmsg->value = swab32(reconfmsg->value); - break; - - case CLUSTER_MSG_FENCESTATUS: - fencemsg = (struct cl_fencemsg *)data; - fencemsg->timesec = swab64(fencemsg->timesec); - fencemsg->nodeid = swab32(fencemsg->nodeid); - break; - } -} - - -static void do_reconfigure_msg(void *data) -{ - struct cl_reconfig_msg *msg = data; - struct cluster_node *node; - struct list *nodelist; - - node = find_node_by_nodeid(msg->nodeid); - if (!node) - return; - - switch(msg->param) - { - case RECONFIG_PARAM_EXPECTED_VOTES: - node->expected_votes = msg->value; - - list_iterate(nodelist, &cluster_members_list) { - node = list_item(nodelist, struct cluster_node); - if (node->state == NODESTATE_MEMBER && - node->expected_votes > msg->value) { - node->expected_votes = msg->value; - } - } - recalculate_quorum(1, 0); /* Allow decrease */ - break; - - case RECONFIG_PARAM_NODE_VOTES: - node->votes = msg->value; - recalculate_quorum(1, 0); /* Allow decrease */ - break; - - case RECONFIG_PARAM_CONFIG_VERSION: - if (config_version != msg->value) { - reread_config(msg->value); - } - notify_listeners(NULL, EVENT_REASON_CONFIG_UPDATE, config_version); - break; - } -} - -static void do_fence_msg(void *data) -{ - struct cl_fencemsg *msg = data; - struct cluster_node *node; - - P_DAEMON("got FENCE message, node %d fenced by %s\n", msg->nodeid, msg->agent); - - node = find_node_by_nodeid(msg->nodeid); - if (!node) - return; - - node->fence_time = msg->timesec; - if (node->fence_agent) - free(node->fence_agent); - node->fence_agent = strdup(msg->agent); - if (msg->fenced) { - node->flags |= NODE_FLAGS_FENCED; - - if (node->state == NODESTATE_MEMBER) - node->flags |= NODE_FLAGS_FENCEDWHILEUP; - } - -} - -static void do_process_transition(int nodeid, char *data) -{ - struct cl_transmsg *msg = (struct cl_transmsg *)data; - struct cluster_node *node; - - if (valid_transition_msg(nodeid, msg) != 0) { - P_MEMB("Transition message from %d does not match current config - should quit ?\n", nodeid); - // Now what ?? - return; - } - - /* If the remote node can see AISONLY nodes then we can't join as we don't - know the full state */ - if (msg->flags & NODE_FLAGS_SEESDISALLOWED && !have_disallowed()) { - /* Must use syslog directly here or the message will never arrive */ - syslog(LOG_CRIT, "CMAN: Joined a cluster with disallowed nodes. must die"); - exit(2); - } - msg->flags &= ~NODE_FLAGS_SEESDISALLOWED; - - node = find_node_by_nodeid(nodeid); - if (!node) { - add_ais_node(nodeid, incarnation, num_ais_nodes); - node = find_node_by_nodeid(nodeid); - } - assert(node); - - P_MEMB("Got TRANSITION message. msg->flags=%x, node->flags=%x, first_trans=%d\n", - msg->flags, node->flags, msg->first_trans); - - /* Newer nodes 6.1.0 onwards, set the DIRTY flag if they have state. If the new node has been down - and has state then we mark it disallowed because we cannot merge stateful nodes */ - if ( (msg->flags & NODE_FLAGS_DIRTY && (node->flags & NODE_FLAGS_BEENDOWN)) || - (msg->flags & NODE_FLAGS_DIRTY && msg->first_trans && !node->us)) { - /* Don't duplicate messages */ - if (node->state != NODESTATE_AISONLY) { - if (cluster_is_quorate) { - P_MEMB("Killing node %s because it has rejoined the cluster with existing state", node->name); - log_printf(LOG_CRIT, "Killing node %s because it has rejoined the cluster with existing state", node->name); - node->state = NODESTATE_AISONLY; - send_kill(nodeid, CLUSTER_KILL_REJOIN); - } - else { - P_MEMB("Node %s not joined to cman because it has existing state", node->name); - log_printf(LOG_CRIT, "Node %s not joined to cman because it has existing state", node->name); - node->state = NODESTATE_AISONLY; - } - } - return; - } - - /* This is for older nodes. If the join_time of the node matches that already stored AND - the node has been down, then we kill it as this must be a rejoin */ - if (msg->minor_version == 0 && - msg->join_time == node->cman_join_time && node->flags & NODE_FLAGS_BEENDOWN) { - /* Don't duplicate messages */ - if (node->state != NODESTATE_AISONLY) { - if (cluster_is_quorate) { - P_MEMB("Killing node %s because it has rejoined the cluster without cman_tool join", node->name); - log_printf(LOG_CRIT, "Killing node %s because it has rejoined the cluster without cman_tool join", node->name); - node->state = NODESTATE_AISONLY; - send_kill(nodeid, CLUSTER_KILL_REJOIN); - } - else { - P_MEMB("Node %s not joined to cman because it has rejoined an inquorate cluster", node->name); - log_printf(LOG_CRIT, "Node %s not joined to cman because it has rejoined an inquorate cluster", node->name); - node->state = NODESTATE_AISONLY; - } - } - return; - } - else { - node->cman_join_time = msg->join_time; - add_ais_node(nodeid, incarnation, num_ais_nodes); - } - - /* If the cluster already has some AISONLY nodes then we can't make - sense of the membership. So the new node has to also be AISONLY - until we are consistent again */ - if (have_disallowed() && !node->us) - node->state = NODESTATE_AISONLY; - - node->flags = msg->flags; /* This will clear the BEENDOWN flag of course */ - - /* Take into account any new expected_votes value that the new node has */ - node->expected_votes = msg->expected_votes; - recalculate_quorum(0, 0); - - if (node->fence_agent && msg->fence_agent[0] && strcmp(node->fence_agent, msg->fence_agent)) - { - free(node->fence_agent); - node->fence_agent = strdup(msg->fence_agent); - node->fence_time = msg->fence_time; - } - - /* - * If this is a rejoined node then it won't know about its own fence data, send it - * some - */ - if (node->fence_time && !msg->fence_time && - node->fence_agent && !msg->fence_agent[0]) - { - char msg[sizeof(struct cl_fencemsg)+strlen(node->fence_agent)+1]; - struct cl_fencemsg *fence_msg = (struct cl_fencemsg *)msg; - - fence_msg->cmd = CLUSTER_MSG_FENCESTATUS; - fence_msg->nodeid = nodeid; - fence_msg->timesec = node->fence_time; - fence_msg->fenced = 0; - strcpy(fence_msg->agent, node->fence_agent); - comms_send_message(msg, sizeof(msg), 0,0, nodeid, 0); - } -} - -static void process_internal_message(char *data, int nodeid, int need_byteswap) -{ - struct cl_protmsg *msg = (struct cl_protmsg *)data; - struct cl_portmsg *portmsg; - struct cl_barriermsg *barriermsg; - struct cl_killmsg *killmsg; - struct cl_leavemsg *leavemsg; - struct cluster_node *node = find_node_by_nodeid(nodeid); - unsigned char portresult[PORT_BITS_SIZE+1]; - - P_MEMB("Message on port 0 is %d\n", msg->cmd); - - /* Byteswap messages if needed */ - if (need_byteswap) - byteswap_internal_message(data); - - switch (msg->cmd) { - case CLUSTER_MSG_PORTOPENED: - portmsg = (struct cl_portmsg *)data; - if (node) - set_port_bit(node, portmsg->port); - post_port_event(EVENT_REASON_PORTOPENED, portmsg->port, nodeid); - break; - - case CLUSTER_MSG_PORTCLOSED: - portmsg = (struct cl_portmsg *)data; - if (node) - clear_port_bit(node, portmsg->port); - post_port_event(EVENT_REASON_PORTCLOSED, portmsg->port, nodeid); - break; - - case CLUSTER_MSG_PORTENQ: - portresult[0] = CLUSTER_MSG_PORTSTATUS; - memcpy(portresult+1, us->port_bits, PORT_BITS_SIZE); - P_MEMB("Sending PORTRESULT, low bytes = %x %x\n", us->port_bits[0], us->port_bits[1]); - - /* Broadcast reply as other new nodes may be interested */ - comms_send_message(portresult, PORT_BITS_SIZE+1, 0,0, 0, 0); - break; - - case CLUSTER_MSG_PORTSTATUS: - if (nodeid != us->node_id) { - P_MEMB("got PORTRESULT from %d, low bytes = %x %x\n", nodeid, data[1], data[2]); - if (node) - memcpy(node->port_bits, data+1, PORT_BITS_SIZE); - } - break; - - case CLUSTER_MSG_TRANSITION: - P_MEMB("got TRANSITION from node %d\n", nodeid); - do_process_transition(nodeid, data); - break; - - case CLUSTER_MSG_KILLNODE: - killmsg = (struct cl_killmsg *)data; - P_MEMB("got KILL for node %d\n", killmsg->nodeid); - if (killmsg->nodeid == wanted_nodeid) { - /* Must use syslog directly here or the message will never arrive */ - syslog(LOG_CRIT, "cman killed by node %d because %s\n", nodeid, - killmsg_reason(killmsg->reason)); - exit(1); - } - break; - - case CLUSTER_MSG_LEAVE: - leavemsg = (struct cl_leavemsg *)data; - P_MEMB("got LEAVE from node %d, reason = %d\n", nodeid, leavemsg->reason); - - /* We got our own leave message back. now quit */ - if (node && node->node_id == us->node_id) { - /* Tell whomever asked us to leave that we are now going down */ - if (shutdown_con) - send_status_return(shutdown_con, CMAN_CMD_TRY_SHUTDOWN, 0); - exit(0); - } - - /* Someone else, make a note of the reason for leaving */ - if (node) - node->leave_reason = leavemsg->reason; - - /* Mark it as leaving, and remove it when we get an AIS node down event for it */ - if (node && (node->state == NODESTATE_MEMBER || node->state == NODESTATE_AISONLY)) - node->state = NODESTATE_LEAVING; - break; - - case CLUSTER_MSG_BARRIER: - barriermsg = (struct cl_barriermsg *)data; - if (node) - process_barrier_msg(barriermsg, node); - break; - - case CLUSTER_MSG_RECONFIGURE: - do_reconfigure_msg(data); - break; - - case CLUSTER_MSG_FENCESTATUS: - do_fence_msg(data); - break; - - default: - log_printf(LOG_WARNING, "Unknown protocol message %d received\n", msg->cmd); - break; - - } -} - -void override_expected(int newexp) -{ - struct list *nodelist; - struct cluster_node *node; - - list_iterate(nodelist, &cluster_members_list) { - node = list_item(nodelist, struct cluster_node); - if (node->state == NODESTATE_MEMBER - && node->expected_votes > newexp) { - node->expected_votes = newexp; - } - } -} - -void clear_reread_flags() -{ - struct list *nodelist; - struct cluster_node *node; - - list_iterate(nodelist, &cluster_members_list) { - node = list_item(nodelist, struct cluster_node); - node->flags &= ~NODE_FLAGS_REREAD; - } -} - -void remove_unread_nodes() -{ - struct list *nodelist, *tmp; - struct cluster_node *node; - - list_iterate_safe(nodelist, tmp, &cluster_members_list) { - node = list_item(nodelist, struct cluster_node); - if (!(node->flags & NODE_FLAGS_REREAD) && - node->state == NODESTATE_DEAD) { - - list_del(&node->list); - free(node); - } - } -} - -/* Add a node from CCS, note that it may already exist if user has simply updated the config file */ -void add_ccs_node(char *nodename, int nodeid, int votes, int expected_votes) -{ - /* Update node entry */ - add_new_node(nodename, nodeid, votes, expected_votes, NODESTATE_DEAD); -} - -void add_ais_node(int nodeid, uint64_t incarnation, int total_members) -{ - struct cluster_node *node; - - P_MEMB("add_ais_node ID=%d, incarnation = %" PRIu64 "\n",nodeid, incarnation); - - node = find_node_by_nodeid(nodeid); - if (!node && total_members == 1) { - node = us; - P_MEMB("Adding AIS node for 'us'\n"); - } - - /* This really should exist!! */ - if (!node) { - char tempname[256]; - log_printf(LOG_ERR, "Got node from AIS id %d with no config entry\n", nodeid); - - /* Emergency nodename */ - sprintf(tempname, "Node%d", nodeid); - node = add_new_node(tempname, nodeid, 1, total_members, NODESTATE_DEAD); - } - - if (node->state == NODESTATE_DEAD || node->state == NODESTATE_LEAVING) { - gettimeofday(&node->join_time, NULL); - node->incarnation = incarnation; - node->state = NODESTATE_MEMBER; - cluster_members++; - recalculate_quorum(0, 0); - } -} - -void del_ais_node(int nodeid) -{ - struct cluster_node *node; - time_t t; - P_MEMB("del_ais_node %d\n", nodeid); - - node = find_node_by_nodeid(nodeid); - if (!node) - return; - - /* If the node was fenced while up (ie independantly of fenced) then - * don't clear the fenced flag. There is a timeout associated with - * this so if we get the node down more than 2 minutes after the - * fence message then we still clear fenced just to be certain that - * fenced will do the job too. - */ - time(&t); - if (!(node->flags & NODE_FLAGS_FENCEDWHILEUP) || (t - node->fence_time > 120)) - node->flags &= ~NODE_FLAGS_FENCED; - - node->flags &= ~NODE_FLAGS_FENCEDWHILEUP; - node->flags |= NODE_FLAGS_BEENDOWN; - - switch (node->state) { - case NODESTATE_MEMBER: - node->state = NODESTATE_DEAD; - memset(&node->port_bits, 0, sizeof(node->port_bits)); - cluster_members--; - recalculate_quorum(0, 0); - break; - - case NODESTATE_AISONLY: - node->state = NODESTATE_DEAD; - break; - - case NODESTATE_LEAVING: - node->state = NODESTATE_DEAD; - cluster_members--; - - P_MEMB("del_ais_node %s, leave_reason=%x\n", node->name, node->leave_reason); - if ((node->leave_reason & 0xF) == CLUSTER_LEAVEFLAG_REMOVED) - recalculate_quorum(1, 1); - else - recalculate_quorum(0, 0); - break; - - case NODESTATE_JOINING: - case NODESTATE_DEAD: - break; - } -} - -static int get_highest_nodeid() -{ - int highest = 0; - struct cluster_node *node; - - list_iterate_items(node, &cluster_members_list) { - if (node->node_id > highest) - highest = node->node_id; - } - return highest; -} - -static int get_node_count() -{ - int count = 0; - - struct cluster_node *node; - - list_iterate_items(node, &cluster_members_list) { - count++; - } - return count; -} - -static struct cluster_node *find_node_by_nodeid(int nodeid) -{ - struct cluster_node *node; - - list_iterate_items(node, &cluster_members_list) { - if (node->node_id == nodeid) - return node; - } - return NULL; -} - - -static struct cluster_node *find_node_by_name(char *name) -{ - struct cluster_node *node; - - list_iterate_items(node, &cluster_members_list) { - if (node->name && strcmp(node->name, name) == 0) - return node; - } - return NULL; -} - -static char *killmsg_reason(int reason) -{ - static char msg[1024]; - - switch (reason) - { - case CLUSTER_KILL_REJECTED: - return "our membership application was rejected"; - - case CLUSTER_KILL_CMANTOOL: - return "we were killed by cman_tool or other application"; - - case CLUSTER_KILL_REJOIN: - return "we rejoined the cluster without a full restart"; - - default: - sprintf(msg, "we got kill message number %d", reason); - return msg; - } -} diff --git a/cman/daemon/commands.h b/cman/daemon/commands.h deleted file mode 100644 index 5d325ad..0000000 --- a/cman/daemon/commands.h +++ /dev/null @@ -1,37 +0,0 @@ -struct cluster_node; -struct connection; -extern void process_cnxman_message(char *data, char *addr, int addrlen, - struct cluster_node *rem_node); - -extern int send_to_userport(unsigned char fromport, unsigned char toport, - int nodeid, int tgtnodeid, - char *recv_buf, int len, - int endian_conv); -extern void clean_dead_listeners(void); -extern void unbind_con(struct connection *con); -extern void commands_init(void); -extern int process_command(struct connection *con, int cmd, char *cmdbuf, - char **retbuf, int *retlen, int retsize, int offset); -extern void send_transition_msg(int last_memb_count, int first_trans); - -extern void add_ais_node(int nodeid, uint64_t incarnation, int total_members); -extern void del_ais_node(int nodeid); -extern void add_ccs_node(char *name, int nodeid, int votes, int expected_votes); -extern void override_expected(int expected); -extern void cman_send_confchg(unsigned int *member_list, int member_list_entries, - unsigned int *left_list, int left_list_entries, - unsigned int *joined_list, int joined_list_entries); - - -extern void clear_reread_flags(void); -extern void remove_unread_nodes(void); - -/* Startup stuff called from cmanccs: */ -extern int cman_set_nodename(char *name); -extern int cman_set_nodeid(int nodeid); -extern int cman_join_cluster(struct corosync_api_v1 *api, - char *name, unsigned short cluster_id, int two_node, - int votes, int expected_votes); - -extern int cluster_members; -extern uint32_t max_outstanding_messages; diff --git a/cman/daemon/daemon.c b/cman/daemon/daemon.c deleted file mode 100644 index 6cef080..0000000 --- a/cman/daemon/daemon.c +++ /dev/null @@ -1,539 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "list.h" -#include "cnxman-socket.h" -#include "cnxman-private.h" -#include "daemon.h" -#include "logging.h" -#include "commands.h" -#include "barrier.h" -#include "ais.h" -#include "cman.h" - -LOGSYS_DECLARE_SUBSYS (CMAN_NAME, LOG_INFO); - -struct queued_reply -{ - struct list list; - int offset; - char buf[1]; -}; - -/* We need to keep these in a list so we can notify of - cluster events */ -static LIST_INIT(client_list); - -/* Things to wake up for */ -volatile sig_atomic_t quit_threads=0; - -int num_connections = 0; -poll_handle ais_poll_handle; -uint32_t max_outstanding_messages = DEFAULT_MAX_QUEUED; - -static int process_client(poll_handle handle, int fd, int revent, void *data); -static void remove_client(poll_handle handle, struct connection *con); - -/* Send it, or queue it for later if the socket is busy */ -static int send_reply_message(struct connection *con, struct sock_header *msg) -{ - int ret; - - P_DAEMON("sending reply %x to fd %d\n", msg->command, con->fd); - - /* If there are already queued messages then don't send this one - out of order */ - if (!list_empty(&con->write_msgs)) { - ret = -1; - errno = EAGAIN; - } - else { - ret = send(con->fd, (char *)msg, msg->length, MSG_DONTWAIT); - } - - if ((ret > 0 && ret != msg->length) || - (ret == -1 && errno == EAGAIN)) { - struct queued_reply *qm; - - /* Have we exceeded the allowed number of queued messages ? */ - if (con->num_write_msgs > max_outstanding_messages) { - P_DAEMON("Disconnecting. client has more that %d replies outstanding (%d)\n", max_outstanding_messages, con->num_write_msgs); - remove_client(ais_poll_handle, con); - return -1; - } - - /* Queue it */ - qm = malloc(sizeof(struct queued_reply) + msg->length); - if (!qm) - { - perror("Error allocating queued message"); - return -1; - } - memcpy(qm->buf, msg, msg->length); - if (ret > 0) - qm->offset = ret; - else - qm->offset = 0; - list_add(&con->write_msgs, &qm->list); - con->num_write_msgs++; - P_DAEMON("queued last message, count is %d\n", con->num_write_msgs); - poll_dispatch_modify(ais_poll_handle, con->fd, POLLIN | POLLOUT, process_client); - } - return 0; -} - -static void remove_client(poll_handle handle, struct connection *con) -{ - struct list *tmp, *qmh; - struct queued_reply *qm; - int msgs=0; - - poll_dispatch_delete(handle, con->fd); - close(con->fd); - if (con->type == CON_CLIENT) - list_del(&con->list); - - unbind_con(con); - remove_barriers(con); - - list_iterate_safe(qmh, tmp, &con->write_msgs) { - qm = list_item(qmh, struct queued_reply); - - list_del(&qm->list); - free(qm); - msgs++; - } - - P_DAEMON("Freed %d queued messages\n", msgs); - free(con); - num_connections--; -} - -/* Send as many as we can */ -static void send_queued_reply(struct connection *con) -{ - struct queued_reply *qm; - struct sock_header *msg; - struct list *tmp, *qmh; - int ret; - - list_iterate_safe(qmh, tmp, &con->write_msgs) { - qm = list_item(qmh, struct queued_reply); - msg = (struct sock_header *)qm->buf; - ret = send(con->fd, qm->buf + qm->offset, msg->length - qm->offset, MSG_DONTWAIT); - if (ret == msg->length - qm->offset) - { - list_del(&qm->list); - free(qm); - con->num_write_msgs--; - } - else - { - if (ret > 0) - qm->offset += ret; - break; - } - } - if (list_empty(&con->write_msgs)) { - /* Remove POLLOUT callback */ - P_DAEMON("Removing POLLOUT from fd %d\n", con->fd); - poll_dispatch_modify(ais_poll_handle, con->fd, POLLIN, process_client); - } -} - -/* Dispatch a request from a CLIENT or ADMIN socket */ -static int process_client(poll_handle handle, int fd, int revent, void *data) -{ - struct connection *con = data; - - if (revent == POLLOUT) { - send_queued_reply(con); - } else { - char buf[MAX_CLUSTER_MESSAGE + sizeof(struct sock_header)]; - struct sock_header *msg = (struct sock_header *)buf; - int len; - int totallen = 0; - - memset(buf, 0, (MAX_CLUSTER_MESSAGE + sizeof(struct sock_header))); - - len = read(fd, buf, sizeof(struct sock_header)); - - P_DAEMON("read %d bytes from fd %d\n", len, fd); - - if (len == 0) { - remove_client(handle, con); - return -1; - } - - if (len < 0 && - (errno == EINTR || errno == EAGAIN)) - return 0; - - if (len < 0) { - remove_client(handle, con); - return 0; - } - - if (msg->magic != CMAN_MAGIC) { - P_DAEMON("bad magic in client command %x\n", msg->magic); - send_status_return(con, msg->command, -EINVAL); - return 0; - } - if (msg->version != CMAN_VERSION) { - P_DAEMON("bad version in client command. msg = 0x%x, us = 0x%x\n", msg->version, CMAN_VERSION); - send_status_return(con, msg->command, -EINVAL); - return 0; - } - if ((msg->length-len) > MAX_CLUSTER_MESSAGE) { - P_DAEMON("message on socket is too big\n"); - send_status_return(con, msg->command, -EINVAL); - return 0; - } - - totallen = len; - - /* Read the rest */ - while (totallen != msg->length) { - len = read(fd, buf+len, msg->length-len); - if (len == 0) - return -1; - - if (len < 0 && - (errno == EINTR || errno == EAGAIN)) - return 0; - - if (len < 0) { - remove_client(handle, con); - return -1; - } - totallen += len; - } - - P_DAEMON("client command is %x\n", msg->command); - - /* Privileged functions can only be done on ADMIN sockets */ - if (msg->command & CMAN_CMDFLAG_PRIV && con->type != CON_ADMIN) { - P_DAEMON("command disallowed from non-admin client\n"); - send_status_return(con, msg->command, -EPERM); - return 0; - } - - /* Slightly arbitrary this one, don't allow ADMIN sockets to - send/receive data. The main loop doesn't keep a backlog queue - of messages for ADMIN sockets - */ - if ((msg->command == CMAN_CMD_DATA || msg->command == CMAN_CMD_BIND || - msg->command == CMAN_CMD_NOTIFY) && con->type == CON_ADMIN) { - P_DAEMON("can't send data down an admin socket, sorry\n"); - send_status_return(con, msg->command, -EINVAL); - return 0; - } - - if (msg->command == CMAN_CMD_DATA) { - char *buf = (char *)msg; - int ret; - uint8_t port; - struct sock_data_header *dmsg = (struct sock_data_header *)msg; - - P_DAEMON("sending %lu bytes of data to node %d, port %d\n", - (unsigned long)(msg->length - sizeof(struct sock_data_header)), dmsg->nodeid, dmsg->port); - - buf += sizeof(struct sock_data_header); - - if (dmsg->port > 255) { - send_status_return(con, msg->command, -EINVAL); - return 0; - } - - if (dmsg->port) - port = dmsg->port; - else - port = con->port; - - ret = comms_send_message(buf, msg->length - sizeof(struct sock_data_header), - port, con->port, - dmsg->nodeid, - msg->flags); - if (ret) { - send_status_return(con, msg->command, -EIO); - } - } - else { - char *cmdbuf = (char *)msg; - char small_retbuf[1024]; /* Enough for most needs */ - char *retbuf = small_retbuf; - struct sock_reply_header *reply; - int ret; - int retlen = 0; - - P_DAEMON("About to process command\n"); - - cmdbuf += sizeof(struct sock_header); - - ret = process_command(con, msg->command, cmdbuf, - &retbuf, &retlen, sizeof(small_retbuf), - sizeof(struct sock_reply_header)); - - /* Reply message will come later on */ - if (ret == -EWOULDBLOCK) - return 0; - - reply = (struct sock_reply_header *)retbuf; - - reply->header.magic = CMAN_MAGIC; - reply->header.flags = 0; - reply->header.command = msg->command | CMAN_CMDFLAG_REPLY; - reply->header.length = retlen + sizeof(struct sock_reply_header); - reply->status = ret; - - P_DAEMON("Returning command data. length = %d\n", retlen); - send_reply_message(con, (struct sock_header *)reply); - - if (retbuf != small_retbuf) - free(retbuf); - } - } - return 0; -} - - -/* Both client and admin rendezvous sockets use this */ -static int process_rendezvous(poll_handle handle, int fd, int revent, void *data) -{ - struct sockaddr_un socka; - struct connection *con = data; - socklen_t sl = sizeof(socka); - int client_fd; - - client_fd = accept(fd, (struct sockaddr *) &socka, &sl); - if (client_fd >= 0) { - struct connection *newcon = malloc(sizeof(struct connection)); - if (!newcon) { - close(client_fd); - return 0; /* returning -1 will remove us */ - } - - newcon->fd = client_fd; - newcon->type = con->type; - newcon->port = 0; - newcon->events = 0; - newcon->num_write_msgs = 0; - list_init(&newcon->write_msgs); - fcntl(client_fd, F_SETFL, fcntl(client_fd, F_GETFL, 0) | O_NONBLOCK); - - poll_dispatch_add(handle, client_fd, POLLIN, newcon, process_client); - num_connections++; - if (newcon->type == CON_CLIENT) - list_add(&client_list, &newcon->list); - } - return 0; -} - -static int open_local_sock(const char *name, int name_len, mode_t mode, poll_handle handle, int type) -{ - int local_socket; - struct sockaddr_un sockaddr; - struct connection *con; - - /* Open local socket */ - if (name[0] != '\0') - unlink(name); - local_socket = socket(PF_UNIX, SOCK_STREAM, 0); - if (local_socket < 0) { - log_printf(LOG_ERR, "Can't create local socket %s: %s\n", name, strerror(errno)); - write_cman_pipe("Can't create local cman socket"); - return -1; - } - /* Set Close-on-exec */ - fcntl(local_socket, F_SETFD, 1); - fcntl(local_socket, F_SETFL, fcntl(local_socket, F_GETFL, 0) | O_NONBLOCK); - - memset(&sockaddr, 0, sizeof(sockaddr)); - memcpy(sockaddr.sun_path, name, name_len); - sockaddr.sun_family = AF_UNIX; - if (bind(local_socket, (struct sockaddr *) &sockaddr, sizeof(sockaddr))) { - log_printf(LOG_ERR, "can't bind local socket to %s: %s\n", name, strerror(errno)); - write_cman_pipe("Can't bind to local cman socket"); - close(local_socket); - return -1; - } - if (listen(local_socket, 1) != 0) { - log_printf(LOG_ERR, "listen on %s failed: %s\n", name, strerror(errno)); - write_cman_pipe("listen failed on local cman socket"); - close(local_socket); - return -1; - } - if (name[0] != '\0') - chmod(name, mode); - - - con = malloc(sizeof(struct connection)); - if (!con) { - log_printf(LOG_ERR, "Can't allocate space for local connection: %s\n", strerror(errno)); - write_cman_pipe("malloc failed for connection info"); - close(local_socket); - return -1; - } - con->type = type; - con->fd = local_socket; - con->num_write_msgs = 0; - - poll_dispatch_add(handle, con->fd, POLLIN, con, process_rendezvous); - - return 0; -} - - - -/* Send a simple return - usually just a failure status */ -int send_status_return(struct connection *con, uint32_t cmd, int status) -{ - struct sock_reply_header msg; - - P_DAEMON("send status return: %d\n", status); - msg.header.magic = CMAN_MAGIC; - msg.header.command = cmd | CMAN_CMDFLAG_REPLY; - msg.header.length = sizeof(msg); - msg.header.flags = 0; - msg.status = status; - - return send_reply_message(con, (struct sock_header *)&msg); -} - -int send_data_reply(struct connection *con, int nodeid, int port, char *data, int len) -{ - char buf[len + sizeof(struct sock_data_header)]; - struct sock_data_header *msg = (struct sock_data_header *)buf; - - msg->header.magic = CMAN_MAGIC; - msg->header.command = CMAN_CMD_DATA | CMAN_CMDFLAG_REPLY; - msg->header.length = sizeof(*msg)+len; - msg->header.flags = 0; - msg->nodeid = nodeid; - msg->port = port; - - memcpy(buf+sizeof(struct sock_data_header), data, len); - return send_reply_message(con, (struct sock_header *)msg); -} - -/* This can be called by the membership thread as well as the daemon thread. */ -void notify_listeners(struct connection *con, int event, int arg) -{ - struct sock_event_message msg; - struct connection *thiscon; - - msg.header.magic = CMAN_MAGIC; - msg.header.command = CMAN_CMD_EVENT; - msg.header.length = sizeof(msg); - msg.header.flags = 0; - msg.reason = event; - msg.arg = arg; - - /* Unicast message */ - if (con) { - send_reply_message(con, (struct sock_header *)&msg); - return; - } - - /* Broadcast message */ - list_iterate_items(thiscon, &client_list) { - if (thiscon->events) - send_reply_message(thiscon, (struct sock_header *)&msg); - } -} - -void notify_confchg(struct sock_header *message) -{ - struct connection *thiscon; - - list_iterate_items(thiscon, &client_list) { - if (thiscon->confchg) - send_reply_message(thiscon, message); - } -} - -void wake_daemon(void) -{ - P_DAEMON("Wake daemon called\n"); -} - - -int num_listeners(void) -{ - int count = 0; - struct connection *thiscon; - - list_iterate_items(thiscon, &client_list) { - thiscon->shutdown_reply = SHUTDOWN_REPLY_UNK; /* Clear out for new shutdown request */ - if (thiscon->events) - count++; - } - return count; -} - -static void sigint_handler(int ignored) -{ - quit_threads = 1; -} - -extern poll_handle aisexec_poll_handle; -int cman_init() -{ - int fd; - struct sigaction sa; - - ais_poll_handle = aisexec_poll_handle; - barrier_init(); - - log_printf(LOG_INFO, "CMAN %s (built %s %s) started\n", - RELEASE_VERSION, __DATE__, __TIME__); - - fd = open_local_sock(CLIENT_SOCKNAME, sizeof(CLIENT_SOCKNAME), 0660, ais_poll_handle, CON_CLIENT); - if (fd < 0) - return -2; - - fd = open_local_sock(ADMIN_SOCKNAME, sizeof(ADMIN_SOCKNAME), 0600, ais_poll_handle, CON_ADMIN); - if (fd < 0) - return -2; - - /* Shutdown trap */ - sa.sa_handler = sigint_handler; - sigaction(SIGINT, &sa, NULL); - sigaction(SIGTERM, &sa, NULL); - - sa.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &sa, NULL); - - return 0; -} - -int cman_finish() -{ - /* Stop */ - unlink(CLIENT_SOCKNAME); - unlink(ADMIN_SOCKNAME); - - return 0; -} - diff --git a/cman/daemon/daemon.h b/cman/daemon/daemon.h deleted file mode 100644 index 6907de3..0000000 --- a/cman/daemon/daemon.h +++ /dev/null @@ -1,12 +0,0 @@ -extern int send_status_return(struct connection *con, uint32_t cmd, int status); -extern int send_data_reply(struct connection *con, int nodeid, int port, char *data, int len); -extern void set_cman_timeout(int secs); -extern void notify_listeners(struct connection *con, int reason, int arg); -extern int num_listeners(void); -extern void cman_set_realtime(void); -extern int cman_init(void); -extern int cman_finish(void); -extern void notify_confchg(struct sock_header *message); - -extern volatile sig_atomic_t quit_threads; -extern int num_connections; diff --git a/cman/daemon/list.h b/cman/daemon/list.h deleted file mode 100644 index aaee167..0000000 --- a/cman/daemon/list.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef _LVM_LIST_H -#define _LVM_LIST_H - -#include - -struct list { - struct list *n, *p; -}; - -#define LIST_INIT(name) struct list name = { &(name), &(name) } - -static inline void list_init(struct list *head) -{ - head->n = head->p = head; -} - -static inline void list_add(struct list *head, struct list *elem) -{ - assert(head->n); - - elem->n = head; - elem->p = head->p; - - head->p->n = elem; - head->p = elem; -} - -static inline void list_add_h(struct list *head, struct list *elem) -{ - assert(head->n); - - elem->n = head->n; - elem->p = head; - - head->n->p = elem; - head->n = elem; -} - -static inline void list_del(struct list *elem) -{ - elem->n->p = elem->p; - elem->p->n = elem->n; -} - -static inline int list_empty(struct list *head) -{ - return head->n == head; -} - -static inline int list_end(struct list *head, struct list *elem) -{ - return elem->n == head; -} - -static inline struct list *list_next(struct list *head, struct list *elem) -{ - return (list_end(head, elem) ? NULL : elem->n); -} - -#define list_item(v, t) \ - ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->list)) - -#define list_struct_base(v, t, h) \ - ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->h)) - -/* Given a known element in a known structure, locate another */ -#define struct_field(v, t, e, f) \ - (((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->f) - -/* Given a known element in a known structure, locate the list head */ -#define list_head(v, t, e) struct_field(v, t, e, list) - -#define list_iterate(v, head) \ - for (v = (head)->n; v != head; v = v->n) - -#define list_uniterate(v, head, start) \ - for (v = (start)->p; v != head; v = v->p) - -#define list_iterate_safe(v, t, head) \ - for (v = (head)->n, t = v->n; v != head; v = t, t = v->n) - -#define list_iterate_items(v, head) \ - for (v = list_item((head)->n, typeof(*v)); &v->list != (head); \ - v = list_item(v->list.n, typeof(*v))) - -static inline unsigned int list_size(const struct list *head) -{ - unsigned int s = 0; - const struct list *v; - - list_iterate(v, head) - s++; - - return s; -} - -#endif diff --git a/cman/daemon/logging.c b/cman/daemon/logging.c deleted file mode 100644 index ad3359f..0000000 --- a/cman/daemon/logging.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "list.h" -#include "cman.h" -#include "cnxman-socket.h" -#include "cnxman-private.h" -#include "logging.h" - -LOGSYS_DECLARE_SUBSYS (CMAN_NAME, LOG_INFO); - -int subsys_mask = 0; - -void set_debuglog(int subsystems) -{ - subsys_mask = subsystems; -} diff --git a/cman/daemon/logging.h b/cman/daemon/logging.h deleted file mode 100644 index 23ecb90..0000000 --- a/cman/daemon/logging.h +++ /dev/null @@ -1,17 +0,0 @@ -//#include - -extern void set_debuglog(int subsystems); - -/* Debug macros */ -#define CMAN_DEBUG_NONE 1 -#define CMAN_DEBUG_BARRIER 2 -#define CMAN_DEBUG_MEMB 4 -#define CMAN_DEBUG_DAEMON 8 -#define CMAN_DEBUG_AIS 16 - -extern int subsys_mask; - -#define P_BARRIER(fmt, args...) if (subsys_mask & CMAN_DEBUG_BARRIER) log_printf(LOG_LEVEL_DEBUG, "barrier: " fmt, ## args) -#define P_MEMB(fmt, args...) if (subsys_mask & CMAN_DEBUG_MEMB) log_printf(LOG_LEVEL_DEBUG, "memb: " fmt, ## args) -#define P_DAEMON(fmt, args...) if (subsys_mask & CMAN_DEBUG_DAEMON) log_printf(LOG_LEVEL_DEBUG , "daemon: " fmt, ## args) -#define P_AIS(fmt, args...) if (subsys_mask & CMAN_DEBUG_AIS) log_printf(LOG_LEVEL_DEBUG, "ais " fmt, ## args) diff --git a/cman/daemon/nodelist.h b/cman/daemon/nodelist.h deleted file mode 100644 index 02dfe17..0000000 --- a/cman/daemon/nodelist.h +++ /dev/null @@ -1,93 +0,0 @@ -/* These just make the access a little neater */ -static inline int objdb_get_string(OBJDB_API *corosync, unsigned int object_service_handle, - char *key, char **value) -{ - int res; - - *value = NULL; - if ( !(res = corosync->object_key_get(object_service_handle, - key, - strlen(key), - (void *)value, - NULL))) { - if (*value) - return 0; - } - return -1; -} - -static inline void objdb_get_int(OBJDB_API *corosync, unsigned int object_service_handle, - char *key, unsigned int *intvalue, unsigned int default_value) -{ - char *value = NULL; - - *intvalue = default_value; - - if (!corosync->object_key_get(object_service_handle, key, strlen(key), - (void *)&value, NULL)) { - if (value) { - *intvalue = atoi(value); - } - } -} - - -/* Helper functions for navigating the nodes list */ -static inline unsigned int nodeslist_init(OBJDB_API *corosync, - unsigned int cluster_parent_handle, - unsigned int *find_handle) -{ - unsigned int object_handle; - unsigned int find_handle1; - unsigned int find_handle2; - - corosync->object_find_create(cluster_parent_handle,"clusternodes", strlen("clusternodes"), &find_handle1); - if (corosync->object_find_next(find_handle1, &object_handle) == 0) - { - unsigned int nodes_handle; - corosync->object_find_destroy(find_handle1); - - corosync->object_find_create(object_handle,"clusternode", strlen("clusternode"), &find_handle2); - - if (corosync->object_find_next(find_handle2, &nodes_handle) == 0) - { - *find_handle = find_handle2; - return nodes_handle; - } - } - return 0; -} - -static inline unsigned int nodeslist_next(OBJDB_API *corosync, unsigned int find_handle) -{ - unsigned int nodes_handle; - - if (corosync->object_find_next(find_handle, &nodes_handle) == 0) - return nodes_handle; - else - return 0; -} - -static inline unsigned int nodelist_byname(OBJDB_API *corosync, - unsigned int cluster_parent_handle, - char *name) -{ - char *nodename; - unsigned int nodes_handle; - unsigned int find_handle = 0; - - nodes_handle = nodeslist_init(corosync, cluster_parent_handle, &find_handle); - while (nodes_handle) { - if (objdb_get_string(corosync, nodes_handle, "name", &nodename)) { - nodes_handle = nodeslist_next(corosync, find_handle); - continue; - } - if (strcmp(nodename, name) == 0) - return nodes_handle; - - nodes_handle = nodeslist_next(corosync, find_handle); - } - corosync->object_find_destroy(find_handle); - - return 0; -} diff --git a/cman/init.d/Makefile b/cman/init.d/Makefile deleted file mode 100644 index 8683c81..0000000 --- a/cman/init.d/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -TARGET1=cman -TARGET2=qdiskd - -INITDT=$(TARGET1) $(TARGET2) - -all: $(TARGET1) $(TARGET2) - -include ../../make/defines.mk -include $(OBJDIR)/make/clean.mk -include $(OBJDIR)/make/install.mk -include $(OBJDIR)/make/uninstall.mk - -$(TARGET1): $(S)/$(TARGET1).in - cat $(S)/$(TARGET1).in | sed \ - -e 's#@SBINDIR@#${sbindir}#g' \ - -e 's#@INITDDIR@#${initddir}#g' \ - > $(TARGET1) - -$(TARGET2): $(S)/$(TARGET2).in - cat $(S)/$(TARGET2).in | sed \ - -e 's#@SBINDIR@#${sbindir}#g' \ - -e 's#@INITDDIR@#${initddir}#g' \ - > $(TARGET2) - -clean: generalclean diff --git a/cman/init.d/cman.in b/cman/init.d/cman.in deleted file mode 100644 index 0b55e68..0000000 --- a/cman/init.d/cman.in +++ /dev/null @@ -1,764 +0,0 @@ -#!/bin/bash -# -# cman - Cluster Manager init script -# -# chkconfig: - 21 79 -# description: Starts and stops cman -# -# -### BEGIN INIT INFO -# Provides: cman -# Required-Start: $network $time -# Required-Stop: $network $time -# Default-Start: -# Default-Stop: -# Short-Description: Starts and stops cman -# Description: Starts and stops the Cluster Manager set of daemons -### END INIT INFO - -# rpm based distros -if [ -d /etc/sysconfig ]; then - [ -f @INITDDIR@/functions ] && . @INITDDIR@/functions - [ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster - [ -f /etc/sysconfig/cman ] && . /etc/sysconfig/cman - [ -z "$LOCK_FILE" ] && LOCK_FILE="/var/lock/subsys/cman" - chkconfig=/sbin/chkconfig - success=success - failure=failure - status=status -fi - -# deb based distros -if [ -d /etc/default ]; then - [ -f /etc/default/cluster ] && . /etc/default/cluster - [ -f /etc/default/cman ] && . /etc/default/cman - [ -z "$LOCK_FILE" ] && LOCK_FILE="/var/lock/cman" - # deb based distros can have chkconfig installed. Use it if installed - # otherwire use our local wrapper. - [ -n "$(which chkconfig)" ] && chkconfig="$(which chkconfig)" - [ -z "$chkconfig" ] && chkconfig=local_chkconfig - success=local_success - failure=local_failure - # functions in rpm based distro implements a very complete version - # of pidof. For now we can live with this. - status=local_status -fi - -[ -z "$CCSD_OPTS" ] && CCSD_OPTS= - -# 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 -[ -z "$CMAN_CLUSTER_TIMEOUT" ] && 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. -[ -z "$CMAN_QUORUM_TIMEOUT" ] && CMAN_QUORUM_TIMEOUT=0 - -# CMAN_SHUTDOWN_TIMEOUT -- amount of time to wait for cman to become a -# cluster member before calling cman_tool leave during shutdown. -# The default is 60 seconds -[ -z "$CMAN_SHUTDOWN_TIMEOUT" ] && CMAN_SHUTDOWN_TIMEOUT=60 - -# 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. -[ -z "$FENCED_START_TIMEOUT" ] && FENCED_START_TIMEOUT=300 - -# NET_RMEM_DEFAULT -- minimum value for rmem_default. If this is set -# higher elsewhere it will not be reduced here. -# These two values are only really needed for the DLM when using sctp -# but do no harm. -[ -z "$NET_RMEM_DEFAULT" ] && NET_RMEM_DEFAULT=4194304 - -# NET_RMEM_MAX -- minimum value for rmem_max. If this is set -# higher elsewhere it will not be reduced here. -[ -z "$NET_RMEM_MAX" ] && NET_RMEM_MAX=4194304 - -# FENCED_MEMBER_DELAY -- amount of time to delay fence_tool join to allow -# all nodes in cluster.conf to become cluster members. In seconds. -[ -z "$FENCED_MEMBER_DELAY" ] && FENCED_MEMBER_DELAY=45 - -# FENCE_JOIN -- boolean value used to control whether or not this node -# should join the fence domain. If FENCE_JOIN is set to "no", then -# the script will not attempt to the fence domain. If FENCE_JOIN is -# set to "yes", then the script will attempt to join the fence domain. -# If FENCE_JOIN is set to any other value, the default behavior is -# to join the fence domain (equivalent to "yes"). -[ -z "$FENCE_JOIN" ] && FENCE_JOIN="yes" - -# NETWORK_BRIDGE_SCRIPT -- script to use for xen network bridging. -# This script must exist in the /etc/xen/scripts directory. -# The default script is "network-bridge". -[ -z "$NETWORK_BRIDGE_SCRIPT" ] && NETWORK_BRIDGE_SCRIPT="network-bridge" - -[ -n "$CLUSTERNAME" ] && cman_join_opts="-c $CLUSTERNAME" - -[ -n "$NODENAME" ] && cman_join_opts+=" -n $NODENAME" - -# CONFIG_LOADER -- select default config parser. -# This can be: -# xmlconfig - read directly from cluster.conf and use ricci as default config -# propagation method. (default) -# ldapconfig - read configuration from an ldap server. -# Requires: LDAP_URL or/and LDAP_BASEDN envvar to be set. -# LDAP_BINDDN and LDAP_BINDPWD have to be either both set or both unset. -# corosync_parser - use internal corosync config file parser. -# openaisparser - use internal openais config file parser. -# ccsconfig - read configuration from ccsd daemon. This method is deprecated -# and available only if building the code with --enable_legacy_code. -[ -n "$CONFIG_LOADER" ] && cman_join_opts+=" -C $CONFIG_LOADER" - -local_chkconfig() -{ - ls /etc/rc${2}.d/S*${3} > /dev/null 2>/dev/null - return $? -} - -local_success() -{ - echo -ne "[ OK ]\r" -} - -local_failure() -{ - echo -ne "[FAILED]\r" -} - -local_status() -{ - pid=$(pidof $1 2>/dev/null) - rtrn=$? - if [ $rtrn -ne 0 ]; then - echo "$1 is stopped" - else - echo "$1 (pid $pid) is running..." - fi - return $rtrn -} - -load_modules() -{ - errmsg=$( /sbin/modprobe configfs 2>&1 ) || return 1 - errmsg=$( /sbin/modprobe dlm 2>&1 ) || return 1 - errmsg=$( /sbin/modprobe lock_dlm 2>&1 ) || return 1 - return 0 -} - -start_configfs() -{ - # configfs - awk '{ print $2 }' /etc/mtab | grep "/sys/kernel/config" > /dev/null 2>&1 \ - && awk '{ print $3 }' /etc/mtab | grep "configfs" > /dev/null 2>&1 - if [ $? -ne 0 ] - then - errmsg=$( /bin/mount -t configfs none /sys/kernel/config 2>&1 ) - return $? - fi - return 0 -} - -start_ccsd() -{ - # ccsd - $status ccsd > /dev/null - if [ $? -ne 0 ] - then - errmsg=$(@SBINDIR@/ccsd $CCSD_OPTS 2>&1) - rtrn=$? - return $rtrn - fi - return 0 -} - -start_cman() -{ - # cman - @SBINDIR@/cman_tool status > /dev/null 2>&1 - if [ $? -ne 0 ] - then - case "$CONFIG_LOADER" in - ldapconfig) - if [ -n "$LDAP_URL" ] || [ -n "$LDAP_BASEDN" ]; then - if [ -n "$LDAP_BINDDN" ]; then - if [ -z "$LDAP_BINDPWD" ]; then - errmsg="ldadconfig has been select but LDAP_BINDPWD is not set" - return 1 - fi - fi - if [ -n "$LDAP_BINDPWD" ]; then - if [ -z "$LDAP_BINDDN" ]; then - errmsg="ldadconfig has been select but LDAP_BINDDN is not set" - return 1 - fi - fi - else - errmsg="ldadconfig has been select but neither LDAP_URL or LDAP_BASEDN have been set" - return 1 - fi - ;; - ccsconfig) - if [ -x @SBINDIR@/ccsd ]; then - echo -n " Starting ccsd... " - start_ccsd - if [ $? -eq 0 ] - then - echo "done" - else - echo "failed" - errmsg="Unable to start ccsd" - return 1 - fi - else - errmsg="ccsconfig has been selected but ccsd does not appear to be installed or executable" - return 1 - fi - ;; - *) - # nothing to do for now - ;; - esac - errmsg=$( @SBINDIR@/cman_tool -t $CMAN_CLUSTER_TIMEOUT -w join \ - $cman_join_opts 2>&1 ) || return 1 - - if [ $CMAN_QUORUM_TIMEOUT -gt 0 ] - then - errmsg=$( @SBINDIR@/cman_tool -t $CMAN_QUORUM_TIMEOUT \ - -q wait 2>&1 ) || return 1 - fi - fi - return 0 -} - - -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 - # - $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 qdiskd... " - service qdiskd start > /dev/null 2>&1 - if [ $? -eq 0 ] - then - echo "done" - else - echo "failed" - return 1 - fi - return 0 -} - - -start_daemons() -{ - $status groupd > /dev/null 2>&1 - if [ $? -ne 0 ]; then - errmsg=$( @SBINDIR@/groupd 2>&1 ) || return 1 - fi - $status fenced > /dev/null 2>&1 - if [ $? -ne 0 ]; then - errmsg=$( @SBINDIR@/fenced 2>&1 ) || return 1 - fi - $status dlm_controld > /dev/null 2>&1 - if [ $? -ne 0 ]; then - errmsg=$( @SBINDIR@/dlm_controld 2>&1 ) || return 1 - fi - $status gfs_controld > /dev/null 2>&1 - if [ $? -ne 0 ]; then - errmsg=$( @SBINDIR@/gfs_controld 2>&1 ) || return 1 - fi - $status cmannotifyd > /dev/null 2>&1 - if [ $? -ne 0 ]; then - errmsg=$( @SBINDIR@/cmannotifyd 2>&1 ) || return 1 - fi - return 0 -} - -start_fence() -{ - @SBINDIR@/cman_tool status | grep Flags | grep 2node > /dev/null 2>&1 - if [ $? -ne 0 ] - then - errmsg=$( @SBINDIR@/fence_tool -w -t $FENCED_START_TIMEOUT join \ - > /dev/null 2>&1 ) || return 1 - else - errmsg=$( @SBINDIR@/fence_tool -w -t $FENCED_START_TIMEOUT \ - -m $FENCED_MEMBER_DELAY join \ - > /dev/null 2>&1 ) || return 1 - fi - return 0 -} - -start_fence_xvmd() -{ - $status fence_xvmd > /dev/null 2>&1 - if [ $? -ne 0 ]; then - errmsg=$( @SBINDIR@/fence_xvmd $FENCE_XVMD_OPTS 2>&1 ) || return 1 - fi - return 0 -} - -xend_bridged_net_enabled() { - # Not a xen kernel - test -d /proc/xen || return 1 - - current_runlevel=$(/sbin/runlevel 2>/dev/null | awk '{ print $2 }' 2>/dev/null) - if [ -z "$current_runlevel" ]; then - errmsg='Unable to determine the current runlevel' - return 1 - fi - - $chkconfig --levels "$current_runlevel" xend 2>/dev/null - if [ $? -ne 0 ]; then - # xend doesn't start at this runlevel. - return 1 - fi - - if [ ! -f /etc/xen/xend-config.sxp ]; then - # xend isn't configured to use bridged networking. - return 1 - fi - - egrep "^[[:blank:]]*\([[:blank:]]*network-script[[:blank:]]+(')?[[:blank:]]*${NETWORK_BRIDGE_SCRIPT}([[:blank:]]*\)|[[:blank:]]+)" /etc/xen/xend-config.sxp >&/dev/null - if [ $? -ne 0 ]; then - # xend isn't configured to use bridged networking. - return 1 - fi - return 0 -} - -xend_bridged_net_start() { - if [ ! -x /etc/xen/scripts/${NETWORK_BRIDGE_SCRIPT} ]; then - if [ -f /etc/xen/scripts/${NETWORK_BRIDGE_SCRIPT} ]; then - errmsg='The xend bridged network script cannot be run' - else - errmsg='The xend bridged network script is missing' - fi - return 1 - fi - - /sbin/modprobe netbk >& /dev/null - /sbin/modprobe netloop >& /dev/null - bridge_parms=`egrep -m 1 "^[[:blank:]]*\([[:blank:]]*network-script[[:blank:]]+(')?[[:blank:]]*${NETWORK_BRIDGE_SCRIPT}([[:blank:]]*\)|[[:blank:]]+)" /etc/xen/xend-config.sxp| sed -r "s/^[[:blank:]]*\([[:blank:]]*network-script[[:blank:]]+'?[[:blank:]]*${NETWORK_BRIDGE_SCRIPT}[[:blank:]]*//; s/'?[[:blank:]]*\).*//"` - errmsg=$(/etc/xen/scripts/${NETWORK_BRIDGE_SCRIPT} start $bridge_parms 2>&1) || return 1 - return 0 -} - -fence_xvmd_enabled() -{ - # - # Check the value of FENCE_JOIN. - # If FENCE_JOIN is set to "no", then we should disable fence_xvm. - # - if [ "$FENCE_JOIN" = "no" ]; then - return 1 - fi - - # - # Check for the 'xm' binary. If it's not here, we are not - # running on a machine capable of running xvmd. - # - which xm > /dev/null 2>&1 || return 1 - - # - # Check for presence of /cluster/fence_xvmd in cluster.conf - # (If -X is specified, it doesn't matter if it's in cluster.conf; - # we'll start it anyway since ccsd is not required) - # - @SBINDIR@/cman_tool status > /dev/null 2>&1 - if [ $? -eq 0 ] - then - if [ "$FENCE_XVMD_OPTS" = "${FENCE_XVMD_OPTS/-X/}" ]; then - @SBINDIR@/ccs_tool query /cluster/fence_xvmd || return 1 - fi - fi - - return 0 -} - -set_networking_params() -{ - if [ ! -f /proc/sys/net/core/rmem_default ] - then - return 0; - fi - - value="$(cat /proc/sys/net/core/rmem_default)" - if [ $value -le $NET_RMEM_DEFAULT ] - then - echo $NET_RMEM_DEFAULT > /proc/sys/net/core/rmem_default - fi - - value="$(cat /proc/sys/net/core/rmem_max)" - if [ $value -le $NET_RMEM_MAX ] - then - echo $NET_RMEM_MAX > /proc/sys/net/core/rmem_max - fi -} - -fence_join_enabled() -{ - # - # Check the value of FENCE_JOIN. - # If FENCE_JOIN is set to "no", we will not attempt to join - # the fence domain. If FENCE_JOIN is set to any other value, - # we will attempt to join the fence domain (default). - # - if [ "$FENCE_JOIN" = "no" ]; then - return 1 - else - return 0 - fi -} - -start() -{ - echo "Starting cluster: " - - xend_bridged_net_enabled - if [ $? -eq 0 ] - then - echo -n " Enabling workaround for Xend bridged networking... " - xend_bridged_net_start - if [ $? -eq 0 ] - then - echo "done" - else - echo "failed: $errmsg" - return 1 - fi - fi - - echo -n " Loading modules... " - ulimit -c unlimited - load_modules - if [ $? -eq 0 ] - then - echo "done" - else - echo "failed" - return 1 - fi - - echo -n " Mounting configfs... " - start_configfs - if [ $? -eq 0 ] - then - echo "done" - else - echo "failed" - return 1 - fi - - echo -n " Setting network parameters... " - set_networking_params - if [ $? -eq 0 ] - then - echo "done" - else - echo "failed" - return 1 - fi - - echo -n " Starting cman... " - start_cman - if [ $? -eq 0 ] - then - echo "done" - else - echo "failed" - return 1 - fi - - start_qdiskd - - echo -n " Starting daemons... " - start_daemons - if [ $? -eq 0 ] - then - echo "done" - else - echo "failed" - return 1 - fi - - if fence_join_enabled; then - echo -n " Starting fencing... " - start_fence - if [ $? -eq 0 ] - then - echo "done" - else - echo "failed" - return 1 - fi - fi - - if fence_xvmd_enabled; then - echo -n " Starting virtual machine fencing host... " - start_fence_xvmd - if [ $? -eq 0 ] - then - echo "done" - else - echo "failed" - return 1 - fi - fi - - return 0 -} - -stop_configfs() -{ - awk '{ print $2 }' /etc/mtab | grep "/sys/kernel/config" > /dev/null 2>&1 \ - && awk '{ print $3 }' /etc/mtab | grep "configfs" > /dev/null 2>&1 - if [ $? -eq 0 ] && [ -z "$(ls -1 /sys/kernel/config)" ] - then - errmsg=$( /bin/umount /sys/kernel/config 2>&1 ) - if [ $? -ne 0 ] - then - echo -n $errmsg " " - fi - fi - return 0 -} - -stop_ccsd() -{ - for sec in $(seq 1 10) - do - if pidof ccsd > /dev/null 2>&1 - 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 > /dev/null 2>&1 || break - - sleep 1 - else - return 0 - fi - done - return 1 -} - -stop_cman() -{ - @SBINDIR@/cman_tool status > /dev/null 2>&1 - if [ $? -eq 0 ] - then - errmsg=$( @SBINDIR@/cman_tool -t $CMAN_SHUTDOWN_TIMEOUT \ - -w leave $1 2>&1 ) || return 1 - fi - return 0 # all ok -} - -stop_daemons() -{ - if pid=$(pidof cmannotifyd 2>&1); then - errmsg=$(kill $pid 2>&1) || return 1 - fi - if pid=$(pidof gfs_controld 2>&1); then - errmsg=$(kill $pid 2>&1) || return 1 - fi - if pid=$(pidof dlm_controld 2>&1); then - errmsg=$(kill $pid 2>&1) || return 1 - fi - if pid=$(pidof fenced 2>&1); then - errmsg=$(kill $pid 2>&1) || return 1 - fi - if pid=$(pidof groupd 2>&1); then - errmsg=$(kill $pid 2>&1) || return 1 - fi - return 0 # all ok -} - -stop_fence() -{ - if pidof fenced > /dev/null 2>&1 - then - @SBINDIR@/fence_tool -w leave > /dev/null 2>&1 - rtrn=$? - sleep 1 # A bit of time for fenced to exit - return $rtrn - fi - return 0 # all ok -} - -stop_fence_xvmd() -{ - if pidof fence_xvmd > /dev/null 2>&1 - then - pkill -TERM fence_xvmd - sleep 1 # A bit of time for fenced to exit - fi - - [ -z "$(pidof fence_xvmd)" ] - return $? -} - -stop() -{ - echo "Stopping cluster: " - - if fence_xvmd_enabled; then - echo -n " Stopping virtual machine fencing host... " - stop_fence_xvmd - if [ $? -eq 0 ] - then - echo "done" - else - echo "failed" - return 1 - fi - fi - - if fence_join_enabled; then - echo -n " Stopping fencing... " - stop_fence - if [ $? -eq 0 ] - then - echo "done" - else - echo "failed" - return 1 - fi - fi - - echo -n " Stopping cman... " - if [ $1 ]; then - stop_cman $1 - else - stop_cman - fi - if [ $? -eq 0 ] - then - echo "done" - else - echo "failed" - return 1 - fi - -# stop_daemons -# [ $? -ne 0 ] && return 1 - - echo -n " Stopping ccsd... " - stop_ccsd - if [ $? -eq 0 ] - then - echo "done" - else - echo "failed" - return 1 - fi - - echo -n " Unmounting configfs... " - stop_configfs - if [ $? -eq 0 ] - then - echo "done" - else - echo "failed" - return 1 - fi - - return 0 -} - -cmanstatus() -{ - if [ -n "$CONFIG_LOADER" ] && [ "$CONFIG_LOADER" = ccsconfig ]; then - errmsg=$( $status ccsd 2>&1) || return 1 - fi - - errmsg=$( $status groupd 2>&1) || return 1 - errmsg=$( $status fenced 2>&1) || return 1 - errmsg=$( $status dlm_controld 2>&1) || return 1 - errmsg=$( $status gfs_controld 2>&1) || return 1 - errmsg=$( $status cmannotifyd 2>&1) || return 1 - - fence_xvmd_enabled || return 0 - errmsg=$( $status fence_xvmd 2>&1) || return 1 - - return 0 -} - -rtrn=1 - -# See how we were called. -case "$1" in - start) - start - rtrn=$? - [ $rtrn = 0 ] && touch $LOCK_FILE - if [ $rtrn -ne 0 ] - then - echo $errmsg - $failure "failed to start cman" - echo - else - $success "start" - echo - fi - ;; - stop) - if [ $2 ]; then - stop - else - stop remove - fi - rtrn=$? - [ $rtrn = 0 ] && rm -f $LOCK_FILE - if [ $rtrn -ne 0 ] - then - echo $errmsg - $failure "failed to stop cman" - echo - else - $success "shutdown" - echo - fi - ;; - - restart|reload) - $0 stop restart - $0 start - rtrn=$? - ;; - - status) - cmanstatus - rtrn=$? - if [ $rtrn -ne 0 ] ; then - echo $errmsg - else - echo "cman is running." - fi - ;; - - *) - echo $"Usage: $0 {start|stop|reload|restart|status}" - ;; -esac - -exit $rtrn diff --git a/cman/init.d/qdiskd.in b/cman/init.d/qdiskd.in deleted file mode 100644 index 3efdfe4..0000000 --- a/cman/init.d/qdiskd.in +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/bash -# -# qdiskd quorum disk daemon -# -# chkconfig: - 22 78 -# description: Starts and stops the quorum disk daemon - -### BEGIN INIT INFO -# Provides: qdiskd -# Required-Start: cman -# Required-Stop: cman -# Default-Start: -# Default-Stop: -# Short-Description: start/stop quorum disk daemon -# Description: start/stop quorum disk daemon -### END INIT INFO - -# rpm based distros -if [ -d /etc/sysconfig ]; then - [ -f @INITDDIR@/functions ] && . @INITDDIR@/functions - [ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster - [ -f /etc/sysconfig/qdiskd ] && . /etc/sysconfig/qdiskd - [ -z "$LOCK_FILE" ] && LOCK_FILE="/var/lock/subsys/qdiskd" - success=success - failure=failure - status=status -fi - -# deb based distros -if [ -d /etc/default ]; then - [ -f /etc/default/cluster ] && . /etc/default/cluster - [ -f /etc/default/qdiskd ] && . /etc/default/qdiskd - [ -z "$LOCK_FILE" ] && LOCK_FILE="/var/lock/qdiskd" - success=local_success - failure=local_failure - # functions in rpm based distro implements a very complete version - # of pidof. For now we can live with this. - status=local_status -fi - -local_success() -{ - echo -ne "[ OK ]\r" -} - -local_failure() -{ - echo -ne "[FAILED]\r" -} - -local_status() -{ - pid=$(pidof $1 2>/dev/null) - rtrn=$? - if [ $rtrn -ne 0 ]; then - echo "$1 is stopped" - else - echo "$1 (pid $pid) is running..." - fi - return $rtrn -} - -rtrn=1 -retries=0 - -# See how we were called. -case "$1" in - start) - echo -n "Starting the Quorum Disk Daemon: " - - $0 status >/dev/null - if [ $? -eq 0 ]; then - $success - echo - exit 0 - fi - - @SBINDIR@/qdiskd -Q - rtrn=$? - if [ $rtrn = 0 ]; then - touch $LOCK_FILE - $success - echo - else - $failure - echo - fi - - ;; - - stop) - echo -n "Stopping the Quorum Disk Daemon: " - pid="$(pidof qdiskd)" - while [ -n "$pid" ] && [ $retries -lt 5 ]; do - kill $pid 2>&1 - pid="$(pidof qdiskd)" - sleep 1 - ((retries++)) - done - if [ -z "$(pidof qdiskd)" ]; then - $success - echo - rtrn=0 - rm -f $LOCK_FILE - else - $failure - echo - rtrn=1 - fi - ;; - - restart|reload) - $0 stop || exit $? - $0 start - rtrn=$? - ;; - - status) - $status qdiskd - rtrn=$? - ;; - - *) - echo $"Usage: $0 {start|stop|reload|restart|status}" - ;; -esac - -exit $rtrn diff --git a/cman/lib/Makefile b/cman/lib/Makefile deleted file mode 100644 index da32992..0000000 --- a/cman/lib/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -TARGET= libcman - -include ../../make/defines.mk -include $(OBJDIR)/make/libs.mk -include $(OBJDIR)/make/cobj.mk -include $(OBJDIR)/make/clean.mk -include $(OBJDIR)/make/install.mk -include $(OBJDIR)/make/uninstall.mk - -CFLAGS += -fPIC -CFLAGS += -I${cmanincdir} -I$(S)/../daemon -CFLAGS += -I${incdir} diff --git a/cman/lib/libcman.c b/cman/lib/libcman.c deleted file mode 100644 index 9855c17..0000000 --- a/cman/lib/libcman.c +++ /dev/null @@ -1,1105 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "cnxman-socket.h" -#include "libcman.h" - -/* List of saved messages */ -struct saved_message -{ - struct sock_header *msg; - struct saved_message *next; -}; - -struct cman_handle -{ - int magic; - int fd; - int zero_fd; - void *privdata; - int want_reply; - cman_callback_t event_callback; - cman_datacallback_t data_callback; - cman_confchgcallback_t confchg_callback; - - void *reply_buffer; - int reply_buflen; - int reply_status; - - struct saved_message *saved_data_msg; - struct saved_message *saved_event_msg; - struct saved_message *saved_reply_msg; -}; - -#define VALIDATE_HANDLE(h) do {if (!(h) || (h)->magic != CMAN_MAGIC) {errno = EINVAL; return -1;}} while (0) - -/* - * Wait for an command/request reply. - * Data/event messages will be queued. - * - */ -static int wait_for_reply(struct cman_handle *h, void *msg, int max_len) -{ - int ret; - - h->want_reply = 1; - h->reply_buffer = msg; - h->reply_buflen = max_len; - - do - { - ret = cman_dispatch(h, CMAN_DISPATCH_BLOCKING | CMAN_DISPATCH_IGNORE_EVENT | CMAN_DISPATCH_IGNORE_DATA); - - } while (h->want_reply == 1 && ret >= 0); - - h->reply_buffer = NULL; - h->reply_buflen = 0; - - /* Error in local comms */ - if (ret < 0) { - return -1; - } - /* cnxman daemon returns -ve errno values on error */ - if (h->reply_status < 0) { - errno = -h->reply_status; - return -1; - } - else { - return h->reply_status; - } -} - - -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; - unode->cn_jointime = knode->jointime; - - memset(&unode->cn_address, 0, sizeof(unode->cn_address)); - memcpy(&unode->cn_address.cna_address, knode->addr, knode->addrlen); - unode->cn_address.cna_addrlen = knode->addrlen; -} - -/* Add to a list. saved_message *m is the head of the list in the cman_handle */ -static void add_to_waitlist(struct saved_message **m, struct sock_header *msg) -{ - struct saved_message *next = *m; - struct saved_message *last = *m; - struct saved_message *this; - - this = malloc(sizeof(struct saved_message)); - if (!this) - return; - - this->msg = malloc(msg->length); - if (!this->msg) - { - free(this); - return; - } - - memcpy(this->msg, msg, msg->length); - this->next = NULL; - - if (!next) - { - *m = this; - return; - } - - for (; next; next = next->next) - { - last = next; - } - last->next = this; -} - -static int process_cman_message(struct cman_handle *h, int flags, struct sock_header *msg) -{ - /* Data for us */ - if ((msg->command & CMAN_CMDMASK_CMD) == CMAN_CMD_DATA) - { - struct sock_data_header *dmsg = (struct sock_data_header *)msg; - char *buf = (char *)msg; - - if (flags & CMAN_DISPATCH_IGNORE_DATA) - { - add_to_waitlist(&h->saved_data_msg, msg); - } - else - { - if (h->data_callback) - h->data_callback(h, h->privdata, - buf+sizeof(*dmsg), msg->length-sizeof(*dmsg), - dmsg->port, dmsg->nodeid); - } - return 0; - } - - /* Got a reply to a previous information request */ - if ((msg->command & CMAN_CMDFLAG_REPLY) && h->want_reply) - { - char *replybuf = (char *)msg; - int replylen = msg->length - sizeof(struct sock_reply_header); - struct sock_reply_header *reply = (struct sock_reply_header *)msg; - - if (flags & CMAN_DISPATCH_IGNORE_REPLY) - { - add_to_waitlist(&h->saved_reply_msg, msg); - return 0; - } - - replybuf += sizeof(struct sock_reply_header); - if (replylen <= h->reply_buflen) - { - memcpy(h->reply_buffer, replybuf, replylen); - } - h->want_reply = 0; - h->reply_status = reply->status; - - return 1; - } - - /* OOB event */ - if (msg->command == CMAN_CMD_EVENT || msg->command == CMAN_CMD_CONFCHG) - { - if (flags & CMAN_DISPATCH_IGNORE_EVENT) - { - add_to_waitlist(&h->saved_event_msg, msg); - } - else - { - if (msg->command == CMAN_CMD_EVENT && h->event_callback) { - struct sock_event_message *emsg = (struct sock_event_message *)msg; - h->event_callback(h, h->privdata, emsg->reason, emsg->arg); - } - - if (msg->command == CMAN_CMD_CONFCHG && h->confchg_callback) - { - struct sock_confchg_message *cmsg = (struct sock_confchg_message *)msg; - - h->confchg_callback(h, h->privdata, - cmsg->entries,cmsg->member_entries, - &cmsg->entries[cmsg->member_entries], cmsg->left_entries, - &cmsg->entries[cmsg->member_entries+cmsg->left_entries], cmsg->joined_entries); - } - } - } - - return 0; -} - -static int loopy_writev(int fd, struct iovec *iovptr, size_t iovlen) -{ - size_t byte_cnt=0; - int len; - - while (iovlen > 0) - { - len = writev(fd, iovptr, iovlen); - if (len <= 0) - return len; - - byte_cnt += len; - while (len >= iovptr->iov_len) - { - len -= iovptr->iov_len; - iovptr++; - iovlen--; - } - - if ((ssize_t)iovlen <=0 ) - break; - - iovptr->iov_base += len; - iovptr->iov_len -= len; - } - return byte_cnt; -} - - -static int send_message(struct cman_handle *h, int msgtype, const void *inbuf, int inlen) -{ - struct sock_header header; - size_t len; - struct iovec iov[2]; - size_t iovlen = 1; - - header.magic = CMAN_MAGIC; - header.version = CMAN_VERSION; - header.command = msgtype; - header.flags = 0; - header.length = sizeof(header) + inlen; - - iov[0].iov_len = sizeof(header); - iov[0].iov_base = &header; - if (inbuf) - { - iov[1].iov_len = inlen; - iov[1].iov_base = (void *) inbuf; - iovlen++; - } - - len = loopy_writev(h->fd, iov, iovlen); - if (len < 0) - return len; - return 0; -} - -/* Does something similar to the ioctl calls */ -static int info_call(struct cman_handle *h, int msgtype, const void *inbuf, int inlen, void *outbuf, int outlen) -{ - if (send_message(h, msgtype, inbuf, inlen)) - return -1; - - return wait_for_reply(h, outbuf, outlen); -} - -static cman_handle_t open_socket(const char *name, int namelen, void *privdata) -{ - struct cman_handle *h; - struct sockaddr_un sockaddr; - - h = malloc(sizeof(struct cman_handle)); - if (!h) - return NULL; - - h->magic = CMAN_MAGIC; - h->privdata = privdata; - h->event_callback = NULL; - h->data_callback = NULL; - h->confchg_callback = NULL; - h->want_reply = 0; - h->saved_data_msg = NULL; - h->saved_event_msg = NULL; - h->saved_reply_msg = NULL; - - h->fd = socket(PF_UNIX, SOCK_STREAM, 0); - if (h->fd == -1) - { - int saved_errno = errno; - free(h); - errno = saved_errno; - return NULL; - } - - fcntl(h->fd, F_SETFD, 1); /* Set close-on-exec */ - memset(&sockaddr, 0, sizeof(sockaddr)); - memcpy(sockaddr.sun_path, name, namelen); - sockaddr.sun_family = AF_UNIX; - - if (connect(h->fd, (struct sockaddr *) &sockaddr, sizeof(sockaddr)) < 0) - { - int saved_errno = errno; - close(h->fd); - free(h); - errno = saved_errno; - return NULL; - } - - /* Get a handle on /dev/zero too. This is always active so we - can return it from cman_get_fd() if we have cached messages */ - h->zero_fd = open("/dev/zero", O_RDONLY); - if (h->zero_fd < 0) - { - int saved_errno = errno; - close(h->fd); - free(h); - h = NULL; - errno = saved_errno; - } - - return (cman_handle_t)h; -} - -cman_handle_t cman_admin_init(void *privdata) -{ - return open_socket(ADMIN_SOCKNAME, sizeof(ADMIN_SOCKNAME), privdata); -} - -cman_handle_t cman_init(void *privdata) -{ - return open_socket(CLIENT_SOCKNAME, sizeof(CLIENT_SOCKNAME), privdata); -} - -int cman_finish(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - h->magic = 0; - close(h->fd); - close(h->zero_fd); - free(h); - - return 0; -} - -int cman_setprivdata(cman_handle_t *handle, void *privdata) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - h->privdata = privdata; - return 0; -} - -int cman_getprivdata(cman_handle_t *handle, void **privdata) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - *privdata = h->privdata; - - return 0; -} - - -int cman_start_notification(cman_handle_t handle, cman_callback_t callback) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - if (!callback) - { - errno = EINVAL; - return -1; - } - if (info_call(h, CMAN_CMD_NOTIFY, NULL, 0, NULL, 0)) - return -1; - h->event_callback = callback; - - return 0; -} - -int cman_stop_notification(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - if (info_call(h, CMAN_CMD_REMOVENOTIFY, NULL, 0, NULL, 0)) - return -1; - h->event_callback = NULL; - - return 0; -} - -int cman_start_confchg(cman_handle_t handle, cman_confchgcallback_t callback) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - if (!callback) - { - errno = EINVAL; - return -1; - } - if (info_call(h, CMAN_CMD_START_CONFCHG, NULL, 0, NULL, 0)) - return -1; - h->confchg_callback = callback; - - return 0; -} - -int cman_stop_confchg(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - if (info_call(h, CMAN_CMD_STOP_CONFCHG, NULL, 0, NULL, 0)) - return -1; - h->confchg_callback = NULL; - - return 0; -} - - -int cman_get_fd(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - /* If we have saved messages then return an FD to /dev/zero which - will always be readable */ - if (h->saved_data_msg || h->saved_event_msg || h->saved_reply_msg) - return h->zero_fd; - else - return h->fd; -} - -int cman_dispatch(cman_handle_t handle, int flags) -{ - struct cman_handle *h = (struct cman_handle *)handle; - int len; - int offset; - int recv_flags = 0; - char buf[PIPE_BUF]; - VALIDATE_HANDLE(h); - - if (!(flags & CMAN_DISPATCH_BLOCKING)) - recv_flags |= MSG_DONTWAIT; - - do - { - int res; - char *bufptr = buf; - struct sock_header *header = (struct sock_header *)buf; - - /* First, drain any waiting queues */ - if (h->saved_reply_msg && !(flags & CMAN_DISPATCH_IGNORE_REPLY)) - { - struct saved_message *smsg = h->saved_reply_msg; - - res = process_cman_message(h, flags, smsg->msg); - h->saved_reply_msg = smsg->next; - len = smsg->msg->length; - free(smsg); - if (res || (flags & CMAN_DISPATCH_ONE)) - break; - else - continue; - } - if (h->saved_data_msg && !(flags & CMAN_DISPATCH_IGNORE_DATA)) - { - struct saved_message *smsg = h->saved_data_msg; - - res = process_cman_message(h, flags, smsg->msg); - h->saved_data_msg = smsg->next; - len = smsg->msg->length; - free(smsg); - if (res || (flags & CMAN_DISPATCH_ONE)) - break; - else - continue; - } - if (h->saved_event_msg && !(flags & CMAN_DISPATCH_IGNORE_EVENT)) - { - struct saved_message *smsg = h->saved_event_msg; - - res = process_cman_message(h, flags, smsg->msg); - h->saved_event_msg = smsg->next; - len = smsg->msg->length; - free(smsg); - if (res || (flags & CMAN_DISPATCH_ONE)) - break; - else - continue; - } - - /* Now look for new messages */ - len = recv(h->fd, buf, sizeof(struct sock_header), recv_flags); - - if (len == 0) { - errno = EHOSTDOWN; - return -1; - } - - if (len < 0 && - (errno == EINTR || errno == EAGAIN)) - return 0; - - if (len < 0) - return -1; - - offset = len; - - /* It's too big! */ - if (header->length > sizeof(buf)) - { - bufptr = malloc(header->length); - if (!bufptr) - return -1; - memcpy(bufptr, buf, sizeof(*header)); - header = (struct sock_header *)bufptr; - } - - /* Read the rest */ - while (offset < header->length) - { - len = read(h->fd, bufptr+offset, header->length-offset); - if (len == 0) { - errno = EHOSTDOWN; - return -1; - } - - if (len < 0 && - (errno == EINTR || errno == EAGAIN)) - return 0; - - if (len < 0) - return -1; - offset += len; - } - - res = process_cman_message(h, flags, header); - if (bufptr != buf) - free(bufptr); - - if (res) - break; - - } while ( flags & CMAN_DISPATCH_ALL && - !(len < 0 && errno == EAGAIN) ); - - return len; -} - -/* GET_ALLMEMBERS returns the number of nodes as status */ -int cman_get_node_count(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - return info_call(h, CMAN_CMD_GETALLMEMBERS, NULL, 0, NULL, 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; - int status; - int buflen; - int count = 0; - VALIDATE_HANDLE(h); - - if (!retnodes || !nodes || maxnodes < 1) - { - errno = EINVAL; - return -1; - } - - buflen = sizeof(struct cl_cluster_node) * maxnodes; - cman_nodes = malloc(buflen); - if (!cman_nodes) - return -1; - - status = info_call(h, CMAN_CMD_GETALLMEMBERS, NULL, 0, cman_nodes, buflen); - 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; - } - - if (status > maxnodes) - status = maxnodes; - - for (count = 0; count < status; count++) - { - copy_node(&nodes[count], &cman_nodes[count]); - } - free(cman_nodes); - *retnodes = status; - return 0; -} - -int cman_get_disallowed_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; - int status; - int buflen; - int count = 0; - int out_count = 0; - VALIDATE_HANDLE(h); - - if (!retnodes || !nodes || maxnodes < 1) - { - errno = EINVAL; - return -1; - } - - buflen = sizeof(struct cl_cluster_node) * maxnodes; - cman_nodes = malloc(buflen); - if (!cman_nodes) - return -1; - - status = info_call(h, CMAN_CMD_GETALLMEMBERS, NULL, 0, cman_nodes, buflen); - 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++) - { - if (cman_nodes[count].state == NODESTATE_AISONLY && out_count < maxnodes) - copy_node(&nodes[out_count++], &cman_nodes[count]); - } - free(cman_nodes); - *retnodes = out_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; - VALIDATE_HANDLE(h); - - if (!node || strlen(node->cn_name) > sizeof(cman_node.name)) - { - errno = EINVAL; - return -1; - } - - cman_node.node_id = nodeid; - strcpy(cman_node.name, node->cn_name); - status = info_call(h, CMAN_CMD_GETNODE, &cman_node, sizeof(struct cl_cluster_node), - &cman_node, sizeof(struct cl_cluster_node)); - if (status < 0) - return -1; - - copy_node(node, &cman_node); - - return 0; -} - -int cman_get_subsys_count(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - return info_call(h, CMAN_CMD_GET_JOINCOUNT, NULL,0, NULL, 0); -} - -int cman_is_active(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - return info_call(h, CMAN_CMD_ISACTIVE, NULL, 0, NULL, 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; - VALIDATE_HANDLE(h); - - req.port = port; - req.nodeid = nodeid; - return info_call(h, CMAN_CMD_ISLISTENING, &req, sizeof(struct cl_listen_request), NULL, 0); -} - -int cman_is_quorate(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - return info_call(h, CMAN_CMD_ISQUORATE, NULL, 0, NULL, 0); -} - - -int cman_get_version(cman_handle_t handle, cman_version_t *version) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - if (!version) - { - errno = EINVAL; - return -1; - } - return info_call(h, CMAN_CMD_GET_VERSION, NULL, 0, version, sizeof(cman_version_t)); -} - -int cman_set_version(cman_handle_t handle, const cman_version_t *version) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - if (!version) - { - errno = EINVAL; - return -1; - } - return info_call(h, CMAN_CMD_SET_VERSION, version, sizeof(cman_version_t), NULL, 0); -} - -int cman_kill_node(cman_handle_t handle, int nodeid) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - if (!nodeid) - { - errno = EINVAL; - return -1; - } - return info_call(h, CMAN_CMD_KILLNODE, &nodeid, sizeof(nodeid), NULL, 0); -} - -int cman_set_votes(cman_handle_t handle, int votes, int nodeid) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct cl_set_votes newv; - VALIDATE_HANDLE(h); - - if (!votes) - { - errno = EINVAL; - return -1; - } - newv.nodeid = nodeid; - newv.newvotes = votes; - return info_call(h, CMAN_CMD_SET_VOTES, &newv, sizeof(newv), NULL, 0); -} - -int cman_set_expected_votes(cman_handle_t handle, int evotes) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - if (!evotes) - { - errno = EINVAL; - return -1; - } - return info_call(h, CMAN_CMD_SETEXPECTED_VOTES, &evotes, sizeof(evotes), NULL, 0); -} - -int cman_leave_cluster(cman_handle_t handle, int reason) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - return info_call(h, CMAN_CMD_LEAVE_CLUSTER, &reason, sizeof(reason), NULL, 0); -} - -int cman_get_cluster(cman_handle_t handle, cman_cluster_t *clinfo) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - if (!clinfo) - { - errno = EINVAL; - return -1; - } - return info_call(h, CMAN_CMD_GETCLUSTER, NULL, 0, clinfo, sizeof(cman_cluster_t)); -} - -int cman_get_extra_info(cman_handle_t handle, cman_extra_info_t *info, int maxlen) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - if (!info || maxlen < sizeof(cman_extra_info_t)) - { - errno = EINVAL; - return -1; - } - return info_call(h, CMAN_CMD_GETEXTRAINFO, NULL, 0, info, maxlen); -} - -int cman_send_data(cman_handle_t handle, const void *buf, int len, int flags, uint8_t port, int nodeid) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct iovec iov[2]; - struct sock_data_header header; - VALIDATE_HANDLE(h); - - header.header.magic = CMAN_MAGIC; - header.header.version = CMAN_VERSION; - header.header.command = CMAN_CMD_DATA; - header.header.flags = flags; - header.header.length = len + sizeof(header); - header.nodeid = nodeid; - header.port = port; - - iov[0].iov_len = sizeof(header); - iov[0].iov_base = &header; - iov[1].iov_len = len; - iov[1].iov_base = (void *) buf; - - return loopy_writev(h->fd, iov, 2); -} - - -int cman_start_recv_data(cman_handle_t handle, cman_datacallback_t callback, uint8_t port) -{ - struct cman_handle *h = (struct cman_handle *)handle; - int portparam; - int status; - VALIDATE_HANDLE(h); - -/* Do a "bind" */ - portparam = port; - status = info_call(h, CMAN_CMD_BIND, &portparam, sizeof(portparam), NULL, 0); - - if (status == 0) - h->data_callback = callback; - - return status; -} - -int cman_end_recv_data(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - h->data_callback = NULL; - return 0; -} - - -int cman_barrier_register(cman_handle_t handle, const char *name, int flags, int nodes) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct cl_barrier_info binfo; - VALIDATE_HANDLE(h); - - if (strlen(name) > MAX_BARRIER_NAME_LEN) - { - errno = EINVAL; - return -1; - } - - binfo.cmd = BARRIER_CMD_REGISTER; - strcpy(binfo.name, name); - binfo.arg = nodes; - binfo.flags = flags; - - return info_call(h, CMAN_CMD_BARRIER, &binfo, sizeof(binfo), NULL, 0); -} - - -int cman_barrier_change(cman_handle_t handle, const char *name, int flags, int arg) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct cl_barrier_info binfo; - VALIDATE_HANDLE(h); - - if (strlen(name) > MAX_BARRIER_NAME_LEN) - { - errno = EINVAL; - return -1; - } - - binfo.cmd = BARRIER_CMD_CHANGE; - strcpy(binfo.name, name); - binfo.arg = arg; - binfo.flags = flags; - - return info_call(h, CMAN_CMD_BARRIER, &binfo, sizeof(binfo), NULL, 0); - -} - -int cman_barrier_wait(cman_handle_t handle, const char *name) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct cl_barrier_info binfo; - VALIDATE_HANDLE(h); - - if (strlen(name) > MAX_BARRIER_NAME_LEN) - { - errno = EINVAL; - return -1; - } - - binfo.cmd = BARRIER_CMD_WAIT; - strcpy(binfo.name, name); - - return info_call(h, CMAN_CMD_BARRIER, &binfo, sizeof(binfo), NULL, 0); -} - -int cman_barrier_delete(cman_handle_t handle, const char *name) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct cl_barrier_info binfo; - VALIDATE_HANDLE(h); - - if (strlen(name) > MAX_BARRIER_NAME_LEN) - { - errno = EINVAL; - return -1; - } - - binfo.cmd = BARRIER_CMD_DELETE; - strcpy(binfo.name, name); - - return info_call(h, CMAN_CMD_BARRIER, &binfo, sizeof(binfo), NULL, 0); -} - -int cman_shutdown(cman_handle_t handle, int flags) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - return info_call(h, CMAN_CMD_TRY_SHUTDOWN, &flags, sizeof(int), NULL, 0); -} - -int cman_set_dirty(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - return info_call(h, CMAN_CMD_SET_DIRTY, NULL, 0, NULL, 0); -} - -int cman_set_debuglog(cman_handle_t handle, int subsystems) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - return info_call(h, CMAN_CMD_SET_DEBUGLOG, &subsystems, sizeof(int), NULL, 0); -} - -int cman_replyto_shutdown(cman_handle_t handle, int yesno) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - send_message(h, CMAN_CMD_SHUTDOWN_REPLY, &yesno, sizeof(int)); - return 0; -} - - -int cman_register_quorum_device(cman_handle_t handle, char *name, int votes) -{ - struct cman_handle *h = (struct cman_handle *)handle; - char buf[strlen(name)+1 + sizeof(int)]; - VALIDATE_HANDLE(h); - - if (strlen(name) > MAX_CLUSTER_MEMBER_NAME_LEN) - { - errno = EINVAL; - return -1; - } - - memcpy(buf, &votes, sizeof(int)); - strcpy(buf+sizeof(int), name); - return info_call(h, CMAN_CMD_REG_QUORUMDEV, buf, strlen(name)+1+sizeof(int), NULL, 0); -} - -int cman_unregister_quorum_device(cman_handle_t handle) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - return info_call(h, CMAN_CMD_UNREG_QUORUMDEV, NULL, 0, NULL, 0); -} - -int cman_poll_quorum_device(cman_handle_t handle, int isavailable) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - return info_call(h, CMAN_CMD_POLL_QUORUMDEV, &isavailable, sizeof(int), NULL, 0); -} - -int cman_get_quorum_device(cman_handle_t handle, struct cman_qdev_info *info) -{ - struct cman_handle *h = (struct cman_handle *)handle; - int ret; - struct cl_cluster_node cman_node; - VALIDATE_HANDLE(h); - - cman_node.node_id = CLUSTER_GETNODE_QUORUMDEV; - ret = info_call(h, CMAN_CMD_GETNODE, &cman_node, sizeof(cman_node), &cman_node, sizeof(cman_node)); - if (!ret) { - strcpy(info->qi_name, cman_node.name); - info->qi_state = cman_node.state; - info->qi_votes = cman_node.votes; - } - return ret; -} - -int cman_get_fenceinfo(cman_handle_t handle, int nodeid, uint64_t *time, int *fenced, char *agent) -{ - struct cman_handle *h = (struct cman_handle *)handle; - int ret; - struct cl_fence_info f; - VALIDATE_HANDLE(h); - - ret = info_call(h, CMAN_CMD_GET_FENCE_INFO, &nodeid, sizeof(int), &f, sizeof(f)); - if (!ret) { - *time = f.fence_time; - if (agent) - strcpy(agent, f.fence_agent); - *fenced = ((f.flags & FENCE_FLAGS_FENCED) != 0); - } - return ret; -} - -int cman_get_node_addrs(cman_handle_t handle, int nodeid, int max_addrs, int *num_addrs, struct cman_node_address *addrs) -{ - struct cman_handle *h = (struct cman_handle *)handle; - int ret; - char buf[sizeof(struct cl_get_node_addrs) + sizeof(struct cl_node_addrs)*max_addrs]; - struct cl_get_node_addrs *outbuf = (struct cl_get_node_addrs *)buf; - VALIDATE_HANDLE(h); - - ret = info_call(h, CMAN_CMD_GET_NODEADDRS, &nodeid, sizeof(int), buf, sizeof(buf)); - if (!ret) { - int i; - - *num_addrs = outbuf->numaddrs; - - if (outbuf->numaddrs > max_addrs) - outbuf->numaddrs = max_addrs; - - for (i=0; i < outbuf->numaddrs; i++) { - memcpy(&addrs[i].cna_address, &outbuf->addrs[i].addr, outbuf->addrs[i].addrlen); - addrs[i].cna_addrlen = outbuf->addrs[i].addrlen; - } - } - return ret; -} - -int cman_node_fenced(cman_handle_t handle, int nodeid, uint64_t time, char *agent) -{ - struct cman_handle *h = (struct cman_handle *)handle; - struct cl_fence_info f; - VALIDATE_HANDLE(h); - - if (strlen(agent) >= MAX_FENCE_AGENT_NAME_LEN) { - errno = EINVAL; - return -1; - } - - f.nodeid = nodeid; - f.fence_time = time; - strcpy(f.fence_agent, agent); - return info_call(h, CMAN_CMD_UPDATE_FENCE_INFO, &f, sizeof(f), NULL, 0); -} - -#ifdef DEBUG -int cman_dump_objdb(cman_handle_t handle, char *filename) -{ - struct cman_handle *h = (struct cman_handle *)handle; - VALIDATE_HANDLE(h); - - return info_call(h, CMAN_CMD_DUMP_OBJDB, filename, strlen(filename)+1, NULL, 0); -} -#endif diff --git a/cman/lib/libcman.h b/cman/lib/libcman.h deleted file mode 100644 index 7548251..0000000 --- a/cman/lib/libcman.h +++ /dev/null @@ -1,423 +0,0 @@ -#ifndef _LIBCMAN_H_ -#define _LIBCMAN_H_ - -#include - -#define LIBCMAN_VERSION 3 - -/* - * Some maxima - */ -#define CMAN_MAX_ADDR_LEN sizeof(struct sockaddr_in6) -#define CMAN_MAX_NODENAME_LEN 255 -#define MAX_CLUSTER_NAME_LEN 16 -#define CMAN_MAX_FENCE_AGENT_NAME_LEN 255 - -/* - * Pass this into cman_get_node() as the nodeid to get local node information - */ -#define CMAN_NODEID_US 0 - -/* - * Pass this into cman_get_node() as the nodeid to get quorum device information - */ -#define CMAN_NODEID_QDISK -1 - - -/* 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() or - * cman_admin_init() - */ -typedef void *cman_handle_t; - -/* - * Reasons we get an event callback. - * PORTOPENED & TRY_SHUTDOWN only exist when LIBCMAN_VERSION >= 2 - * - * The 'arg' parameter varies depending on the callback type. - * for PORTCLOSED/PORTOPENED arg == the port opened/closed - * for STATECHANGE arg is quorum state (1=quorate, 0=not) - * for TRY_SHUTDOWN arg == 1 for ANYWAY, otherwise 0 (ie if arg == 1 - * then cman WILL shutdown regardless - * of your response, think of this as advance warning) - * for CONFIG_UPDATE arg will be the new config version - */ -typedef enum {CMAN_REASON_PORTCLOSED, - CMAN_REASON_STATECHANGE, - CMAN_REASON_PORTOPENED, - CMAN_REASON_TRY_SHUTDOWN, - CMAN_REASON_CONFIG_UPDATE} cman_call_reason_t; - -/* - * Reason flags for cman_leave - */ -#define CMAN_LEAVEFLAG_DOWN 0 -#define CMAN_LEAVEFLAG_REMOVED 3 -#define CMAN_LEAVEFLAG_FORCE 0x10 - -/* - * Flags for cman_shutdown - * ANYWAY - cman will shutdown regardless of clients' responses (but they - * will still get told) - * REMOVED - the rest of the cluster will adjust quorum to stay quorate - */ -#define CMAN_SHUTDOWN_ANYWAY 1 -#define CMAN_SHUTDOWN_REMOVED 2 - -/* - * Flags passed to cman_dispatch(): - * CMAN_DISPATCH_ONE dispatches a single message then returns, - * CMAN_DISPATCH_ALL dispatches all outstanding messages (ie till EAGAIN) then - * returns, - * CMAN_DISPATCH_BLOCKING forces it to wait for a message (clears MSG_DONTWAIT - * in recvmsg) - * CMAN_DISPATCH_IGNORE_* allows the caller to select which messages to process. - */ -#define CMAN_DISPATCH_ONE 0 -#define CMAN_DISPATCH_ALL 1 -#define CMAN_DISPATCH_BLOCKING 2 -#define CMAN_DISPATCH_IGNORE_REPLY 4 -#define CMAN_DISPATCH_IGNORE_DATA 8 -#define CMAN_DISPATCH_IGNORE_EVENT 16 -#define CMAN_DISPATCH_TYPE_MASK 3 -#define CMAN_DISPATCH_IGNORE_MASK 46 - -/* - * A node address. This is a complete sockaddr_in[6] - * To explain: - * If you cast cna_address to a 'struct sockaddr', the sa_family field - * will be AF_INET or AF_INET6. Armed with that knowledge you can then - * cast it to a sockaddr_in or sockaddr_in6 and pull out the address. - * No other sockaddr fields are valid. - * Also, you must ignore any part of the sockaddr beyond the length supplied - */ -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(), though only cv_config can be changed - */ -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; - uint32_t ci_generation; -} cman_cluster_t; - -/* - * This is returned from cman_get_extra_info - it's really - * only for use by cman_tool, don't depend on this not changing - */ - -/* Flags in ei_flags */ -#define CMAN_EXTRA_FLAG_2NODE 1 -#define CMAN_EXTRA_FLAG_ERROR 2 -#define CMAN_EXTRA_FLAG_SHUTDOWN 4 -#define CMAN_EXTRA_FLAG_DISALLOWED 8 -#define CMAN_EXTRA_FLAG_DIRTY 16 - -typedef struct cman_extra_info { - int ei_node_state; - int ei_flags; - int ei_node_votes; - int ei_total_votes; - int ei_expected_votes; - int ei_quorum; - int ei_members; - char ei_ports[32]; - int ei_num_addresses; - char ei_addresses[1]; /* Array of num_addresses*sockaddr_storage*2 - First batch is the multicast address list */ -} cman_extra_info_t; - -/* Quorum device info, returned from cman_get_quorum_device() */ -typedef struct cman_qdev_info { - char qi_name[CMAN_MAX_NODENAME_LEN+1]; - int qi_state; - int qi_votes; -} cman_qdev_info_t; - -/* - * NOTE: Apart from cman_replyto_shutdown(), you must not - * call other cman_* functions while in these two callbacks: - */ - -/* Callback routine for a membership or other 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); - -/* Callback for nodes joining/leaving */ -typedef void (*cman_confchgcallback_t)(cman_handle_t handle, void *privdata, - unsigned int *member_list, int member_list_entries, - unsigned int *left_list, int left_list_entries, - unsigned int *joined_list, int joined_list_entries); - -/* - * cman_init returns the handle you need to pass to the other API calls. - * cman_admin_init opens admin socket for privileged operations. - * cman_finish destroys that handle. - * - * Note that admin sockets can't send data messages or receive callbacks. - */ -cman_handle_t cman_init(void *privdata); -cman_handle_t cman_admin_init(void *privdata); -int cman_finish(cman_handle_t handle); - -/* Update/retrieve the private data */ -int cman_setprivdata(cman_handle_t *h, void *privdata); -int cman_getprivdata(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 or joined the cluster. - */ -int cman_start_notification(cman_handle_t handle, cman_callback_t callback); -int cman_stop_notification(cman_handle_t handle); - -/* - * Start/stop AIS-style confchg callbacks. These are less racy than the - * old cman callbacks in that the caller will get one for each AIS - * confchg message and it will contain all of the nodes that joined & - * left in that transition. - */ -int cman_start_confchg(cman_handle_t handle, cman_confchgcallback_t callback); -int cman_stop_confchg(cman_handle_t handle); - -/* Call this if you get a TRY_SHUTDOWN event to signal whether you - * will let cman shutdown or not. - * Note that getting this callback does not mean that cman WILL shutdown, - * only that it might. To detect a cman shutdown see cman_dispatch() below. - */ -int cman_replyto_shutdown(cman_handle_t, int yesno); - - -/* - * Get the internal CMAN fd so you can pass it into poll() or select(). - * When it's active then call cman_dispatch() on the handle to process the event - * NOTE: This fd can change between calls to cman_dispatch() so always call this - * routine to get the latest one. (This is mainly due to message caching). - * One upshot of this is that you must never read or write this FD (it may on - * occasion point to /dev/zero if you have messages cached!) - */ -int cman_get_fd(cman_handle_t handle); - -/* - * cman_dispatch() will return -1 with errno == EHOSTDOWN if the cluster is - * shut down, 0 if nothing was read, or a positive number if something was - * dispatched. - */ - -int cman_dispatch(cman_handle_t handle, int flags); - - -/* - * ----------------------------------------------------------------------------- - * Get info calls. - */ - -/* Return the number of nodes we know about. This will normally - * be the number of nodes in CCS - */ -int cman_get_node_count(cman_handle_t handle); - -/* Returns the number of connected clients. This isn't as useful as a it used to - * be as a count >1 does not automatically mean cman won't shut down. Subsystems - * can decide for themselves whether a clean shutdown is possible. - */ -int cman_get_subsys_count(cman_handle_t handle); - -/* Returns an array of node info structures. Call cman_get_node_count() first - * to determine how big your array needs to be - */ -int cman_get_nodes(cman_handle_t handle, int maxnodes, int *retnodes, cman_node_t *nodes); - -/* Returns a list of nodes that are known to AIS but blocked from joining the - * CMAN cluster because they rejoined with cluster without a cman_tool join - */ -int cman_get_disallowed_nodes(cman_handle_t handle, int maxnodes, int *retnodes, cman_node_t *nodes); - -/* - * cman_get_node() can get node info by nodeid OR by name. If the first - * char of node->cn_name is zero then the nodeid will be used, otherwise - * the name will be used. I'll say this differently: If you want to look - * up a node by nodeid, you MUST clear out the cman_node_t structure passed - * into cman_get_node(). nodeid can be CMAN_NODEID_US. - */ -int cman_get_node(cman_handle_t handle, int nodeid, cman_node_t *node); - -/* cman_get_node() only returns the first address of a node (whatever /that/ - * may mean). If you want to know all of them you need to call this. - * max_addrs is the size of the 'addrs' array. num_addrs will be filled in by - * the number of addresses the node has, regardless of the size of max_addrs. - * So if you don't allocate enough space for the first call, you should know how - * much is needed for a second! - */ -int cman_get_node_addrs(cman_handle_t handle, int nodeid, int max_addrs, int *num_addrs, struct cman_node_address *addrs); - -/* Returns 1 if cman has completed initialisation and aisexec is running */ -int cman_is_active(cman_handle_t handle); - -/* - * Returns 1 if a client is registered for data callbacks on a particular - * port on a particular node. if cman returns -1 (errno==EBUSY) then it - * doesn't currently know the status but has requested it, so try again - * later or wait for a PORTOPENED notification. - * nodeid can be CMAN_NODEID_US - */ -int cman_is_listening(cman_handle_t handle, int nodeid, uint8_t port); - -/* Do we have quorum? */ -int cman_is_quorate(cman_handle_t handle); - -/* Return software & config (cluster.conf file) version */ -int cman_get_version(cman_handle_t handle, cman_version_t *version); - -/* Get cluster name and number */ -int cman_get_cluster(cman_handle_t handle, cman_cluster_t *clinfo); - -/* Get fence information for a node. - * 'int *fenced' is only valid if the node is down, it is set to - * 1 if the node has been fenced since it left the cluster. - * agent should be CMAN_MAX_FENCE_AGENT_NAME_LEN - */ -int cman_get_fenceinfo(cman_handle_t handle, int nodeid, uint64_t *fence_time, int *fenced, char *agent); - -/* Get stuff for cman_tool. Nobody else should use this */ -int cman_get_extra_info(cman_handle_t handle, cman_extra_info_t *info, int maxlen); - -/* Dump the objdb contents (only works if compiled with DEBUG enabled) */ -int cman_dump_objdb(cman_handle_t handle, char *filename); - -/* - * ----------------------------------------------------------------------------- - * Admin functions. You will need privileges and have a handle created by - * cman_admin_init() to use them. - */ - -/* Change the config file version. This should be needed much less now, as - * cman will re-read the config file if a new node joins with a new config - * version */ -int cman_set_version(cman_handle_t handle, const cman_version_t *version); - -/* Deprecated in favour of cman_shutdown(). Use cman_tool anyway please. */ -int cman_leave_cluster(cman_handle_t handle, int reason); - -/* Change the number of votes for this node. NOTE: a CCS update will - overwrite this, so make sure you change both. Or, better, change CCS - and call set_version() */ -int cman_set_votes(cman_handle_t handle, int votes, int nodeid); - -/* As above, for expected_votes */ -int cman_set_expected_votes(cman_handle_t handle, int expected_votes); - -/* Tell a particular node to leave the cluster NOW */ -int cman_kill_node(cman_handle_t handle, int nodeid); - -/* Tell CMAN a node has been fenced, when and by what means. */ -int cman_node_fenced(cman_handle_t handle, int nodeid, uint64_t fence_time, char *agent); - -/* - * cman_shutdown() will send a REASON_TRY_SHUTDOWN event to all - * clients registered for notifications. They should respond by calling - * cman_replyto_shutdown() to indicate whether they will allow - * cman to close down or not. If cman gets >=1 "no" (0) replies or the - * request times out (default 5 seconds) then shutdown will be - * cancelled and cman_shutdown() will return -1 with errno == EBUSY. - * - * Set flags to CMAN_SHUTDOWN_ANYWAY to force shutdown. Clients will still - * be notified /and/ they will know you want a forced shutdown. - * - * Setting flags to CMAN_SHUTDOWN_REMOVED will tell the rest of the - * cluster to adjust quorum to keep running with this node has left - */ -int cman_shutdown(cman_handle_t, int flags); - -/* ----------------------------------------------------------------------------- - * 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, const void *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. - * Here for backwards compatibility. Most of the things you would achieve - * with this can now be better done using openAIS services or just messaging. - */ -int cman_barrier_register(cman_handle_t handle, const char *name, int flags, int nodes); -int cman_barrier_change(cman_handle_t handle, const char *name, int flags, int arg); -int cman_barrier_wait(cman_handle_t handle, const char *name); -int cman_barrier_delete(cman_handle_t handle, const char *name); - -/* - * Add your own quorum device here, needs an admin socket - * - * After creating a quorum device you will need to call 'poll_quorum_device' - * at least once every (default) 10 seconds (this can be changed in CCS) - * otherwise it will time-out and the cluster will lose its vote. - */ -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); -int cman_get_quorum_device(cman_handle_t handle, struct cman_qdev_info *info); - -/* - * Sets the dirty bit inside cman. This indicates that the node has - * some internal 'state' (eg in a daemon, filesystem or lock manager) - * and cannot merge with another cluster that already has state. - * This needs an admin socket. It cannot be reset. - */ -int cman_set_dirty(cman_handle_t handle); - - -/* - * Changes the debug logging level inside cman. - * subsystems is a bitmask of: - */ -#define CMAN_DEBUGLOG_NONE 0 -#define CMAN_DEBUGLOG_BARRIER 2 -#define CMAN_DEBUGLOG_MEMBERSHIP 4 -#define CMAN_DEBUGLOG_DAEMON 8 -#define CMAN_DEBUGLOG_AIS 16 - -int cman_set_debuglog(cman_handle_t handle, int subsystems); - -#endif diff --git a/cman/man/Makefile b/cman/man/Makefile deleted file mode 100644 index 54d7c9a..0000000 --- a/cman/man/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -TARGET= cman.5 \ - qdisk.5 \ - cman_tool.8 \ - qdiskd.8 \ - mkqdisk.8 \ - cmannotifyd.8 - -include ../../make/defines.mk -include $(OBJDIR)/make/man.mk diff --git a/cman/man/cman.5 b/cman/man/cman.5 deleted file mode 100644 index d36f484..0000000 --- a/cman/man/cman.5 +++ /dev/null @@ -1,222 +0,0 @@ -.\" groff -t -e -mandoc -Tlatin1 cman.5 | less - -.TH "cman" "5" "" "" "cluster.conf cman configuration section" - -.SH "NAME" -cman \- cluster.conf cman configuration section - -.SH "DESCRIPTION" - -.in +7 -Cman configuration values are placed in the section of -\fBcluster.conf\fP. Per-node configuration related to cman is placed -in the standard sections. All cman -configuration settings are optional; usually none are used. The -section is placed under the section in cluster.conf. - - - - - ... - -.in -7 - - -\fIUDP port\fR -.in +7 -By default, cman will use UDP port 5405/5404 for internode communication. This can -be changed by setting a port number as follows: - - - - -This will cause cman to use ports 6809 and 6808 for cluster communications. - -.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 sets the expected votes value to be the sum -of votes of all nodes listed in cluster.conf. This can be overridden by setting -an explicit expected_votes value as follows: - - - - -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. - - - -.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: - - - -.in -7 - - -\fINode ID\fR -.in +7 - -All nodes must have a unique node ID. This is a single integer that identifies -it to the cluster. -A node's application to join the cluster may be rejected if you try to set -the nodeid to one that is already used. - - - - -.in -7 -\fIMulti-home configuration\fR -.in +7 -It is quite common to use multiple ethernet adapters for cluster nodes, so -they will tolerate the failure of one link. A common way to do this is to use -ethernet bonding. Alternatively you can get openais to run in redundant ring -mode by specifying an 'altname' for the node. This is an alternative name by -which the node is known, that resolves to another IP address used on the -other ethernet adapter(s). You can optionally specify a different port and/or -multicast address for each altname in use. Up to 9 altnames (10 interfaces -in total) can be used. - -Note that if you are using the DLM with cman/openais then you MUST tell it -to use SCTP as it's communications protocol as TCP does not support multihoming. - - - - - - -.in -7 - - -\fIMulticast network configuration\fR -.in +7 -cman uses multicast UDP packets to communicate with other nodes in the cluster. -By default it will generate a multicast address using 239.192.x.x where x.x is -the 16bit cluster ID number split into bytes. This, in turn is generated from a -hash of the cluster name though it can be specified explicitly. The purpose -of this is to allow multiple clusters to share the same subnet - they will each -use a different multicast address. You might also/instead want to isolate -clusters using the port number as shown above. - -It is possible to override the multicast address by specifying it in cluster.conf -as shown: - - - - - -.in -7 - -\fICluster ID\fR -.in +7 -The cluster ID number is used to isolate clusters in the same subnet. Usually it -is generated from a hash of the cluster name, but it can be overridden here if -you feel the need. Sometimes cluster names can hash to the same ID. - - - - -.in -7 - -\fIopenais security key\fR -.in +7 -All traffic sent out by cman/openais is encrypted. By default the security key -used is simply the cluster name. If you need more security you can specify a -key file that contains the key used to encrypt cluster communications. -Of course, the contents of the key file must be the same on all nodes in the -cluster. It is up to you to securely copy the file to the nodes. - - - - -Note that this only applies to cluster communication. The DLM does not encrypt -traffic. -.in -7 - - -\fIOther openais parameters\fR -.in +7 -When openais is started by cman (cman_tool runs aisexec), the openais.conf -file is not used. Many of the configuration parameters listed in -openais.conf can be set in cluster.conf (CCS) instead. Cman will read -openais parameters from the following sections in cluster.conf and load -them into openais: - - - - - - - - - -See the -.B openais.conf(5) -man page for more information on keys that are valid for these sections. -Note that settings in the section will override settings in -the sections above, and options on the cman_tool command line will -override both. In particular, settings like bindnetaddr, mcastaddr, -mcastport and nodeid will always be replaced by values in . - -Cman uses different defaults for some of the openais parameters listed in -openais.conf(5). If you wish to use a non-default setting, they can be -configured in cluster.conf as shown above. Cman uses the following -default values: - - - /> - - - -Here's how to set the token timeout to five seconds: - - - -And this is how to add extra openais logging options to CMAN and CPG: - - - - - - - - -.in -7 - - -.sp - -.SH "SEE ALSO" - -cluster.conf(5), openais.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 4cd60a5..0000000 --- a/cman/man/cman_tool.8 +++ /dev/null @@ -1,411 +0,0 @@ -.TH CMAN_TOOL 8 "Nov 8 2007" "Cluster utilities" - -.SH NAME -cman_tool \- Cluster Management Tool -.SH SYNOPSIS -.B cman_tool join | leave | kill | expected | votes | version | wait | status | nodes | services | debug [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 cluster.conf. However, it is possible to provide -all the information on the command-line or to override cluster.conf 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' and group_tool to see how many (and which) -subsystems are active. -.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 tell cluster members to update. - -.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 subsystems using cman (deprecated, group_tool -should be used instead). - -.TP -.I debug -Sets the debug level of the running cman daemon. Debug output will be -sent to syslog level LOG_DEBUG. the -.B -d -switch specifies the new logging level. This is the same bitmask used -for cman_tool join -d -.br -.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 -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 -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 -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 -Update config version. You don't need to use this when adding a new node, -the new cman node will tell the rest of the cluster to read the latest -version of the config file automatically. -.br -In fact the argument to -r might look as though it is ignored. -Its presence simply tells cman to re-read the configuration file and look -for that version in the file. cman will keep re-reading the file -until a version number >= the passed version is found. -.br -cman_tool version on its own will always show the current version -and not the one being looked for. So be aware that the display -will possible not update immediately after you have run -cman_tool version -r. -.SH "WAIT" OPTIONS -.TP -.I -q -Waits until the cluster is quorate before returning. -.I -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. - -.br -.SH "JOIN" OPTIONS -.TP -.I -c -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 -UDP port number used for cluster communication. This defaults to 5405. -.TP -.I -v -Number of votes this node has in the cluster. Defaults to 1. -.TP -.I -e -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. The default for -this value is 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 -Overrides the node name. By default the unqualified hostname is used. This -option is also used to specify which interface is used for cluster -communication. -.TP -.I -N -Overrides the node ID for this node. Normally, nodes are assigned a -node id in cluster.conf. If you specify an incorrect node ID here, the -node might not be allowed to join the cluster. Setting node IDs in the -configuration is a far better way to do this. -.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 -o -Override the name this node will have in the cluster. This will -normally be the hostname or the first name specified by -n. -Note how this differs from -n: -n tells cman_tool how to find -the host address and/or the entry in the configuration file. -o simply -changes the name the node will have in the cluster and has no -bearing on the actual name of the machine. Use this option -will extreme caution. -.BR -.TP -.I -m -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 -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 -k -All traffic sent out by cman/openais is encrypted. By default the security key -used is simply the cluster name. If you need more security you can specify a -key file that contains the key used to encrypt cluster communications. -Of course, the contents of the key file must be the same on all nodes in the -cluster. It is up to you to securely copy the file to the nodes. -.TP -.I -t -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. -.TP -.I -X -Tells cman not to use the configuration file to get cluster information. If you use this option then cman will -apply several defaults to the cluster to get it going. The cluster name will be -"RHCluster", node IDs will default to the IP address of the node and remote node -names will show up as Node. All of these, apart from the node names can -be overridden on the cman_tool command-line if required. -.br -If you have to set up fence devices, services or anything else in cluster.conf then -this option is probably not worthwhile to you - the extra readability of sensible node -names and numbers will make it worth using cluster.conf for the cluster too. But for a simple -failover cluster this might save you some effort. -.br -On each node using this configuration you will need to have the same authorization key -installed. To create this key run -.br -mkdir /etc/ais -.br -ais-keygen -.br -mv /etc/ais/authkey /etc/cluster/cman_authkey -.br -then copy that file to all nodes you want to join the cluster. -.br -.TP -.I -C -Overrides the default configuration module. Usually cman uses ccsd to load its -configuration. If you have your configuration database held elsewhere (eg LDAP) and -have a configuration plugin for it, then you should specify the name of the module -(see the documentation for the module for the name of it - it's not necessarily the -same as the filename) here. -.br -It is possible to chain configuration modules by separating them with colons. So to -add two modules (eg) 'ldapconfig' and 'ldappreproc' to the chain start cman with --C ldapconfig:ldappreproc -.br -The default value for this is 'ccsconfig'. Note that if the -X is on the command-line -then -C will be ignored. -.TP -.I -A -Don't load openais services. Normally cman_tool join will load the configuration -module 'openaisserviceenable' which will load the services installed by openais. -If you don't want to use these services or have not installed openais then -this switch will disable them. -.SH "NODES" OPTIONS -.TP -.I -f -Shows the date/time the node was last fenced (if it has bee fenced), and also -the fence system that was used. -.br -.TP -.I -a -Shows the IP address(es) the nodes are communicating on. -.br -.TP -.I -n -Shows node information for a specific node. This should be the unqualified node -name as it appears in 'cman_tool nodes'. -.br -.TP -.I -F -Specify the format of the output. The format string may contain one or -more format options, each separated by a comma. Valid format options -include: id, name, type, and addr. -.br -.SH "DEBUG" OPTIONS -.TP -.I -d -The value is a bitmask of -.br -2 Barriers -.br -4 Membership messages -.br -8 Daemon operation, including command-line interaction -.br -16 Interaction with OpenAIS -.br -32 Startup debugging (cman_tool join operations only) -.br -.SH NOTES -.br -the -.B nodes -subcommand shows a list of nodes known to cman. the state is one of the following: -.br -M The node is a member of the cluster -.br -X The node is not a member of the cluster -.br -d The node is known to the cluster but disallowed access to it. -.br -.SH ENVIRONMENT VARIABLES -cman_tool removes most environment variables before forking and running OpenAIS, as well as adding some of its own for setting up -configuration parameters that were overridden on the command-line, the exception to this is that variable with names starting -COROSYNC_ will be passed down intact as they are assumed to be used for configuring the daemon. - -.SH DISALLOWED NODES -Occasionally (but very infrequently I hope) you may see nodes marked as "Disallowed" in cman_tool status or "d" in cman_tool nodes. This is a bit of a nasty hack to get around mismatch between what the upper layers expect of the cluster manager and OpenAIS. -.TP -If a node experiences a momentary lack of connectivity, but one that is long enough to trigger the token timeouts, then it will be removed from the cluster. When connectivity is restored OpenAIS will happily let it rejoin the cluster with no fuss. Sadly the upper layers don't like this very much. They may (indeed probably will have) have changed their internal state while the other node was away and there is no straightforward way to bring the rejoined node up-to-date with that state. When this happens the node is marked "Disallowed" and is not permitted to take part in cman operations. -.P -If the remainder of the cluster is quorate the the node will be sent a kill message and it will be forced to leave the cluster that way. Note that fencing should kick in to remove the node permanently anyway, but it may take longer than the network outage for this to complete. - -If the remainder of the cluster is inquorate then we have a problem. The likelihood is that we will have two (or more) partitioned clusters and we cannot decide which is the "right" one. In this case we need to defer to the system administrator to kill an appropriate selection of nodes to restore the cluster to sensible operation. - -The latter scenario should be very rare and may indicate a bug somewhere in the code. If the local network is very flaky or busy it may be necessary to increase some of the protocol timeouts for OpenAIS. We are trying to think of better solutions to this problem. - -Recovering from this state can, unfortunately, be complicated. Fortunately, in the majority of cases, fencing will do the job for you, and the disallowed state will only be temporary. If it persists, the recommended approach it is to do a cman tool nodes on all systems in the cluster and determine the largest common subset of nodes that are valid members to each other. Then reboot the others and let them rejoin correctly. In the case of a single-node disconnection this should be straightforward, with a large cluster that has experienced a network partition it could get very complicated! - -Example: - -In this example we have a five node cluster that has experienced a network partition. Here is the output of cman_tool nodes from all systems: -.nf -Node Sts Inc Joined Name - 1 M 2372 2007-11-05 02:58:55 node-01.example.com - 2 d 2376 2007-11-05 02:58:56 node-02.example.com - 3 d 2376 2007-11-05 02:58:56 node-03.example.com - 4 M 2376 2007-11-05 02:58:56 node-04.example.com - 5 M 2376 2007-11-05 02:58:56 node-05.example.com - -Node Sts Inc Joined Name - 1 d 2372 2007-11-05 02:58:55 node-01.example.com - 2 M 2376 2007-11-05 02:58:56 node-02.example.com - 3 M 2376 2007-11-05 02:58:56 node-03.example.com - 4 d 2376 2007-11-05 02:58:56 node-04.example.com - 5 d 2376 2007-11-05 02:58:56 node-05.example.com - -Node Sts Inc Joined Name - 1 d 2372 2007-11-05 02:58:55 node-01.example.com - 2 M 2376 2007-11-05 02:58:56 node-02.example.com - 3 M 2376 2007-11-05 02:58:56 node-03.example.com - 4 d 2376 2007-11-05 02:58:56 node-04.example.com - 5 d 2376 2007-11-05 02:58:56 node-05.example.com - -Node Sts Inc Joined Name - 1 M 2372 2007-11-05 02:58:55 node-01.example.com - 2 d 2376 2007-11-05 02:58:56 node-02.example.com - 3 d 2376 2007-11-05 02:58:56 node-03.example.com - 4 M 2376 2007-11-05 02:58:56 node-04.example.com - 5 M 2376 2007-11-05 02:58:56 node-05.example.com - -Node Sts Inc Joined Name - 1 M 2372 2007-11-05 02:58:55 node-01.example.com - 2 d 2376 2007-11-05 02:58:56 node-02.example.com - 3 d 2376 2007-11-05 02:58:56 node-03.example.com - 4 M 2376 2007-11-05 02:58:56 node-04.example.com - 5 M 2376 2007-11-05 02:58:56 node-05.example.com -.fi -In this scenario we should kill the node node-02 and node-03. Of course, the 3 node cluster of node-01, node-04 & node-05 should remain quorate and be able to fenced the two rejoined nodes anyway, but it is possible that the cluster has a qdisk setup that precludes this. - -.SH CONFIGURATION SYSTEMS -This section details how the configuration systems work in cman. You might need to know this if you are using the -C option -to cman_tool, or writing your own configuration subsystem. -.br -By default cman uses two configuration plugins to OpenAIS. The first, 'ccsconfig', reads the configuration information -stored in cluster.conf and stores it in an internal database, in the same schema as it finds in cluster.conf. -The second plugin, 'cmanpreconfig', takes the information in that the database, adds several cman defaults, determines -the OpenAIS node name and nodeID -and formats the information in a similar manner to openais.conf(5). OpenAIS then reads those keys to start the cluster protocol. -cmanpreconfig also reads several environment variables that might be set by cman_tool which can override information in the -configuration. -.br -In the absence of ccsconfig, ie when 'cman_tool join' is run with -X switch (this removes ccsconfig from the module list), -cmanpreconfig also generates several defaults so that the cluster can be got running without any configuration information - see above -for the details. -.br -Note that cmanpreconfig will not overwrite OpenAIS keys that are explicitly set in the configuration file, allowing you to provide -custom values for token timeouts etc, even though cman has its own defaults for some of those values. The exception to this is the node -name/address and multicast values, which are always taken from the cman configuration keys. diff --git a/cman/man/cmannotifyd.8 b/cman/man/cmannotifyd.8 deleted file mode 100644 index 56ad353..0000000 --- a/cman/man/cmannotifyd.8 +++ /dev/null @@ -1,66 +0,0 @@ -.TH "cmannotifyd" "8" "November 2008" "" "CMAN Notification Daemon" -.SH "NAME" -cmannotifyd \- CMAN Notification Daemon -.SH "SYNOPSIS" -\fBcmannotifyd [\-f] [\-d] -.SH "DESCRIPTION" -.PP -The \fBcmannotifyd\fP daemon talks to CMAN and provides a mechanism to notify -external entities about cluster changes. - -CMAN dispatches 3 kind of notifications: - -\- CMAN_REASON_TRY_SHUTDOWN when cman requests to all clients if it is allowed -to shutdown. - -\- CMAN_REASON_STATECHANGE when cman detects a node joining or leaving the -cluster. - -\- CMAN_REASON_CONFIG_UPDATE when a configuration change event has been -detected/requested. - -These notifications are then dispatched to the shell script -.B cman_notify -in the environment variable CMAN_NOTIFICATION. - -.B cman_notify -will then execute all the scripts in the configured notification -directory (default: /etc/cluster/cman-notify.d) passing a very minimal set of -envvars including, of course, the CMAN_NOTIFICATION= type. -The execution order is set by the filename as shown by "LC_ALL=C ls -las". - -.B cmannotifyd -logs are stored in the default log file -(/var/log/cluster/cmannotifyd.log). - -.B cman_notify -logs are stored in the default log file -(/var/log/cluster/cman_notify.log). By default the output from the scripts -executed by -.B cman_notify -is redirected to /dev/null. -Users can either set CMAN_NOTIFICATION_DEBUG=1 in their environment or -set proper debug configuration in cluster.conf to redirect scripts output -to the cman_notify log file. - -.SH "NOTES" -cmannotifyd does not block on cman_notify nor check the exit -status of the script. - -Notifications are dispatched in the same order as they -arrive, one by one. - -CMAN_REASON_TRY_SHUTDOWN is passed to scripts for information only, they -can not influence cman's decsion about whether or not to shut down. - -CMAN_REASON_STATECHANGE also implies CMAN_NOTIFICATION_QUORUM exported -in the environment. CMAN_NOTIFICATION_QUORUM will be set to 1 (when the node -is part of a quorate cluster) or 0 (otherwise). - -A template for cman_notify scripts can be found in the doc/ directory. - -.SH "OPTIONS" -.IP "\-f" -Run in the foreground (do not fork / daemonize). -.IP "\-d" -Enable debug output. diff --git a/cman/man/mkqdisk.8 b/cman/man/mkqdisk.8 deleted file mode 100644 index a097680..0000000 --- a/cman/man/mkqdisk.8 +++ /dev/null @@ -1,31 +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] [-d [-d ...]] -.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. -.IP "\-d" -Increase debugging level. Specify multiple times for more information. -Currently, specifying more than twice has no effect. - -.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 dcf0908..0000000 --- a/cman/man/qdisk.5 +++ /dev/null @@ -1,462 +0,0 @@ -.TH "QDisk" "5" "20 Feb 2007" "" "Cluster Quorum Disk" -.SH "NAME" -qdisk \- 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, preferably 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 node votes should be more or less equal. - -* 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 or greater than the total number -of node-votes in the cluster. While it is possible to assign only one -(or a few) votes to the quorum device, the effects of doing so have not -been explored. - -* 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 performance 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 tag" -This tag is a child of the top-level tag. - -.in 8 -\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 9 -\fImax_error_cycles\fP\fB="\fP0\fB"/>\fP -.in 12 -If we receive an I/O error during a cycle, we do not poll CMAN and tell -it we are alive. If specified, this value will cause qdiskd to exit -after the specified number of consecutive cycles during which I/O errors -occur. The default is 0 (no maximum). - -.in 8 -\fB/>\fP -.in 0 - -.SH "3.2. The tag" -This tag is a child of the tag. - -.in 8 -\fB\fP -.in 0 - - -.SH "3.3. Examples" -.SH "3.3.1. 3 cluster nodes & 3 routers" -.in 8 - -.br - -.in 12 - -.br - -.br - -.in 8 - -.br - -.in 12 - -.br - -.br - -.br -.in 8 - - -.SH "3.3.2. 2 cluster nodes & 1 IP tiebreaker" -.in 8 - -.br - -.in 12 - -.br - -.in 8 - -.br - -.in 12 - -.br -.in 8 - -.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/notifyd/Makefile b/cman/notifyd/Makefile deleted file mode 100644 index b2e5114..0000000 --- a/cman/notifyd/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -TARGET1= cmannotifyd -TARGET2= cman_notify - -SBINDIRT=${TARGET1} ${TARGET2} - -all: depends ${TARGET1} ${TARGET2} - -include ../../make/defines.mk -include $(OBJDIR)/make/cobj.mk -include $(OBJDIR)/make/clean.mk -include $(OBJDIR)/make/install.mk -include $(OBJDIR)/make/uninstall.mk - -CFLAGS += -D_GNU_SOURCE -DSBINDIR=\"${sbindir}\" -CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${logtincdir} -CFLAGS += -I${incdir} - -LDFLAGS += -L${cmanlibdir} -L${ccslibdir} -L${logtlibdir} -lcman -lccs -llogthread -LDFLAGS += -L${libdir} - -OBJS1= main.o - -${TARGET1}: ${OBJS1} - $(CC) -o $@ $^ $(LDFLAGS) - -${TARGET2}: $(S)/${TARGET2}.in - cat $(S)/${TARGET2}.in | sed \ - -e 's#@NOTIFYDDIR@#${notifyddir}#g' \ - -e 's#@LOGDIR@#${logdir}#g' \ - > ${TARGET2} - -depends: - $(MAKE) -C ../lib all - -clean: generalclean - --include $(OBJS1:.o=.d) diff --git a/cman/notifyd/cman_notify.in b/cman/notifyd/cman_notify.in deleted file mode 100644 index 9e05bc0..0000000 --- a/cman/notifyd/cman_notify.in +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -# concept from Debian run-parts and similar from fedora crontabs - -# keep going when something fails -set +e - -if [ ! -d "@NOTIFYDDIR@" ]; then - exit 0 -fi - -LOGFILE="@LOGDIR@/cman_notify.log" - -if [ "$CMAN_NOTIFICATION_DEBUG" = "1" ]; then - OUT="$LOGFILE" -fi - -# Ignore *~ and *, scripts -for i in $(LC_ALL=C; echo @NOTIFYDDIR@/*[^~,]); do - [ -d $i ] && continue - # skip know scripts - [ "${i%.cfsaved}" != "${i}" ] && continue - [ "${i%.rpmsave}" != "${i}" ] && continue - [ "${i%.rpmorig}" != "${i}" ] && continue - [ "${i%.rpmnew}" != "${i}" ] && continue - [ "${i%.swp}" != "${i}" ] && continue - [ "${i%,v}" != "${i}" ] && continue - [ "${i%.dpkg-old}" != "${i}" ] && continue - [ "${i%.dpkg-dist}" != "${i}" ] && continue - [ "${i%.dpkg-new}" != "${i}" ] && continue - - if [ -x $i ]; then - echo "starting $(basename $i)" >> $LOGFILE - [ -n "$OUT" ] && $i >> $OUT - [ -z "$OUT" ] && $i > /dev/null 2>&1 - echo "finished $(basename $i)" >> $LOGFILE - fi -done - -exit 0 diff --git a/cman/notifyd/main.c b/cman/notifyd/main.c deleted file mode 100644 index 173cb64..0000000 --- a/cman/notifyd/main.c +++ /dev/null @@ -1,382 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "copyright.cf" - -int debug = 0; -int daemonize = 1; -int daemon_quit = 0; -cman_handle_t cman_handle; -int rr = 0; - -#define LOCKFILE_NAME "/var/run/cmannotifyd.pid" - -#define OPTION_STRING "hdfVr" - -#ifndef MAX_ARGS -#define MAX_ARGS 128 -#endif - -static void print_usage() -{ - printf("Usage:\n\n"); - printf("cmannotifyd [options]\n\n"); - printf("Options:\n\n"); - printf(" -f Do not fork in background\n"); - printf(" -d Enable debugging output\n"); - printf(" -r Run Real Time priority\n"); - printf(" -h This help\n"); - printf(" -V Print program version information\n"); - return; -} - -static void read_arguments(int argc, char **argv) -{ - int cont = 1; - int optchar; - - while (cont) { - optchar = getopt(argc, argv, OPTION_STRING); - - switch (optchar) { - - case 'd': - debug = 1; - break; - - case 'f': - daemonize = 0; - break; - - case 'r': - rr = 1; - break; - - case 'h': - print_usage(); - exit(EXIT_SUCCESS); - break; - - case 'V': - printf("cmannotifyd %s (built %s %s)\n%s\n", - RELEASE_VERSION, __DATE__, __TIME__, - REDHAT_COPYRIGHT); - exit(EXIT_SUCCESS); - break; - - case EOF: - cont = 0; - break; - - default: - fprintf(stderr, "unknown option: %c\n", optchar); - print_usage(); - exit(EXIT_FAILURE); - break; - - } - - } -} - -static void lockfile(void) -{ - int fd, error; - struct flock lock; - char buf[128]; - - memset(buf, 0, 128); - - fd = open(LOCKFILE_NAME, O_CREAT | O_WRONLY, - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (fd < 0) { - fprintf(stderr, "cannot open/create lock file %s\n", - LOCKFILE_NAME); - exit(EXIT_FAILURE); - } - - 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) { - fprintf(stderr, "cmannotifyd is already running\n"); - exit(EXIT_FAILURE); - } - - error = ftruncate(fd, 0); - if (error) { - fprintf(stderr, "cannot clear lock file %s\n", LOCKFILE_NAME); - exit(EXIT_FAILURE); - } - - sprintf(buf, "%d\n", getpid()); - - error = write(fd, buf, strlen(buf)); - if (error <= 0) { - fprintf(stderr, "cannot write lock file %s\n", LOCKFILE_NAME); - exit(EXIT_FAILURE); - } -} - -static void sigterm_handler(int sig) -{ - daemon_quit = 1; -} - -static void set_oom_adj(int val) -{ - FILE *fp; - - fp = fopen("/proc/self/oom_adj", "w"); - if (!fp) - return; - - fprintf(fp, "%i", val); - fclose(fp); -} - -static void set_scheduler(void) -{ - struct sched_param sched_param; - int rv; - - rv = sched_get_priority_max(SCHED_RR); - if (rv != -1) { - sched_param.sched_priority = rv; - rv = sched_setscheduler(0, SCHED_RR, &sched_param); - if (rv == -1) - logt_print(LOG_WARNING, - "could not set SCHED_RR priority %d err %d", - sched_param.sched_priority, errno); - } else { - logt_print(LOG_WARNING, - "could not get maximum scheduler priority err %d", - errno); - } -} - -static void init_logging(int reconf) -{ - int ccs_handle; - int mode = - LOG_MODE_OUTPUT_FILE | LOG_MODE_OUTPUT_SYSLOG_THREADED | - LOG_MODE_FILTER_DEBUG_FROM_SYSLOG; - int facility = SYSLOGFACILITY; - int priority = SYSLOGLEVEL; - char file[PATH_MAX]; - - memset(file, 0, PATH_MAX); - sprintf(file, LOGDIR "/cmannotifyd.log"); - - ccs_handle = ccs_connect(); - if (ccs_handle > 0) { - ccs_read_logging(ccs_handle, "CMANNOTIFYD", &debug, &mode, - &facility, &priority, file); - ccs_disconnect(ccs_handle); - } - - if (!daemonize) - mode |= LOG_MODE_OUTPUT_STDERR; - - if (!reconf) - logt_init("CMANNOTIFYD", mode, facility, priority, file); - else - logt_conf("CMANNOTIFYD", mode, facility, priority, file); -} - -static void dispatch_notification(char *str, int *quorum) -{ - char *envp[MAX_ARGS]; - char *argv[MAX_ARGS]; - int envptr = 0; - int argvptr = 0; - char scratch[PATH_MAX]; - pid_t notify_pid; - int pidstatus; - - if (!str) - return; - - /* pass notification type */ - snprintf(scratch, sizeof(scratch), "CMAN_NOTIFICATION=%s", str); - envp[envptr++] = strdup(scratch); - - if (quorum) { - snprintf(scratch, sizeof(scratch), "CMAN_NOTIFICATION_QUORUM=%d", *quorum); - envp[envptr++] = strdup(scratch); - } - - if (debug) - envp[envptr++] = strdup("CMAN_NOTIFICATION_DEBUG=1"); - - envp[envptr++] = NULL; - - argv[argvptr++] = "cman_notify"; - - argv[argvptr++] = NULL; - - switch ( (notify_pid = fork()) ) - { - case -1: - /* unable to fork */ - exit(EXIT_FAILURE); - break; - - case 0: /* child */ - execve(SBINDIR "/cman_notify", argv, envp); - /* unable to execute cman_notify */ - exit(EXIT_FAILURE); - break; - - default: /* parent */ - waitpid(notify_pid, &pidstatus, 0); - break; - } - -} - -static void cman_callback(cman_handle_t ch, void *private, int reason, int arg) -{ - char *str = NULL; - - switch (reason) { - case CMAN_REASON_TRY_SHUTDOWN: - logt_print(LOG_DEBUG, "Received a cman shutdown request\n"); - cman_replyto_shutdown(ch, 1); /* allow cman to shutdown */ - str = "CMAN_REASON_TRY_SHUTDOWN"; - dispatch_notification(str, 0); - break; - case CMAN_REASON_STATECHANGE: - logt_print(LOG_DEBUG, - "Received a cman statechange notification\n"); - str = "CMAN_REASON_STATECHANGE"; - dispatch_notification(str, &arg); - break; - case CMAN_REASON_CONFIG_UPDATE: - logt_print(LOG_DEBUG, - "Received a cman config update notification\n"); - init_logging(1); - str = "CMAN_REASON_CONFIG_UPDATE"; - dispatch_notification(str, 0); - break; - } -} - -static void byebye_cman() -{ - if (!cman_handle) - return; - - cman_finish(cman_handle); - cman_handle = NULL; -} - -static void setup_cman(int forever) -{ - int init = 0, active = 0; - -retry_init: - cman_handle = cman_init(NULL); - if (!cman_handle) { - if ((init++ < 5) || (forever)) { - if (daemon_quit) - goto out; - - sleep(1); - goto retry_init; - } - logt_print(LOG_CRIT, "cman_init error %d\n", errno); - exit(EXIT_FAILURE); - } - -retry_active: - if (!cman_is_active(cman_handle)) { - if ((active++ < 5) || (forever)) { - if (daemon_quit) - goto out; - - sleep(1); - goto retry_active; - } - logt_print(LOG_CRIT, "cman_is_active error %d\n", errno); - cman_finish(cman_handle); - exit(EXIT_FAILURE); - } - - if (cman_start_notification(cman_handle, cman_callback) < 0) { - logt_print(LOG_CRIT, "cman_start_notification error %d\n", errno); - cman_finish(cman_handle); - exit(EXIT_FAILURE); - } - - return; - -out: - byebye_cman(); - exit(EXIT_SUCCESS); -} - -static void loop() -{ - int rv; - - for (;;) { - rv = cman_dispatch(cman_handle, CMAN_DISPATCH_ONE); - if (rv == -1 && errno == EHOSTDOWN) { - byebye_cman(); - logt_print(LOG_DEBUG, "waiting for cman to reappear..\n"); - setup_cman(1); - logt_print(LOG_DEBUG, "cman is back..\n"); - } - - if (daemon_quit) { - logt_print(LOG_DEBUG, "shutting down...\n"); - byebye_cman(); - exit(EXIT_SUCCESS); - } - - sleep(1); - } -} - -int main(int argc, char **argv) -{ - - read_arguments(argc, argv); - lockfile(); - - if (daemonize) { - if (daemon(0, 0) < 0) { - perror("Unable to daemonize"); - exit(EXIT_FAILURE); - } - } - - init_logging(0); - signal(SIGTERM, sigterm_handler); - set_oom_adj(-16); - if (rr) - set_scheduler(); - - setup_cman(0); - loop(); - - return 0; -} diff --git a/cman/qdisk/Makefile b/cman/qdisk/Makefile deleted file mode 100644 index 8c90001..0000000 --- a/cman/qdisk/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -TARGET1= qdiskd -TARGET2= mkqdisk - -SBINDIRT=${TARGET1} ${TARGET2} - -all: depends ${TARGET1} ${TARGET2} - -include ../../make/defines.mk -include $(OBJDIR)/make/cobj.mk -include $(OBJDIR)/make/clean.mk -include $(OBJDIR)/make/install.mk -include $(OBJDIR)/make/uninstall.mk - -CFLAGS += -D_GNU_SOURCE -CFLAGS += -Werror -Wstrict-prototypes -Wshadow -CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${corosyncincdir} -CFLAGS += -I$(S) -CFLAGS += -I${incdir} - -LDFLAGS += -L${corosynclibdir} -llogsys -lpthread -LDFLAGS += -L${libdir} - -EXTRA_LDFLAGS += -L${cmanlibdir} -L${ccslibdir} -lcman -lccs - -OBJS1= main.o \ - score.o \ - bitmap.o \ - daemon_init.o - -OBJS2= mkqdisk.o - -SHAREDOBJS= disk.o \ - crc32.o \ - disk_util.o \ - proc.o \ - scandisk.o - -${TARGET1}: ${SHAREDOBJS} ${OBJS1} - $(CC) -o $@ $^ $(EXTRA_LDFLAGS) $(LDFLAGS) - -${TARGET2}: ${SHAREDOBJS} ${OBJS2} - $(CC) -o $@ $^ $(LDFLAGS) - -depends: - $(MAKE) -C ../lib all - -clean: generalclean - --include $(OBJS1:.o=.d) --include $(OBJS2:.o=.d) --include $(SHAREDOBJS:.o=.d) 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 37ff969..0000000 --- a/cman/qdisk/bitmap.c +++ /dev/null @@ -1,88 +0,0 @@ -/** @file - * Bitmap and membership mask handling routines. - */ -#include - - -/** - * 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/crc32.c b/cman/qdisk/crc32.c deleted file mode 100644 index 597d0b7..0000000 --- a/cman/qdisk/crc32.c +++ /dev/null @@ -1,97 +0,0 @@ -/** @file - * Calculates CRC32s on data. - */ - -#include -#include -#include -#include -#include - -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; -} diff --git a/cman/qdisk/daemon_init.c b/cman/qdisk/daemon_init.c deleted file mode 100644 index cc6f90e..0000000 --- a/cman/qdisk/daemon_init.c +++ /dev/null @@ -1,227 +0,0 @@ -/** @file - * daemon_init function, does sanity checks and calls daemon(). - * - * Author: Jeff Moyer - */ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * This should ultimately go in a header file. - */ -void daemon_init(char *prog); -int check_process_running(char *prog, pid_t * pid); - -/* - * Local prototypes. - */ -static void update_pidfile(char *prog); -static int setup_sigmask(void); - -static 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; - } - - ret = fscanf(fp, "%d\n", &oldpid); - fclose(fp); - - if ((ret == EOF) || (ret != 1)) - return 0; - - 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) { - log_printf(LOG_ERR, - "daemon_init: Sorry, only root wants to run this.\n"); - exit(1); - } - - if (check_process_running(prog, &pid) && (pid != getpid())) { - log_printf(LOG_ERR, - "daemon_init: Process \"%s\" already running.\n", - prog); - exit(1); - } - if (setup_sigmask() < 0) { - log_printf(LOG_ERR, "daemon_init: Unable to set signal mask.\n"); - exit(1); - } - - if(daemon(0, 0)) { - log_printf(LOG_ERR, "daemon_init: Unable to daemonize.\n"); - exit(1); - } - - - update_pidfile(prog); -} diff --git a/cman/qdisk/disk.c b/cman/qdisk/disk.c deleted file mode 100644 index 972bbf6..0000000 --- a/cman/qdisk/disk.c +++ /dev/null @@ -1,757 +0,0 @@ -/** @file - * Single-block Raw/Direct I/O Functions - */ -/* - * author: Tim Burke - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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) { - log_printf(LOG_ERR, "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) { - log_printf(LOG_ERR, "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) { - log_printf(LOG_DEBUG, "Header CRC32 mismatch; Exp: 0x%08x " - "Got: 0x%08x\n", bkupcrc, crc); - return -1; - } - - /* - * Verify the magic number. - */ - if (hdr->h_magic != SHARED_HEADER_MAGIC) { - log_printf(LOG_DEBUG, "Magic mismatch; Exp: 0x%08x " - "Got: 0x%08x\n", SHARED_HEADER_MAGIC, hdr->h_magic); - 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) { - log_printf(LOG_DEBUG, "Data CRC32 mismatch; Exp: 0x%08x " - "Got: 0x%08x\n", hdr->h_dcrc, crc); - 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) { - log_printf(LOG_ERR, "qdisk_open: ioctl(BLKSSZGET)"); - close(disk->d_fd); - return -1; - } - - disk->d_blksz = ssz; - disk->d_pagesz = sysconf(_SC_PAGESIZE); - - /* Check to verify that the partition is large enough.*/ - ret = lseek(disk->d_fd, END_OF_DISK(disk->d_blksz), SEEK_SET); - if (ret < 0) { - log_printf(LOG_DEBUG, "open_partition: seek"); - close(disk->d_fd); - return -1; - } - - if (ret < END_OF_DISK(disk->d_blksz)) { - log_printf(LOG_ERR, "Partition %s too small\n", name); - errno = EINVAL; - close(disk->d_fd); - return -1; - } - - /* Set close-on-exec bit */ - ret = fcntl(disk->d_fd, F_GETFD, 0); - if (ret < 0) { - log_printf(LOG_ERR, "open_partition: fcntl(F_GETFD)"); - close(disk->d_fd); - return -1; - } - - ret |= FD_CLOEXEC; - if (fcntl(disk->d_fd, F_SETFD, ret) < 0) { - log_printf(LOG_ERR, "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) { - log_printf(LOG_ERR, "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; -*/ - log_printf(LOG_WARNING, "Warning: %s is not a block device\n", - name); - } - - /* - * Verify read/write permission. - */ - if (qdisk_open(name, &disk) < 0) { - log_printf(LOG_DEBUG, "%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; - - ret = lseek(disk->d_fd, readOffset, SEEK_SET); - if (ret != readOffset) { - log_printf(LOG_DEBUG, - "diskRawReadShadow: can't seek to offset %d.\n", - (int) readOffset); - errno = ENODATA; - return -1; - } - - ret = diskRawRead(disk, buf, len); - if (ret != len) { - log_printf(LOG_DEBUG, "diskRawReadShadow: aligned read " - "returned %d, not %d.\n", ret, len); - 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)) { - log_printf(LOG_DEBUG, "diskRawReadShadow: bad CRC32, " - "offset = %d len = %d\n", - (int) readOffset, len); - 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) -{ - void *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. */ - return (read(disk->d_fd, buf, len)); - } - - if (len > disk->d_blksz) { - log_printf(LOG_ERR, - "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; - } - - readret = read(disk->d_fd, alignedBuf, readlen); - if (readret > 0) { - if (readret > len) { - memcpy(alignedBuf, buf, len); - readret = len; - } else { - memcpy(alignedBuf, buf, readret); - } - } - - free(alignedBuf); - if (readret != len) { - log_printf(LOG_ERR, "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) -{ - void *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. */ - return (write(disk->d_fd, buf, len)); - } - - if (len > disk->d_blksz) { - log_printf(LOG_ERR, - "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) { - log_printf(LOG_ERR, - "diskRawWrite: not setup for larger than %d.\n", - (int)disk->d_blksz); - return (-1); - } - - memcpy(buf, alignedBuf, len); - ret = write(disk->d_fd, alignedBuf, writelen); - if (ret > len) { - ret = len; - } - - free(alignedBuf); - if (ret != len) { - log_printf(LOG_ERR, "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)) { - log_printf(LOG_ERR, - "diskRawWriteShadow: writeOffset=%08x, " - "len=%08x.\n", (int)writeOffset, len); - return (-1); - } - - retval_seek = lseek(disk->d_fd, writeOffset, SEEK_SET); - if (retval_seek != writeOffset) { - log_printf(LOG_ERR, - "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) { - log_printf(LOG_ERR, "%s: %s\n", __FUNCTION__, - strerror(errno)); - } - log_printf(LOG_ERR, - "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; - void *ptr; - 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); - - ptr = NULL; - rv = posix_memalign((void **)&ptr, disk->d_pagesz, disk->d_blksz); - if (rv < 0) - return -1; - - if (ptr == NULL) - return -1; - - hdrp = (shared_header_t *)ptr; - 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; - void *ptr; - 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))) { - log_printf(LOG_ERR, "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); - - ptr = NULL; - rv = posix_memalign((void **)&ptr, disk->d_pagesz, total); - if (rv < 0) { - log_printf(LOG_ERR, "posix_memalign"); - return -1; - } - - /* - * Copy the data into our new buffer - */ - hdrp = (shared_header_t *)ptr; - 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) - log_printf(LOG_ERR, "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) { - log_printf(LOG_ERR, "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) { - log_printf(LOG_ERR, "time"); - return -1; - } - - qh.qh_magic = HEADER_MAGIC_NUMBER; - qh.qh_blksz = disk->d_blksz; - qh.qh_kernsz = 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) { - log_printf(LOG_DEBUG, "qdisk_verify"); - return -1; - } - - ret = qdisk_open(partname, &disk); - if (ret < 0) { - log_printf(LOG_ERR, "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 27a4db4..0000000 --- a/cman/qdisk/disk.h +++ /dev/null @@ -1,282 +0,0 @@ -/** - @file Main quorum daemon include file - */ -#ifndef _QUORUM_DISK_H -#define _QUORUM_DISK_H - -#include -#include -#include -#include - -#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 -} 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_kernsz; // Ingored -} quorum_header_t; - -#define swab_quorum_header_t(ptr) \ -{\ - swab32((ptr)->qh_magic); \ - swab32((ptr)->qh_version); \ - swab32((ptr)->qh_blksz); \ - swab32((ptr)->qh_kernsz); \ - 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; - int qc_max_error_cycles; - int qc_pad; - disk_node_state_t qc_disk_status; - disk_node_state_t qc_status; - int qc_master; /* Master?! */ - int qc_status_sock; - run_flag_t qc_flags; - cman_handle_t qc_ch; - char *qc_device; - char *qc_label; - char *qc_status_file; - char *qc_cman_label; - char *qc_status_sockname; -} 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_init(qd_ctx *ctx, cman_handle_t ch, int me); -void qd_destroy(qd_ctx *ctx); - -/* proc.c */ -int find_partitions(const char *label, - char *devname, size_t devlen, int print); -int check_device(char *device, char *label, 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 36c315a..0000000 --- a/cman/qdisk/disk_util.c +++ /dev/null @@ -1,260 +0,0 @@ -/** - @file Misc. Quorum daemon context utilities / high-level functions - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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__) - 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 - */ -static 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) { - log_printf(LOG_ERR, "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; -} - - -/** - Generate a token based on the current system time. - */ -static 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; - ctx->qc_status_sock = -1; - - 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/main.c b/cman/qdisk/main.c deleted file mode 100644 index 4dbe511..0000000 --- a/cman/qdisk/main.c +++ /dev/null @@ -1,1707 +0,0 @@ -/** - @file Main loop / functions for disk-based quorum daemon. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "score.h" -#if (!defined(LIBCMAN_VERSION) || \ - (defined(LIBCMAN_VERSION) && LIBCMAN_VERSION < 2)) -#include -#endif - -/* from daemon_init.c */ -int daemon_init(char *); -int check_process_running(char *, pid_t *); - -/* from proc.c */ -char *state_str(disk_node_state_t s); - -/* - 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; -static 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. - */ -static inline int -state_run(disk_node_state_t state) -{ - return (state >= S_INIT ? state : 0); -} - - -/** - Clear out / initialize node info block. - */ -static 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. - */ -static 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: - log_printf(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) { - log_printf(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) { - log_printf(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. - */ -static 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) { - log_printf(LOG_NOTICE, "Node %d evicted\n", - ni[x].ni_status.ps_nodeid); - } else { - /* State == S_NONE or incarnation change */ - log_printf(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) { - log_printf(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_status.ps_incarnation; - - /* - Write eviction notice if we're the master. - */ - if (ctx->qc_status == S_MASTER) { - log_printf(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) { - log_printf(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)) { - log_printf(LOG_CRIT, "Node %d is undead.\n", - ni[x].ni_status.ps_nodeid); - - log_printf(LOG_ALERT, - "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); - ni[x].ni_status.ps_state = S_EVICT; - - /* XXX Need to fence it again */ - if (ctx->qc_flags & RF_ALLOW_KILL) { - log_printf(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; - log_printf(LOG_DEBUG, "Node %d is UP\n", - ni[x].ni_status.ps_nodeid); - ni[x].ni_incarnation = - ni[x].ni_status.ps_incarnation; - 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) { - log_printf(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; - } - - /* - 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 - */ -static 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) { - log_printf(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. - */ -static 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 = 0; - - log_printf(LOG_INFO, "Quorum Daemon Initializing\n"); - - if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0) { - log_printf(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) { - log_printf(LOG_CRIT, "Failed to open %s: %s\n", ctx->qc_device, - strerror(errno)); - return -1; - } - - log_printf(LOG_DEBUG, "I/O Size: %lu Page Size: %lu\n", - (unsigned long)ctx->qc_disk.d_blksz, (unsigned long)ctx->qc_disk.d_pagesz); - - if (h && maxh) { - start_score_thread(ctx, h, maxh); - } else { - log_printf(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) { - log_printf(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) { - log_printf(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); - log_printf(LOG_INFO, "Initial score %d/%d\n", score, maxscore); - if ((ctx->qc_flags & RF_STOP_CMAN) && (score < score_req)) - return -1; - log_printf(LOG_INFO, "Initialization complete\n"); - - return 0; -} - - -/** - Vote for a master if it puts a bid in. - */ -static 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. - */ -static 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. - */ -static 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; -} - -static 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"); -} - - -static 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= 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; xqc_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); -} - -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) { - log_printf(LOG_WARNING, "set_priority [%s] failed: %s\n", func, - strerror(errno)); - } -} - - -static 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; -} - - -static 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, errors, error_cycles = 0; - memb_mask_t mask, master_mask; - struct timeval maxtime, oldtime, newtime, diff, sleeptime, interval; - - 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; - - get_my_score(&score, &score_max); - if (score_max < ctx->qc_scoremin) { - log_printf(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 */ - errors = read_node_blocks(ctx, ni, max); - - /* 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) { - log_printf(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) { - log_printf(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) { - log_printf(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) { - log_printf(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. - */ - - log_printf(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; - - log_printf(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. */ - - log_printf(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) { - log_printf(LOG_ERR, "cman_dispatch: %s\n", - strerror(errno)); - log_printf(LOG_ERR, - "Halting qdisk operations\n"); - return -1; - } - check_cman(ctx, mask, master_mask); - if (!errors) - 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) { - log_printf(LOG_ERR, "cman_dispatch: %s\n", - strerror(errno)); - log_printf(LOG_ERR, - "Halting qdisk operations\n"); - return -1; - } - if (!errors) - 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) { - log_printf(LOG_ERR, "Error writing to quorum disk\n"); - errors++; /* this value isn't really used - at this point */ - } - - /* 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); - _diff_tv(&diff, &oldtime, &newtime); - - /* - * Reboot if we didn't send a heartbeat in interval*TKO_COUNT - */ - if (_cmp_tv(&maxtime, &diff) == 1 && - ctx->qc_flags & RF_PARANOID) { - log_printf(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 { - log_printf(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)); - } - - if (errors && ctx->qc_max_error_cycles) { - ++error_cycles; - if (error_cycles >= ctx->qc_max_error_cycles) { - log_printf(LOG_ALERT, - "Too many I/O errors; giving up.\n"); - _running = 0; - } - } else { - error_cycles = 0; - } - - /* Could hit a watchdog timer here if we wanted to */ - if (_running) - select(0, NULL, NULL, NULL, &sleeptime); - } - - return !!errors; -} - - -/** - Tell the other nodes we're done (safely!). - */ -static 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) { - log_printf(LOG_WARNING, - "Error writing to quorum disk during logout\n"); - } - return 0; -} - - -/** - Grab logsys configuration data from libccs - */ -static int -get_logsys_config_data(int *debug) -{ - int ccsfd = -1, loglevel = SYSLOGLEVEL, facility = SYSLOGFACILITY; - char *val = NULL, *error = NULL; - unsigned int logmode; - int global_debug = 0; - - log_printf(LOG_DEBUG, "Loading logsys configuration information\n"); - - ccsfd = ccs_connect(); - if (ccsfd < 0) { - log_printf(LOG_CRIT, "Connection to CCSD failed; cannot start\n"); - return -1; - } - - logmode = logsys_config_mode_get(); - - if (!*debug) { - if (ccs_get(ccsfd, "/cluster/logging/@debug", &val) == 0) { - if(!strcmp(val, "on")) { - global_debug = 1; - } else - if(!strcmp(val, "off")) { - global_debug = 0; - } else - log_printf(LOG_ERR, "global debug: unknown value\n"); - free(val); - val = NULL; - } - - if (ccs_get(ccsfd, "/cluster/logging/logger_subsys[@subsys=\"QDISK\"]/@debug", &val) == 0) { - if(!strcmp(val, "on")) { - *debug = 1; - } else - if(!strcmp(val, "off")) { /* debug from cmdline/envvars override config */ - *debug = 0; - } else - log_printf(LOG_ERR, "subsys debug: unknown value: %s\n", val); - free(val); - val = NULL; - } else - *debug = global_debug; /* global debug overrides subsystem only if latter is not specified */ - - if (ccs_get(ccsfd, "/cluster/logging/logger_subsys[@subsys=\"QDISK\"]/@syslog_level", &val) == 0) { - loglevel = logsys_priority_id_get (val); - if (loglevel < 0) - loglevel = SYSLOGLEVEL; - - if (!*debug) { - if (loglevel == LOG_LEVEL_DEBUG) - *debug = 1; - - logsys_config_priority_set (loglevel); - } - - free(val); - val = NULL; - } else - if (ccs_get(ccsfd, "/cluster/quorumd/@log_level", &val) == 0) { /* check backward compat options */ - loglevel = logsys_priority_id_get (val); - if (loglevel < 0) - loglevel = SYSLOGLEVEL; - - log_printf(LOG_ERR, "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; - ctx->qc_max_error_cycles = 0; - - /* 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 */ - 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; - } - - /* 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 status socket */ - snprintf(query, sizeof(query), "/cluster/quorumd/@status_sock"); - if (ccs_get(ccsfd, query, &val) == 0) { - ctx->qc_status_sockname = 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: - log_printf(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); - } - - - /* - * 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); - } - - - /* - * How many consecutive error cycles do we allow before - * giving up? - */ - /* default = no max */ - snprintf(query, sizeof(query), "/cluster/quorumd/@max_error_cycles"); - if (ccs_get(ccsfd, query, &val) == 0) { - ctx->qc_max_error_cycles = atoi(val); - if (ctx->qc_max_error_cycles <= 0) - ctx->qc_max_error_cycles = 0; - free(val); - } - - *cfh = configure_heuristics(ccsfd, h, maxh); - - log_printf(LOG_DEBUG, - "Quorum Daemon: %d heuristics, %d interval, %d tko, %d votes\n", - *cfh, ctx->qc_interval, ctx->qc_tko, ctx->qc_votes); - log_printf(LOG_DEBUG, "Run Flags: %08x\n", ctx->qc_flags); - - ccs_disconnect(ccsfd); - - return 0; -} - - -static void -check_stop_cman(qd_ctx *ctx) -{ - if (!(ctx->qc_flags & RF_STOP_CMAN)) - return; - - log_printf(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 - log_printf(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, ret = -1; - qd_ctx ctx; - cman_handle_t ch = NULL; - node_info_t ni[MAX_NODES_DISK]; - struct h_data h[10]; - int debug = 0, foreground = 0, trylater = 0; - char device[128]; - pid_t pid; - quorum_header_t qh; - - logsys_init("QDISK", LOG_MODE_OUTPUT_STDERR | LOG_MODE_OUTPUT_SYSLOG_THREADED | LOG_MODE_OUTPUT_FILE | LOG_MODE_FILTER_DEBUG_FROM_SYSLOG | LOG_MODE_BUFFER_BEFORE_CONFIG, SYSLOGFACILITY, SYSLOGLEVEL, LOGDIR "/qdisk.log"); - - if (check_process_running(argv[0], &pid) && pid !=getpid()) { - printf("QDisk services already running\n"); - return 0; - } - - while ((rv = getopt(argc, argv, "fdQs")) != EOF) { - switch (rv) { - case 'd': - debug = 1; - break; - case 'f': - foreground = 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(getenv("QDISK_DEBUGLOG")) - debug = 1; - - if(debug) - logsys_config_priority_set (LOG_LEVEL_DEBUG); - - trylater = get_logsys_config_data(&debug); - - if (trylater) - logsys_config_mode_set (LOG_MODE_OUTPUT_STDERR | LOG_MODE_OUTPUT_SYSLOG_THREADED | LOG_MODE_OUTPUT_FILE | LOG_MODE_FLUSH_AFTER_CONFIG); - -#if (defined(LIBCMAN_VERSION) && LIBCMAN_VERSION >= 2) - ch = cman_admin_init(NULL); -#else - ch = cman_init(NULL); -#endif - if (!ch) { - if (!foreground && !forked) { - if (daemon_init(argv[0]) < 0) - goto out; - else - forked = 1; - } - - log_printf(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) { - if (daemon_init(argv[0]) < 0) - goto out; - else - forked = 1; - } - sleep(5); - } - - qd_init(&ctx, ch, me.cn_nodeid); - - signal(SIGINT, int_handler); - signal(SIGTERM, int_handler); - - if (get_config_data(&ctx, h, 10, &cfh, debug, trylater) < 0) { - log_printf(LOG_CRIT, "Configuration failed\n"); - check_stop_cman(&ctx); - goto out; - } - - if (ctx.qc_label) { - ret = find_partitions(ctx.qc_label, device, sizeof(device), 0); - if (ret < 0) { - log_printf(LOG_CRIT, "Unable to match label" - " '%s' to any device\n", - ctx.qc_label); - check_stop_cman(&ctx); - goto out; - } - /* XXX Multiple matches: do we care? */ - - if (ctx.qc_device) - free(ctx.qc_device); - - ctx.qc_device = strdup(device); - - log_printf(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, &qh, 0) != 0) { - log_printf(LOG_CRIT, - "Specified partition %s does not have a " - "qdisk label\n", ctx.qc_device); - check_stop_cman(&ctx); - goto out; - } - - if (qh.qh_version == VERSION_MAGIC_V2 && - qh.qh_blksz != qh.qh_kernsz) { - log_printf(LOG_CRIT, - "Specified device %s does not match kernel's " - "reported sector size (%lu != %lu)\n", - ctx.qc_device, - (unsigned long)qh.qh_blksz, - (unsigned long)qh.qh_kernsz); - check_stop_cman(&ctx); - goto out; - } - } - - if (!foreground && !forked) { - if (daemon_init(argv[0]) < 0) - goto out; - } - - set_priority(ctx.qc_sched, ctx.qc_sched_prio); - - if (quorum_init(&ctx, ni, MAX_NODES_DISK, h, cfh) < 0) { - log_printf(LOG_CRIT, "Initialization failed\n"); - check_stop_cman(&ctx); - goto out; - } - - ret = 0; - - if (!_running) - goto out; - - 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) { - log_printf(LOG_CRIT, - "Could not register %s with CMAN; " - "return = %d; error = %s\n", - ctx.qc_device, rv, strerror(errno)); - goto out; - } - */ - if (quorum_loop(&ctx, ni, MAX_NODES_DISK) == 0) - cman_unregister_quorum_device(ctx.qc_ch); - - quorum_logout(&ctx); - /* free cman handle to avoid leak in cman */ -out: - cman_finish(ctx.qc_ch); - qd_destroy(&ctx); - logsys_exit(); - return ret; -} - diff --git a/cman/qdisk/mkqdisk.c b/cman/qdisk/mkqdisk.c deleted file mode 100644 index e1afe6c..0000000 --- a/cman/qdisk/mkqdisk.c +++ /dev/null @@ -1,94 +0,0 @@ -/** - @file Quorum disk utility - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int -main(int argc, char **argv) -{ - char device[128]; - char *newdev = NULL, *newlabel = NULL; - int rv, verbose_level = 1; - - logsys_init("QDISK", LOG_MODE_OUTPUT_STDERR | LOG_MODE_NOSUBSYS, SYSLOGFACILITY, SYSLOGLEVEL, NULL); - - printf("mkqdisk v" RELEASE_VERSION "\n\n"); - - /* XXX this is horrible but we need to prioritize options as long as - * we can't queue messages properly - */ - while ((rv = getopt(argc, argv, "Ldf:c:l:h")) != EOF) { - switch (rv) { - case 'd': - ++verbose_level; - /* Workaround a bug in logsys new API. - * logsys segfaults if our first operation is to set the priority - * because the logsys_config_priority_set is buggy. - * Temporary use the direct call while fix is applied upstream and propagated - */ - // logsys_config_priority_set(LOG_LEVEL_DEBUG); - _logsys_config_priority_set(0, LOG_LEVEL_DEBUG); - break; - } - } - - /* reset the option index to reparse */ - optind = 0; - - while ((rv = getopt(argc, argv, "Ldf:c:l:h")) != EOF) { - switch (rv) { - case 'd': - /* processed above, needs to be here for compat */ - break; - case 'L': - /* List */ - return find_partitions(NULL, NULL, 0, verbose_level); - case 'f': - return find_partitions( optarg, device, - sizeof(device), verbose_level); - case 'c': - newdev = optarg; - break; - case 'l': - newlabel = optarg; - break; - case 'h': - printf("usage: mkqdisk -L | -f