Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
Gitweb: http://git.fedorahosted.org/git/?p=dlm.git;a=commitdiff;h=d2ef4558785c33551…
Commit: d2ef4558785c33551e4614241a6266822b28e30c
Parent: da90c9bfee84aff6b55964f4db5a19086f4db963
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Feb 28 15:46:42 2017 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Feb 28 15:46:42 2017 -0600
source moved to https://pagure.io/dlm
---
README.rst | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/README.rst b/README.rst
index b6b76b5..40da15b 100644
--- a/README.rst
+++ b/README.rst
@@ -1,2 +1,3 @@
+| ``See https://pagure.io/dlm``
| ``See dlm_controld(8) at dlm.git/dlm_controld/dlm_controld.8``
| ``See dlm.conf(5) at dlm.git/dlm_controld/dlm.conf.5``
Gitweb: http://git.fedorahosted.org/git/?p=dlm.git;a=commitdiff;h=da90c9bfee84aff6b…
Commit: da90c9bfee84aff6b55964f4db5a19086f4db963
Parent: e9302c077724a9de814022a48438966ffc4fa89c
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Feb 23 11:36:09 2017 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Feb 23 11:36:09 2017 -0600
add readme
---
README.rst | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..b6b76b5
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,2 @@
+| ``See dlm_controld(8) at dlm.git/dlm_controld/dlm_controld.8``
+| ``See dlm.conf(5) at dlm.git/dlm_controld/dlm.conf.5``
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=183aa4fae1f34…
Commit: 183aa4fae1f34ca594c4e782948bfd4790ba5b3d
Parent: aabd30fca943f8c865691bbc76ddb045c1ec0a33
Author: Jan Pokorn�� <jpokorny(a)redhat.com>
AuthorDate: Tue Feb 28 02:31:57 2017 +0100
Committer: Jan Pokorn�� <jpokorny(a)redhat.com>
CommitterDate: Tue Feb 28 02:31:57 2017 +0100
fedorahosted.org discontinued
Signed-off-by: Jan Pokorn�� <jpokorny(a)redhat.com>
---
README | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/README b/README
index d2d00c9..ded30cd 100644
--- a/README
+++ b/README
@@ -1,3 +1,3 @@
-cluster.git master branch is no longer actively developed.
+DISCONTINUED ON FEDORAHOSTED.ORG
-Please refer to STABLE31 branch or RHEL6 branch for stable releases.
+New home: https://pagure.io/linux-cluster/cluster
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=6d44fe232bbe7…
Commit: 6d44fe232bbe709ecb405f6ae455efe47c336cd0
Parent: 1ac358de4743de3bc401eac639ca88252231f3d9
Author: Jan Pokorn�� <jpokorny(a)redhat.com>
AuthorDate: Tue Feb 28 02:32:10 2017 +0100
Committer: Jan Pokorn�� <jpokorny(a)redhat.com>
CommitterDate: Tue Feb 28 02:32:10 2017 +0100
fedorahosted.org discontinued
Signed-off-by: Jan Pokorn�� <jpokorny(a)redhat.com>
---
Makefile | 69 -
README | 3 +
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 | 33 -
cman/cman_tool/cman_tool.h | 109 -
cman/cman_tool/join.c | 396 ---
cman/cman_tool/main.c | 1297 ----------
cman/daemon/Makefile | 41 -
cman/daemon/ais.c | 378 ---
cman/daemon/ais.h | 14 -
cman/daemon/barrier.c | 469 ----
cman/daemon/barrier.h | 6 -
cman/daemon/cman-preconfig.c | 1781 -------------
cman/daemon/cman.h | 19 -
cman/daemon/cmanconfig.c | 312 ---
cman/daemon/cmanconfig.h | 3 -
cman/daemon/cnxman-private.h | 183 --
cman/daemon/cnxman-socket.h | 289 ---
cman/daemon/commands.c | 2459 ------------------
cman/daemon/commands.h | 37 -
cman/daemon/daemon.c | 528 ----
cman/daemon/daemon.h | 12 -
cman/daemon/fnvhash.c | 93 -
cman/daemon/fnvhash.h | 1 -
cman/daemon/list.h | 97 -
cman/daemon/nodelist.h | 91 -
cman/init.d/Makefile | 21 -
cman/init.d/cman.in | 1038 --------
cman/init.d/cman.init.defaults.in | 132 -
cman/lib/Makefile | 12 -
cman/lib/libcman.c | 1145 ---------
cman/lib/libcman.h | 457 ----
cman/lib/libcman.pc.in | 11 -
cman/man/Makefile | 17 -
cman/man/checkquorum.8 | 29 -
cman/man/cman.5 | 211 --
cman/man/cman_notify.8 | 17 -
cman/man/cman_tool.8 | 442 ----
cman/man/cmannotifyd.8 | 66 -
cman/man/mkqdisk.8 | 31 -
cman/man/qdisk.5 | 530 ----
cman/man/qdiskd.8 | 25 -
cman/notifyd/Makefile | 37 -
cman/notifyd/cman_notify.in | 40 -
cman/notifyd/main.c | 430 ----
cman/qdisk/Makefile | 52 -
cman/qdisk/bitmap.c | 91 -
cman/qdisk/daemon_init.c | 236 --
cman/qdisk/disk.c | 784 ------
cman/qdisk/disk.h | 298 ---
cman/qdisk/disk_util.c | 264 --
cman/qdisk/iostate.c | 154 --
cman/qdisk/iostate.h | 19 -
cman/qdisk/main.c | 2289 -----------------
cman/qdisk/mkqdisk.c | 102 -
cman/qdisk/platform.h | 40 -
cman/qdisk/proc.c | 262 --
cman/qdisk/scandisk.c | 782 ------
cman/qdisk/scandisk.h | 86 -
cman/qdisk/score.c | 488 ----
cman/qdisk/score.h | 47 -
cman/scripts/Makefile | 11 -
cman/scripts/checkquorum | 97 -
cman/scripts/checkquorum.wdmd | 104 -
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 | 378 ---
common/liblogthread/liblogthread.h | 19 -
common/liblogthread/liblogthread.pc.in | 11 -
config/Makefile | 4 -
config/libs/Makefile | 4 -
config/libs/libccsconfdb/Makefile | 24 -
config/libs/libccsconfdb/ccs.h | 16 -
config/libs/libccsconfdb/ccs_internal.h | 29 -
config/libs/libccsconfdb/extras.c | 454 ----
config/libs/libccsconfdb/fullxpath.c | 361 ---
config/libs/libccsconfdb/libccs.c | 660 -----
config/libs/libccsconfdb/libccs.pc.in | 11 -
config/libs/libccsconfdb/xpathlite.c | 454 ----
config/man/Makefile | 9 -
config/man/cluster.conf.5 | 237 --
config/plugins/Makefile | 4 -
config/plugins/ldap/99cluster.ldif | 1899 --------------
config/plugins/ldap/Makefile | 30 -
config/plugins/ldap/configldap.c | 295 ---
config/plugins/ldap/example.ldif | 137 -
config/plugins/ldap/ldap-base.csv | 352 ---
config/plugins/xml/Makefile | 27 -
config/plugins/xml/config.c | 149 --
config/tools/Makefile | 4 -
config/tools/ccs_tool/Makefile | 39 -
config/tools/ccs_tool/ccs_tool.c | 380 ---
config/tools/ccs_tool/editconf.c | 2395 ------------------
config/tools/ccs_tool/editconf.h | 18 -
config/tools/ldap/Makefile | 30 -
config/tools/ldap/confdb2ldif.c | 180 --
config/tools/ldap/rng2ldif/Makefile | 46 -
config/tools/ldap/rng2ldif/debug.h | 10 -
config/tools/ldap/rng2ldif/genclass.c | 106 -
config/tools/ldap/rng2ldif/ldaptypes.c | 53 -
config/tools/ldap/rng2ldif/ldaptypes.h | 8 -
config/tools/ldap/rng2ldif/name.c | 58 -
config/tools/ldap/rng2ldif/name.h | 6 -
config/tools/ldap/rng2ldif/rng2ldif.c | 242 --
config/tools/ldap/rng2ldif/tree.c | 469 ----
config/tools/ldap/rng2ldif/tree.h | 40 -
config/tools/ldap/rng2ldif/value-list.c | 206 --
config/tools/ldap/rng2ldif/value-list.h | 28 -
config/tools/ldap/rng2ldif/zalloc.c | 23 -
config/tools/ldap/rng2ldif/zalloc.h | 6 -
config/tools/man/Makefile | 14 -
config/tools/man/ccs_config_dump.8 | 35 -
config/tools/man/ccs_config_validate.8 | 56 -
config/tools/man/ccs_tool.8 | 151 --
config/tools/man/ccs_update_schema.8 | 29 -
config/tools/man/confdb2ldif.8 | 64 -
config/tools/xml/Makefile | 47 -
config/tools/xml/ccs_config_dump.c | 187 --
config/tools/xml/ccs_config_validate.in | 242 --
config/tools/xml/ccs_update_schema.in | 382 ---
config/tools/xml/cluster.rng.in.head | 1126 ---------
config/tools/xml/cluster.rng.in.tail | 1 -
configure | 686 -----
contrib/Makefile | 6 -
contrib/libaislock/Makefile | 15 -
contrib/libaislock/libaislock.c | 466 ----
contrib/libaislock/libaislock.h | 190 --
contrib/libaislock/libaislock.pc.in | 11 -
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 | 2 -
dlm/libdlm/Makefile | 81 -
dlm/libdlm/libdlm.c | 1485 -----------
dlm/libdlm/libdlm.h | 275 --
dlm/libdlm/libdlm.pc.in | 11 -
dlm/libdlm/libdlm_internal.h | 9 -
dlm/libdlm/libdlm_lt.pc.in | 11 -
dlm/libdlmcontrol/Makefile | 17 -
dlm/libdlmcontrol/libdlmcontrol.h | 90 -
dlm/libdlmcontrol/libdlmcontrol.pc.in | 11 -
dlm/libdlmcontrol/main.c | 419 ----
dlm/man/Makefile | 30 -
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 | 98 -
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 | 289 ---
dlm/tests/usertest/dlmtest2.c | 1454 -----------
dlm/tests/usertest/flood.c | 170 --
dlm/tests/usertest/joinleave.c | 62 -
dlm/tests/usertest/lstest.c | 326 ---
dlm/tests/usertest/lvb.c | 244 --
dlm/tests/usertest/pingtest.c | 343 ---
dlm/tests/usertest/sublocks.c | 178 --
dlm/tests/usertest/threads.c | 309 ---
dlm/tool/Makefile | 32 -
dlm/tool/main.c | 1324 ----------
doc/COPYING.applications | 339 ---
doc/COPYING.libraries | 510 ----
doc/COPYRIGHT | 141 --
doc/Makefile | 24 -
doc/README.licence | 33 -
doc/cluster.logrotate.in | 9 -
doc/cluster_conf.html | 1212 ---------
doc/cman_notify_template.sh | 57 -
doc/usage.txt | 67 -
fence/Makefile | 4 -
fence/fence_check/Makefile | 20 -
fence/fence_check/fence_check.in | 241 --
fence/fence_node/Makefile | 35 -
fence/fence_node/fence_node.c | 306 ---
fence/fence_tool/Makefile | 32 -
fence/fence_tool/fence_tool.c | 737 ------
fence/fenced/Makefile | 49 -
fence/fenced/config.c | 226 --
fence/fenced/config.h | 39 -
fence/fenced/cpg.c | 2510 -------------------
fence/fenced/dbus.c | 87 -
fence/fenced/fd.h | 299 ---
fence/fenced/fenced.h | 36 -
fence/fenced/group.c | 489 ----
fence/fenced/logging.c | 92 -
fence/fenced/main.c | 1092 --------
fence/fenced/member_cman.c | 416 ---
fence/fenced/recover.c | 477 ----
fence/include/linux_endian.h | 68 -
fence/include/list.h | 336 ---
fence/libfence/Makefile | 20 -
fence/libfence/agent.c | 1142 ---------
fence/libfence/libfence.h | 65 -
fence/libfence/libfence.pc.in | 11 -
fence/libfenced/Makefile | 14 -
fence/libfenced/libfenced.h | 53 -
fence/libfenced/libfenced.pc.in | 11 -
fence/libfenced/main.c | 323 ---
fence/man/Makefile | 10 -
fence/man/fence_check.8 | 65 -
fence/man/fence_node.8 | 127 -
fence/man/fence_tool.8 | 60 -
fence/man/fenced.8 | 353 ---
group/Makefile | 4 -
group/daemon/Makefile | 35 -
group/daemon/app.c | 1846 --------------
group/daemon/cman.c | 206 --
group/daemon/cpg.c | 1116 ---------
group/daemon/gd_internal.h | 325 ---
group/daemon/groupd.h | 13 -
group/daemon/joinleave.c | 165 --
group/daemon/logging.c | 60 -
group/daemon/main.c | 1074 --------
group/dlm_controld/Makefile | 52 -
group/dlm_controld/action.c | 1089 --------
group/dlm_controld/config.c | 306 ---
group/dlm_controld/config.h | 53 -
group/dlm_controld/cpg.c | 2631 --------------------
group/dlm_controld/crc.c | 72 -
group/dlm_controld/deadlock.c | 1550 ------------
group/dlm_controld/dlm_controld.h | 38 -
group/dlm_controld/dlm_daemon.h | 391 ---
group/dlm_controld/group.c | 376 ---
group/dlm_controld/logging.c | 61 -
group/dlm_controld/main.c | 1429 -----------
group/dlm_controld/member_cman.c | 350 ---
group/dlm_controld/netlink.c | 225 --
group/dlm_controld/plock.c | 2388 ------------------
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/man/Makefile | 12 -
group/man/dlm_controld.8 | 313 ---
group/man/group_tool.8 | 80 -
group/man/groupd.8 | 64 -
group/test/Makefile | 16 -
group/test/client.c | 45 -
group/test/clientd.c | 179 --
group/tool/Makefile | 30 -
group/tool/main.c | 735 ------
make/binding-passthrough.mk | 7 -
make/clean.mk | 7 -
make/cobj.mk | 38 -
make/copyright.cf | 6 -
make/defines.mk.input | 80 -
make/install.mk | 92 -
make/libs.mk | 59 -
make/official_release_version | 1 -
make/passthrough.mk | 7 -
make/perl-binding-common.mk | 30 -
make/release.mk | 160 --
make/uninstall.mk | 59 -
rgmanager/ChangeLog | 634 -----
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/cpglock-internal.h | 35 -
rgmanager/include/cpglock.h | 40 -
rgmanager/include/daemon_init.h | 10 -
rgmanager/include/ds.h | 13 -
rgmanager/include/event.h | 143 --
rgmanager/include/fdops.h | 14 -
rgmanager/include/findproc.h | 11 -
rgmanager/include/fo_domain.h | 49 -
rgmanager/include/gettid.h | 7 -
rgmanager/include/groups.h | 43 -
rgmanager/include/list.h | 95 -
rgmanager/include/lock.h | 17 -
rgmanager/include/logging.h | 11 -
rgmanager/include/members.h | 40 -
rgmanager/include/message.h | 175 --
rgmanager/include/msgsimple.h | 64 -
rgmanager/include/platform.h | 59 -
rgmanager/include/pthread_dbg.h | 41 -
rgmanager/include/res-ocf.h | 53 -
rgmanager/include/resgroup.h | 258 --
rgmanager/include/reslist.h | 210 --
rgmanager/include/restart_counter.h | 15 -
rgmanager/include/rg_dbus.h | 20 -
rgmanager/include/rg_locks.h | 47 -
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/sock.h | 18 -
rgmanager/include/vf.h | 181 --
rgmanager/init.d/Makefile | 20 -
rgmanager/init.d/cpglockd.in | 147 --
rgmanager/init.d/cpglockd.init.defaults.in | 7 -
rgmanager/init.d/rgmanager.in | 162 --
rgmanager/man/Makefile | 19 -
rgmanager/man/clubufflush.8 | 13 -
rgmanager/man/clufindhostname.8 | 22 -
rgmanager/man/clulog.8 | 27 -
rgmanager/man/clurgmgrd.8 | 1 -
rgmanager/man/clustat.8 | 53 -
rgmanager/man/clusvcadm.8 | 147 --
rgmanager/man/cpglockd.8 | 21 -
rgmanager/man/rgmanager.8 | 392 ---
rgmanager/src/Makefile | 4 -
rgmanager/src/clulib/Makefile | 41 -
rgmanager/src/clulib/ckpt_state.c | 536 ----
rgmanager/src/clulib/cman.c | 249 --
rgmanager/src/clulib/cpg_lock.c | 137 -
rgmanager/src/clulib/daemon_init.c | 228 --
rgmanager/src/clulib/dlm_lock.c | 301 ---
rgmanager/src/clulib/fdops.c | 176 --
rgmanager/src/clulib/gettid.c | 24 -
rgmanager/src/clulib/libcpglock.c | 287 ---
rgmanager/src/clulib/lock.c | 6 -
rgmanager/src/clulib/locktest.c | 67 -
rgmanager/src/clulib/logging.c | 112 -
rgmanager/src/clulib/members.c | 527 ----
rgmanager/src/clulib/message.c | 273 --
rgmanager/src/clulib/msg_cluster.c | 1278 ----------
rgmanager/src/clulib/msg_socket.c | 440 ----
rgmanager/src/clulib/msgsimple.c | 108 -
rgmanager/src/clulib/msgtest.c | 266 --
rgmanager/src/clulib/rg_strings.c | 219 --
rgmanager/src/clulib/sets.c | 353 ---
rgmanager/src/clulib/signals.c | 68 -
rgmanager/src/clulib/sock.c | 354 ---
rgmanager/src/clulib/tmgr.c | 150 --
rgmanager/src/clulib/vft.c | 1801 --------------
rgmanager/src/clulib/wrap_lock.c | 205 --
rgmanager/src/daemons/Makefile | 137 -
rgmanager/src/daemons/cpglockd.c | 1814 --------------
rgmanager/src/daemons/cpglockdump.c | 8 -
rgmanager/src/daemons/event_config.c | 514 ----
rgmanager/src/daemons/fo_domain.c | 655 -----
rgmanager/src/daemons/groups.c | 1986 ---------------
rgmanager/src/daemons/main.c | 1283 ----------
rgmanager/src/daemons/reslist.c | 995 --------
rgmanager/src/daemons/resrules.c | 1218 ---------
rgmanager/src/daemons/restart_counter.c | 193 --
rgmanager/src/daemons/restree.c | 1935 --------------
rgmanager/src/daemons/rg_event.c | 568 -----
rgmanager/src/daemons/rg_forward.c | 279 ---
rgmanager/src/daemons/rg_locks.c | 368 ---
rgmanager/src/daemons/rg_queue.c | 71 -
rgmanager/src/daemons/rg_state.c | 2366 ------------------
rgmanager/src/daemons/rg_thread.c | 770 ------
rgmanager/src/daemons/sbuf.c | 85 -
rgmanager/src/daemons/service_op.c | 359 ---
rgmanager/src/daemons/slang_event.c | 1468 -----------
rgmanager/src/daemons/test-expand-time.c | 25 -
rgmanager/src/daemons/test.c | 450 ----
.../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/update-dbus.c | 319 ---
rgmanager/src/daemons/watchdog.c | 108 -
rgmanager/src/resources/Makefile | 12 -
rgmanager/src/resources/default_event_script.sl | 652 -----
rgmanager/src/resources/follow-service.sl | 157 --
rgmanager/src/utils/Makefile | 73 -
rgmanager/src/utils/clubufflush.c | 121 -
rgmanager/src/utils/clufindhostname.c | 77 -
rgmanager/src/utils/clulog.c | 70 -
rgmanager/src/utils/clunfslock.sh | 69 -
rgmanager/src/utils/clustat.c | 1216 ---------
rgmanager/src/utils/clusvcadm.c | 465 ----
scripts/uninstall.pl | 71 -
499 files changed, 3 insertions(+), 114787 deletions(-)
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 5d4b50f..0000000
--- a/Makefile
+++ /dev/null
@@ -1,69 +0,0 @@
-include make/defines.mk
-
-REALSUBDIRS = common config cman dlm fence/libfenced group \
- fence rgmanager bindings doc contrib
-
-SUBDIRS = $(filter-out \
- $(if ${without_common},common) \
- $(if ${without_config},config) \
- $(if ${without_cman},cman) \
- $(if ${without_dlm},dlm) \
- $(if ${without_fence},fence/libfenced) \
- $(if ${without_group},group) \
- $(if ${without_fence},fence) \
- $(if ${without_rgmanager},rgmanager) \
- $(if ${without_bindings},bindings) \
- , $(REALSUBDIRS))
-
-all: ${SUBDIRS}
-
-${SUBDIRS}:
- ${MAKE} -C $@ all
-
-# Dependencies
-
-common:
-config:
-cman: common config
-dlm: config
-fence/libfenced:
-group: cman dlm fence/libfenced
-fence: group
-rgmanager: cman dlm
-bindings: cman
-contrib: dlm
-
-oldconfig:
- @if [ -f $(OBJDIR)/.configure.sh ]; then \
- sh $(OBJDIR)/.configure.sh; \
- else \
- echo "Unable to find old configuration data"; \
- fi
-
-install:
- set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
- install -d ${notifyddir}
- install -d ${logdir}
- install -d ${DESTDIR}/var/lib/cluster
- install -d ${DESTDIR}/var/run/cluster
-
-uninstall:
- set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
- rmdir ${notifyddir} || :;
- rmdir ${logdir} || :;
- rmdir ${DESTDIR}/var/lib/cluster || :;
- rmdir ${DESTDIR}/var/run/cluster || :;
-
-clean:
- set -e && for i in ${REALSUBDIRS}; do \
- contrib_code=1 \
- ${MAKE} -C $$i $@;\
- done
-
-distclean: clean
- rm -f make/defines.mk
- rm -f .configure.sh
- rm -f *tar.gz
- rm -rf build
-
-.PHONY: ${REALSUBDIRS}
diff --git a/README b/README
new file mode 100644
index 0000000..ded30cd
--- /dev/null
+++ b/README
@@ -0,0 +1,3 @@
+DISCONTINUED ON FEDORAHOSTED.ORG
+
+New home: https://pagure.io/linux-cluster/cluster
diff --git a/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 <fdinitto(a)redhat.com>
-
-=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 <fdinitto(a)redhat.com>
-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 <fdinitto(a)redhat.com>',
- '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 1cf8bc9..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 scripts
diff --git a/cman/cman_tool/Makefile b/cman/cman_tool/Makefile
deleted file mode 100644
index 77b48db..0000000
--- a/cman/cman_tool/Makefile
+++ /dev/null
@@ -1,33 +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}\" -DSBINDIR=\"${sbindir}\"
-CFLAGS += -I${cmanincdir} -I${ccsincdir}
-CFLAGS += -I${corosyncincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${cmanlibdir} -lcman -L${ccslibdir} -lccs
-LDFLAGS += -L${corosynclibdir} -lconfdb
-LDFLAGS += -L${libdir}
-
-${TARGET}: ${OBJS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-depends:
- $(MAKE) -C ../lib all
-
-clean: generalclean
-
--include $(OBJS:.o=.Tpo)
diff --git a/cman/cman_tool/cman_tool.h b/cman/cman_tool/cman_tool.h
deleted file mode 100644
index 6c5744e..0000000
--- a/cman/cman_tool/cman_tool.h
+++ /dev/null
@@ -1,109 +0,0 @@
-#ifndef __CMAN_TOOL_DOT_H__
-#define __CMAN_TOOL_DOT_H__
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-
-extern char *prog_name;
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-
-#define die(fmt, args...) \
-do { \
- fprintf(stderr, "%s: ", prog_name); \
- fprintf(stderr, fmt "\n", ##args); \
- exit(EXIT_FAILURE); \
-} while (0)
-
-#define DEFAULT_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,
- FMT_VOTES,
- FMT_EXP,
- FMT_STATE,
-};
-
-enum validate_options
-{
- VALIDATE_FAIL = 0,
- VALIDATE_WARN,
- VALIDATE_NONE,
-};
-
-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 nostderr_debug;
- int nodeid;
- int timeout;
- unsigned int config_version;
-
- int config_version_opt;
- int config_validate_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 addresses_opt;
- int noconfig_opt;
- int nosync_opt;
- int nosetpri_opt;
- int noopenais_opt;
-};
-typedef struct commandline commandline_t;
-
-int join(commandline_t *comline);
-
-#endif /* __CMAN_TOOL_DOT_H__ */
diff --git a/cman/cman_tool/join.c b/cman/cman_tool/join.c
deleted file mode 100644
index 44c8d69..0000000
--- a/cman/cman_tool/join.c
+++ /dev/null
@@ -1,396 +0,0 @@
-#include <errno.h>
-#include <unistd.h>
-#include <sys/wait.h>
-#include <stdint.h>
-#include <signal.h>
-#include <netinet/in.h>
-#include <corosync/confdb.h>
-#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(void)
-{
- 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");
- }
-
- /* We leave stderr open to allow error messags through.
- the cman plugin will close it when it's all started
- up properly.
- */
- setsid();
-}
-
-
-static const char *corosync_exit_reason(signed char status)
-{
- static char reason[256];
- switch (status) {
- case 1:
- return "Could not determine UID to run as";
- break;
- case 2:
- return "Could not determine GID to run as";
- break;
- case 3:
- return "Error initialising memory pool";
- break;
- case 4:
- return "Could not fork";
- break;
- case 5:
- return "Could not bind to libais socket";
- break;
- case 6:
- return "Could not bind to network socket";
- break;
- case 7:
- return "Could not read security key for communications";
- break;
- case 8:
- return "Could not read cluster configuration";
- break;
- case 9:
- return "Could not set up logging";
- break;
- case 11:
- return "Could not dynamically load modules";
- break;
- case 12:
- return "Could not load and initialise object database";
- break;
- case 13:
- return "Could not initialise all required services";
- break;
- case 14:
- return "Out of memory";
- break;
- case 15:
- return "Fatal error";
- break;
- case 16:
- return "Required directory not present /var/lib/corosync.";
- break;
- case 17:
- return "Could not acquire lock";
- break;
- case 18:
- return "Another Corosync instance is already running";
- break;
- default:
- snprintf(reason, sizeof(reason) - 1, "Error, reason code is %d", status);
- return reason;
- break;
- }
-}
-
-static int check_corosync_status(pid_t pid)
-{
- int status;
- int pidstatus;
-
- status = waitpid(pid, &pidstatus, WNOHANG);
- if (status == -1 && errno == ECHILD) {
-
- return 0;
- }
- if (status == pid && pidstatus != 0) {
- if (WIFEXITED(pidstatus))
- fprintf(stderr, "corosync died: %s\n", corosync_exit_reason(WEXITSTATUS(pidstatus)));
- if (WIFSIGNALED(pidstatus))
- fprintf(stderr, "corosync died with signal: %d\n", WTERMSIG(pidstatus));
- exit(1);
- }
- return status;
-}
-
-int join(commandline_t *comline)
-{
- int i;
- int envptr = 0;
- int argvptr = 0;
- char scratch[1024];
- char config_modules[1024];
- cman_handle_t h = NULL;
- int status;
- hdb_handle_t object_handle;
- confdb_handle_t confdb_handle;
- int res;
- pid_t corosync_pid;
- int p[2];
- confdb_callbacks_t callbacks = {
- .confdb_key_change_notify_fn = NULL,
- .confdb_object_create_change_notify_fn = NULL,
- .confdb_object_delete_change_notify_fn = NULL
- };
-
- /*
- * 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_DEBUG=%d", comline->verbose);
- envp[envptr++] = strdup(scratch);
- }
- if (comline->nostderr_debug) {
- snprintf(scratch, sizeof(scratch), "CMAN_NOSTDERR_DEBUG=true");
- envp[envptr++] = strdup(scratch);
- }
- if (comline->noconfig_opt) {
- envp[envptr++] = strdup("CMAN_NOCONFIG=true");
- snprintf(config_modules, sizeof(config_modules), "cmanpreconfig%s",
- comline->noopenais_opt?"":":openaisserviceenablestable");
- }
- else {
- snprintf(config_modules, sizeof(config_modules), "%s:cmanpreconfig%s", comline->config_lcrso,
- comline->noopenais_opt?"":":openaisserviceenablestable");
- }
- snprintf(scratch, sizeof(scratch), "COROSYNC_DEFAULT_CONFIG_IFACE=%s", config_modules);
- envp[envptr++] = strdup(scratch);
-
- /* Copy any COROSYNC_* env variables to the new daemon */
- i=0;
- while (i < MAX_ARGS && __environ[i]) {
- if (strncmp(__environ[i], "COROSYNC_", 9) == 0)
- envp[envptr++] = __environ[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;
-
- /* Always run corosync -f because we have already forked twice anyway, and
- we want to return any exit code that might happen */
- /* also strdup strings because it's otherwise virtually impossible to fix
- * build warnings due to the way argv C implementation is done */
- argv[0] = strdup("corosync");
- argv[++argvptr] = strdup("-f");
- if (comline->nosetpri_opt)
- argv[++argvptr] = strdup("-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; i<envptr-1; i++) {
- fprintf(stderr, "%s\n", envp[i]);
- }
- }
- be_daemon();
-
- sprintf(scratch, "FORKED: %d\n", getpid());
- write(p[1], scratch, strlen(scratch));
-
- execve(COROSYNCBIN, argv, envp);
-
- /* exec failed - tell the parent process */
- sprintf(scratch, "execve of " COROSYNCBIN " failed: %s", strerror(errno));
- 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];
- char *messageptr = message;
-
- FD_ZERO(&fds);
- FD_SET(p[0], &fds);
-
- status = select(p[0]+1, &fds, NULL, NULL, &tv);
-
- /* Did we get a cman-reported error? */
- if (status == 1) {
- int len;
- if ((len = read(p[0], message, sizeof(message) - 1) > 0)) {
- message[sizeof(message) - 1] = '\0';
-
- /* Forked OK - get the real corosync pid */
- if ((messageptr) && (sscanf(messageptr, "FORKED: %d", &corosync_pid) == 1)) {
- if (comline->verbose & DEBUG_STARTUP_ONLY)
- fprintf(stderr, "forked process ID is %d\n", corosync_pid);
- status = 0;
-
- /* There might be a SUCCESS or error message in the pipe too. */
- messageptr = strchr(messageptr, '\n');
- if (messageptr && strlen(messageptr) > 1)
- messageptr++;
- else
- continue;
- }
- /* Success! get the new PID of double-forked corosync */
- if ((messageptr) && (sscanf(messageptr, "SUCCESS: %d", &corosync_pid) == 1)) {
- if (comline->verbose & DEBUG_STARTUP_ONLY)
- fprintf(stderr, "corosync running, process ID is %d\n", corosync_pid);
- status = 0;
- break;
- }
- else if (messageptr) {
- fprintf(stderr, "%s\n", messageptr);
- status = 1;
- break;
- }
- }
- else if (len < 0 && errno == EINTR) {
- continue;
- }
- else { /* Error or EOF - check the child status */
- status = check_corosync_status(corosync_pid);
- if (status == 0)
- break;
- }
- }
-
- } 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) {
- status = check_corosync_status(corosync_pid);
- die("corosync died during startup\n");
- }
-
- h = cman_admin_init(NULL);
- if (!h && comline->verbose & DEBUG_STARTUP_ONLY)
- {
- fprintf(stderr, "waiting for cman to start\n");
- status = check_corosync_status(corosync_pid);
- }
- }
- 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);
-
- /* Copy all COROSYNC_* environment variables into objdb so they can be used to validate new configurations later */
- res = confdb_initialize (&confdb_handle, &callbacks);
- if (res != CS_OK)
- goto join_exit;
-
- res = confdb_object_create(confdb_handle, OBJECT_PARENT_HANDLE, "cman_private", strlen("cman_private"), &object_handle);
- if (res == CS_OK) {
- int envnum = 0;
- const char *envvar = __environ[envnum];
- const char *equal;
- char envname[PATH_MAX];
-
-
- while (envvar) {
- if (strncmp("COROSYNC_", envvar, 9) == 0) {
- equal = strchr(envvar, '=');
- if (equal) {
- strncpy(envname, envvar, PATH_MAX);
- if (equal-envvar < PATH_MAX) {
- envname[equal-envvar] = '\0';
-
- res = confdb_key_create_typed(confdb_handle, object_handle, envname,
- equal+1, strlen(equal+1),CONFDB_VALUETYPE_STRING);
- }
- }
- }
- envvar = __environ[++envnum];
- }
- }
- res = confdb_key_create_typed(confdb_handle, object_handle,
- "COROSYNC_DEFAULT_CONFIG_IFACE",
- config_modules, strlen(config_modules), CONFDB_VALUETYPE_STRING);
- confdb_finalize (confdb_handle);
-
-join_exit:
- return 0;
-}
diff --git a/cman/cman_tool/main.c b/cman/cman_tool/main.c
deleted file mode 100644
index 6946e9e..0000000
--- a/cman/cman_tool/main.c
+++ /dev/null
@@ -1,1297 +0,0 @@
-#include <errno.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <signal.h>
-#include <time.h>
-#include <corosync/confdb.h>
-#include <netinet/in.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include "copyright.cf"
-#include "libcman.h"
-#include "cman_tool.h"
-
-#define DEFAULT_CONFIG_MODULE "xmlconfig"
-
-#define OPTION_STRING ("m:n:v:e:2p:c:i:N:t:o:k:F:C:VAPwfqazh?XD::Sd::r::")
-#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
-
-static void print_usage(int subcmd)
-{
- printf("Usage:\n");
- printf("\n");
- printf("%s <join|leave|kill|expected|votes|version|wait|status|nodes|services|debug> [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 <addr> Multicast address to use\n");
- printf(" -v <votes> Number of votes this node has\n");
- printf(" -e <votes> Number of expected votes for the cluster\n");
- printf(" -p <port> UDP port number for cman communications\n");
- printf(" -n <nodename> The name of this node (defaults to hostname)\n");
- printf(" -c <clustername> The name of the cluster to join\n");
- printf(" -N <id> Node id\n");
- printf(" -C <module> 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 <file> Private key file for Corosync communications\n");
- printf(" -P Don't set corosync to realtime priority\n");
- printf(" -X Use internal cman defaults for configuration\n");
- printf(" -A Don't load openais services\n");
- printf(" -D<fail|warn|none> What to do about the config. Default (without -D) is to\n");
- printf(" validate the config. with -D no validation will be done.\n");
- printf(" -Dwarn will print errors but allow the operation to continue.\n");
- printf(" -z Disable stderr debugging output.\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 <nodename> The name of the node to kill (can specify multiple times)\n");
- printf("\n");
- }
-
- if (!subcmd || subcmd == OP_EXPECTED) {
- printf("expected\n");
- printf(" -e <votes> New number of expected votes for the cluster\n");
- printf("\n");
- }
-
- if (!subcmd || subcmd == OP_VOTES) {
- printf("votes\n");
- printf(" -v <votes> 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(" -a Also show node address(es)\n");
- printf(" -n <nodename> Only show information for specific node\n");
- printf(" -F <format> 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 Reload cluster.conf and update config version.\n");
- printf(" -D <fail,warn,none> What to do about the config. Default (without -D) is to\n");
- printf(" validate the config. with -D no validation will be done. -Dwarn will print errors\n");
- printf(" but allow the operation to continue\n");
- printf(" -S Don't run ccs_sync to distribute cluster.conf (if appropriate)\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;
-
- if (inet_ntop(ss->ss_family, saddr, buf, sizeof(buf)))
- printf("%s", buf);
- else
- printf("none");
-}
-
-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:
- snprintf(buf, buflen - 1, "Unknown: code=%d", node_state);
- break;
- }
-
- return buf;
-}
-
-static const char *cman_error(int err)
-{
- const char *die_error;
-
- switch (err) {
- 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(err);
- break;
- }
- return die_error;
-}
-
-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_DISALLOWED_ENABLED)
- printf(" DisallowedEnabled");
- if (einfo->ei_flags & CMAN_EXTRA_FLAG_DIRTY)
- printf(" HaveState");
- 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: %u\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; i<numnodes; i++) {
- printf("%s ", nodes[i].cn_name);
- }
- printf("\n");
- }
- }
- cman_finish(h);
-}
-
-static int node_compare(const void *va, const void *vb)
-{
- const cman_node_t *a = va;
- const cman_node_t *b = vb;
- return a->cn_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;
- if (!strcmp(opt, "votes"))
- return FMT_VOTES;
- if (!strcmp(opt, "exp"))
- return FMT_EXP;
- if (!strcmp(opt, "state"))
- return FMT_STATE;
-
- 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 *jtime;
- int numaddrs=1;
- struct cman_node_address addrs[MAX_INTERFACES];
- char jstring[1024];
- int i,j,k;
- unsigned int tmpid;
- cman_node_extra_t enode;
-
- 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;
- }
-
- /* Make the name more friendly if cman can't find it in cluster.conf
- * (we really don't want corosync to look up names in DNS so it invents them)
- */
- if (sscanf(node->cn_name, "Node%u", &tmpid) == 1 && tmpid == node->cn_nodeid) {
- if (!cman_get_node_addrs(h, node->cn_nodeid, MAX_INTERFACES, &numaddrs, addrs) && numaddrs) {
- getnameinfo((struct sockaddr *)addrs[0].cna_address, addrs[0].cna_addrlen, node->cn_name, sizeof(node->cn_name), NULL, 0, NI_NAMEREQD);
- }
- }
-
- 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
- strncpy(jstring, " ", sizeof(jstring));
-
- if (!comline->format_opts) {
- printf("%4u %c %5d %s %s\n",
- node->cn_nodeid, member_type,
- node->cn_incarnation, jstring, node->cn_name);
- }
-
- if (comline->addresses_opt || comline->format_opts) {
- if (node->cn_nodeid > 0) {
- 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 && (cman_get_node_extra(h, node->cn_nodeid, &enode) == 0)) {
- for (j = 0; j < MAX_FORMAT_OPTS; j++) {
- switch (format[j]) {
- case FMT_NONE:
- break;
- case FMT_ID:
- printf("%u ", node->cn_nodeid);
- break;
- case FMT_NAME:
- printf("%s ", node->cn_name);
- break;
- case FMT_TYPE:
- printf("%c ", member_type);
- break;
- case FMT_VOTES:
- printf("%d ", enode.cnx_votes);
- break;
- case FMT_EXP:
- printf("%d ", enode.cnx_expected_votes);
- break;
- case FMT_STATE:
- switch (enode.cnx_state)
- {
- case CLUSTER_NODESTATE_JOINING:
- printf("Joining ");
- break;
- case CLUSTER_NODESTATE_MEMBER:
- printf("Member ");
- break;
- case CLUSTER_NODESTATE_DEAD:
- printf("Dead ");
- break;
- case CLUSTER_NODESTATE_LEAVING:
- printf("Leaving ");
- break;
- case CLUSTER_NODESTATE_DISALLOWED:
- printf("Disallowed ");
- break;
- default:
- printf("Unknown ");
- break;
- }
- 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 (!dis_nodes)
- die("cannot allocate memory for disallowed node\n");
-
- 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");
-}
-
-
-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 && !comline->wait_opt) {
- die("Error leaving cluster: %s", cman_error(errno));
- }
- cman_finish(h);
-
- /* Wait until cman shuts down */
- if (comline->wait_opt) {
- while ( (h = cman_admin_init(NULL)) ) {
- cman_finish(h);
- sleep(1);
- }
- }
-}
-
-static void set_expected(commandline_t *comline)
-{
- cman_handle_t h;
-
- h = open_cman_handle(1);
-
- if (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 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;
- strncpy(node.cn_name, comline->nodenames[0], CMAN_MAX_NODENAME_LEN);
- 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 (cman_set_votes(h, comline->votes, nodeid))
- die("can't set votes: %s", cman_error(errno));
-
- cman_finish(h);
-}
-
-static int validate_config(commandline_t *comline, int current_version)
-{
- struct stat st;
- char command[PATH_MAX];
- char validator[PATH_MAX];
- char ccs_quiet[8];
- int cmd_res;
-
- /* Look for ccs_config_validate */
- snprintf(validator, sizeof(validator), "%s/ccs_config_validate", SBINDIR);
- if (stat(validator, &st) != 0 || !(st.st_mode & S_IXUSR)) {
- fprintf(stderr, "Cannot find ccs_config_validate, configuration was not checked but assumed to be OK.\n");
- return 0;
- }
-
- if (comline->verbose > 1) {
- snprintf(ccs_quiet, sizeof(ccs_quiet), " ");
- } else {
- snprintf(ccs_quiet, sizeof(ccs_quiet), "-q");
- }
-
- if (current_version) {
- snprintf(command, sizeof(command), "%s %s -R %d",
- validator, ccs_quiet, current_version);
- } else {
- snprintf(command, sizeof(command), "%s %s",
- validator, ccs_quiet);
- }
-
- if (comline->verbose > 1)
- printf("calling '%s'\n", command);
-
- cmd_res = system(command);
-
- return WEXITSTATUS(cmd_res);
-}
-
-/* Here we set the COROSYNC_ variables that might be needed by the corosync
- configuration modules. We just put them into the environment and leave
- them for the sub-process to pick up.
- 'config_modules' is returned separately because it's needed internally to
- and it saves the caller from extracting it all over again.
- We only return 0 (success) if config_modules is returned as without that
- the caller can't really do anything at all.
-*/
-static int get_config_variables(commandline_t *comline, char **config_modules)
-{
- int res;
- int got_iface = 1;
- char key_name[1024];
- char *key_value = NULL;
- size_t key_value_len;
- confdb_value_types_t type;
- hdb_handle_t confdb_handle;
- hdb_handle_t cmanp_handle;
- confdb_callbacks_t callbacks = {
- .confdb_key_change_notify_fn = NULL,
- .confdb_object_create_change_notify_fn = NULL,
- .confdb_object_delete_change_notify_fn = NULL
- };
-
- *config_modules = NULL;
- res = confdb_initialize (&confdb_handle, &callbacks);
- if (res != CS_OK)
- return 0;
-
- res = confdb_object_find_start(confdb_handle, OBJECT_PARENT_HANDLE);
- if (res != CS_OK)
- goto finish;
-
- res = confdb_object_find(confdb_handle, OBJECT_PARENT_HANDLE, "cman_private", strlen("cman_private"), &cmanp_handle);
- if (res != CS_OK)
- goto finish;
-
- res = confdb_key_iter_start(confdb_handle, cmanp_handle);
- if (res != CS_OK)
- goto finish;
-
- while ( (res = confdb_key_iter_typed2(confdb_handle, cmanp_handle, key_name,
- (void**)&key_value, &key_value_len, &type)) == CS_OK) {
- key_value[key_value_len] = '\0';
-
- setenv(key_name, key_value, 1);
- if (strcmp(key_name, "COROSYNC_DEFAULT_CONFIG_IFACE") == 0) {
- *config_modules = strdup(key_value);
- got_iface = 0;
- }
- free(key_value);
- key_value = NULL;
- }
-
-finish:
- confdb_finalize(confdb_handle);
- return got_iface;
-}
-
-static void version(commandline_t *comline)
-{
- struct cman_version ver;
- cman_handle_t h;
- int result;
- char *config_modules = NULL;
-
- 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_opt) {
- printf("%d.%d.%d config %d\n", ver.cv_major, ver.cv_minor, ver.cv_patch,
- ver.cv_config);
- goto out;
- }
-
- if (comline->verbose)
- printf("Getting config variables\n");
- if (get_config_variables(comline, &config_modules))
- die("cannot get COROSYNC_DEFAULT_CONFIG_IFACE");
-
- /* By default we validate the configuration first */
- if (comline->config_validate_opt != VALIDATE_NONE) {
-
- if (comline->verbose)
- printf("Validating configuration\n");
- result = validate_config(comline, ver.cv_config);
- if (result == 253)
- /* Unable to find new config version */
- die("Unable to retrive the new config version\n");
- if (result == 254)
- /* Config regression = fail. */
- die("Not reloading, config version older or equal the running config");
- if (result == 255)
- /* Generic error from ccs_config_validate */
- die("Not reloading, generic error running ccs_config_validate\n"
- "Try re-running with -d options");
- else if (result && comline->config_validate_opt == VALIDATE_FAIL)
- die("Not reloading, configuration is not valid");
- }
-
- /* We don't bother looking for ccs_sync here - just assume it's in /usr/bin and
- that it exists. If this is not true then then user can choose to bypass
- the disibution and do it themselves.
- Note that ccs_sync might prompt on stderr for passwords the first time it is
- run.
- */
- if (strstr(config_modules, "xmlconfig") && !comline->nosync_opt) {
- if (comline->verbose > 1)
- printf("calling ccs_sync\n");
- result = system("/usr/bin/ccs_sync");
- if (result)
- die("ccs_sync failed.\nIf you have distributed the config file yourself, try re-running with -S\n");
- }
-
- if (comline->verbose)
- printf("Telling cman the new version number\n");
-
- ver.cv_config = comline->config_version;
-
- result = cman_set_version(h, &ver);
-
- switch(result) {
- case 0:
- if (comline->verbose)
- printf("Configuration succesfully updated or already running\n");
- break;
- default:
- die("Error loading configuration in corosync/cman");
- break;
- }
- 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; i<comline->num_nodenames; i++) {
-
- /* Resolve node name into a number */
- node.cn_nodeid = 0;
- strncpy(node.cn_name, comline->nodenames[i], CMAN_MAX_NODENAME_LEN);
- 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);
-}
-
-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 suboptchar;
- int show_help = 0;
- char buf[16];
-
- while (cont) {
- optchar = getopt(argc, argv, OPTION_STRING);
-
- switch (optchar) {
-
- case 'm':
- comline->multicast_addr = strdup(optarg);
- break;
-
- case 'a':
- comline->addresses_opt = 1;
- break;
-
- case 'D':
- /* Just look at the upper-cased version of the first letter of the argument */
- if (optarg) {
- suboptchar = optarg[0] & 0x5F;
- switch (suboptchar)
- {
- case 'F':
- comline->config_validate_opt = VALIDATE_FAIL;
- break;
- case 'W':
- comline->config_validate_opt = VALIDATE_WARN;
- break;
- case 'N':
- comline->config_validate_opt = VALIDATE_NONE;
- break;
- default:
- die("invalid option to -D, it should be 'force', 'warn' or 'none'\n");
- break;
- }
- }
- else {
- comline->config_validate_opt = VALIDATE_NONE;
- }
- break;
- case 'S':
- comline->nosync_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 = 0;
- comline->config_version_opt = TRUE;
- if (optarg) {
- fprintf(stderr, "Warning: specifying a "
- "version for the -r flag is "
- "deprecated and no longer used\n");
- }
- 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);
- strncpy(comline->clustername, optarg, sizeof(comline->clustername) - 1);
- 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 'z':
- comline->nostderr_debug = 1;
- 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;
- };
- }
-
- if (comline->config_lcrso == NULL)
- comline->config_lcrso = strdup(DEFAULT_CONFIG_MODULE);
-
- 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;
- } else if (strcmp(argv[optind], "remove") == 0) {
- comline->remove = TRUE;
- } else if (strcmp(argv[optind], "force") == 0) {
- comline->force = TRUE;
- } else {
- snprintf(buf, sizeof(buf),
- "%d", atoi(argv[optind]));
- if (!strcmp(buf, argv[optind]) &&
- (comline->config_version_opt == TRUE) &&
- comline->operation == OP_VERSION) {
- fprintf(stderr, "Warning: specifying a "
- "version for the -r flag is "
- "deprecated and no longer used\n");
- } 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");
-}
-
-
-static void do_join(commandline_t *comline)
-{
- int ret;
-
- check_arguments(comline);
-
- if (comline->timeout) {
- signal(SIGALRM, sigalarm_handler);
- alarm(comline->timeout);
- }
-
- /* By default we validate the configuration first */
- if (comline->config_validate_opt != VALIDATE_NONE) {
-
- if (comline->verbose)
- printf("Validating configuration\n");
-
- if (validate_config(comline, 0) &&
- comline->config_validate_opt == VALIDATE_FAIL)
- die("Not joining, configuration is not valid\n");
- }
-
- join(comline);
- if (comline->wait_opt || comline->wait_quorate_opt) {
- do {
- ret = cluster_wait(comline);
- if (ret == ENOTCONN)
- join(comline);
-
- } while (ret == ENOTCONN);
- }
-}
-
-int main(int argc, char *argv[])
-{
- commandline_t comline;
-
- prog_name = argv[0];
-
- memset(&comline, 0, sizeof(commandline_t));
-
- decode_arguments(argc, argv, &comline);
-
- switch (comline.operation) {
- case OP_JOIN:
- do_join(&comline);
- 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;
- }
-
- exit(EXIT_SUCCESS);
-}
-
-char *prog_name;
diff --git a/cman/daemon/Makefile b/cman/daemon/Makefile
deleted file mode 100644
index a2672e9..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 \
- ais.o \
- commands.o \
- barrier.o \
- cmanconfig.o
-
-OBJS2= cman-preconfig.o \
- fnvhash.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=.Tpo)
--include $(OBJS2:.o=.Tpo)
diff --git a/cman/daemon/ais.c b/cman/daemon/ais.c
deleted file mode 100644
index ea5020c..0000000
--- a/cman/daemon/ais.c
+++ /dev/null
@@ -1,378 +0,0 @@
-#include <sys/poll.h>
-#include <sys/types.h>
-#include <sys/errno.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/socket.h>
-#include <sys/utsname.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <inttypes.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-/* corosync headers */
-#include <corosync/corotypes.h>
-#include <corosync/corotypes.h>
-#include <corosync/coroipc_types.h>
-#include <corosync/coroipcc.h>
-#include <corosync/corodefs.h>
-#include <corosync/mar_gen.h>
-#include <corosync/engine/coroapi.h>
-#include <corosync/engine/logsys.h>
-#include <corosync/engine/quorum.h>
-#include <corosync/lcr/lcr_comp.h>
-
-#include "list.h"
-#include "cnxman-socket.h"
-#include "cnxman-private.h"
-#include "commands.h"
-
-#include "ais.h"
-#include "cman.h"
-#define OBJDB_API struct corosync_api_v1
-#include "nodelist.h"
-#include "cmanconfig.h"
-#include "daemon.h"
-
-extern char cluster_name[MAX_CLUSTER_NAME_LEN+1];
-extern unsigned int quorumdev_poll;
-extern unsigned int ccsd_poll_interval;
-extern unsigned int enable_disallowed;
-extern unsigned int shutdown_timeout;
-extern unsigned int startup_config_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;
-quorum_set_quorate_fn_t corosync_set_quorum;
-struct memb_ring_id cman_ring_id;
-extern unsigned int config_version;
-static hdb_handle_t cluster_parent_handle;
-
-static int startup_pipe;
-static int first_trans = 1;
-struct corosync_api_v1 *corosync;
-
-static hdb_handle_t group_handle;
-static struct corosync_tpg_group cman_group[1] = {
- { .group = "CMAN", .group_len = 4},
-};
-
-LOGSYS_DECLARE_SUBSYS (CMAN_NAME);
-
-/* 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,
- const unsigned int *member_list, size_t member_list_entries,
- const unsigned int *left_list, size_t left_list_entries,
- const unsigned int *joined_list, size_t joined_list_entries,
- const struct memb_ring_id *ring_id);
-static void cman_deliver_fn(unsigned int nodeid, const void *msg, unsigned int msg_len,
- int endian_conversion_required);
-static void cman_quorum_init(struct corosync_api_v1 *api, quorum_set_quorate_fn_t report);
-
-/*
- * 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,
- .sync_mode = CS_SYNC_V1,
-};
-
-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 quorum_services_api_ver1 cman_quorum_iface_ver0 = {
- .init = cman_quorum_init
-};
-
-static struct lcr_iface ifaces_ver0[2] = {
- {
- .name = "corosync_cman",
- .version = 0,
- .versions_replace = 0,
- .versions_replace_count = 0,
- .dependencies = 0,
- .dependency_count = 0,
- .constructor = NULL,
- .destructor = NULL,
- .interfaces = NULL,
- },
- {
- .name = "quorum_cman",
- .version = 0,
- .versions_replace = 0,
- .versions_replace_count = 0,
- .dependencies = 0,
- .dependency_count = 0,
- .constructor = NULL,
- .destructor = NULL,
- .interfaces = (void **)(void *)&cman_quorum_iface_ver0,
- },
-};
-
-static struct lcr_comp cman_comp_ver0 = {
- .iface_count = 2,
- .ifaces = ifaces_ver0,
-};
-
-
-__attribute__ ((constructor)) static void cman_comp_register(void) {
- lcr_interfaces_set(&ifaces_ver0[0], &cman_service_handler_iface);
- lcr_interfaces_set(&ifaces_ver0[1], &cman_quorum_iface_ver0);
- lcr_component_register(&cman_comp_ver0);
-}
-
-/* ------------------------------- */
-
-static void cman_quorum_init(struct corosync_api_v1 *api, quorum_set_quorate_fn_t report)
-{
- corosync = api;
- corosync_set_quorum = report;
-}
-
-static int cman_exec_init_fn(struct corosync_api_v1 *api)
-{
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
- hdb_handle_t totem_handle;
- char pipe_msg[256];
- unsigned int totem_token;
-
- 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);
-
- /*
- * quorum_dev_poll should default to the token timeout so that quorum devices behave
- * like nodes
- */
- corosync->object_find_create(OBJECT_PARENT_HANDLE, "totem", strlen("totem"), &find_handle);
- corosync->object_find_next(find_handle, &totem_handle);
- objdb_get_int(api, totem_handle, "token", &totem_token, 1000);
- 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, totem_token);
- 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, "disallowed", &enable_disallowed, DEFAULT_DISALLOWED);
- objdb_get_int(api, object_handle, "startup_config_timeout", &startup_config_timeout, DEFAULT_STARTUP_CONFIG_TIMEOUT);
- }
- corosync->object_find_destroy(find_handle);
- log_printf(LOGSYS_LEVEL_DEBUG, 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(api);
-
- /* Let cman_tool know we are running and our PID */
- snprintf(pipe_msg, sizeof(pipe_msg) - 1,"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);
-
- if (getenv("CMAN_NOSTDERR_DEBUG")) {
- int tmpfd;
- tmpfd = open("/dev/null", O_RDWR);
- if (tmpfd > -1 && tmpfd != STDERR_FILENO) {
- dup2(tmpfd, STDERR_FILENO);
- close(tmpfd);
- }
- }
-
- 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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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);
-}
-
-static void cman_deliver_fn(unsigned int nodeid, const void *msg, unsigned int msg_len,
- int endian_conversion_required)
-{
- const struct cl_protheader *original_header = msg;
- struct cl_protheader header;
- const char *buf = msg;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "ais: deliver_fn source nodeid = %d, len=%d, endian_conv=%d\n",
- nodeid, msg_len, endian_conversion_required);
-
- if (endian_conversion_required) {
- header.srcid = swab32(original_header->srcid);
- header.tgtid = swab32(original_header->tgtid);
- header.flags = swab32(original_header->flags);
- header.srcport = original_header->srcport;
- header.tgtport = original_header->tgtport;
- }
- else {
- memcpy(&header, original_header, sizeof(header));
- }
-
- /* 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), msg_len - sizeof(struct cl_protheader),
- endian_conversion_required);
- }
-}
-
-static void cman_confchg_fn(enum totem_configuration_type configuration_type,
- const unsigned int *member_list, size_t member_list_entries,
- const unsigned int *left_list, size_t left_list_entries,
- const unsigned int *joined_list, size_t joined_list_entries,
- const struct memb_ring_id *ring_id)
-{
- int i;
- static int last_memb_count = 0;
- static size_t saved_left_list_entries;
- static size_t saved_left_list_size;
- static unsigned int *saved_left_list = NULL;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "ais: confchg_fn called type = %d, seq=%lld\n", configuration_type, ring_id->seq);
-
- memcpy(&cman_ring_id, ring_id, sizeof(*ring_id));
- incarnation = ring_id->seq;
- num_ais_nodes = member_list_entries;
-
- /* Tell the cman membership layer */
- for (i=0; i<left_list_entries; i++)
- del_ais_node(left_list[i]);
-
- /* Joining nodes are only added after a valid TRANSITION message
- * is received.
- */
-
- /* Save the left list for later so we can do a consolidated confchg message */
- if (configuration_type == TOTEM_CONFIGURATION_TRANSITIONAL) {
- if (saved_left_list == NULL) {
- saved_left_list_size = left_list_entries*2;
- saved_left_list = malloc(sizeof(int) * saved_left_list_size);
- if (!saved_left_list) {
- log_printf(LOGSYS_LEVEL_CRIT, "cannot allocate memory for confchg message");
- exit(3);
- }
- }
- if (saved_left_list_size < left_list_entries) {
- saved_left_list_size = left_list_entries*2;
- saved_left_list = realloc(saved_left_list, sizeof(int) * saved_left_list_size);
- if (!saved_left_list) {
- log_printf(LOGSYS_LEVEL_CRIT, "cannot reallocate memory for confchg message");
- exit(3);
- }
- }
- saved_left_list_entries = left_list_entries;
- memcpy(saved_left_list, left_list, left_list_entries * sizeof(int));
- }
-
- if (configuration_type == TOTEM_CONFIGURATION_REGULAR) {
- log_printf(LOGSYS_LEVEL_DEBUG, "ais: last memb_count = %d, current = %"PRIuFAST32"\n", last_memb_count, member_list_entries);
- send_transition_msg(last_memb_count, first_trans);
- last_memb_count = member_list_entries;
- if (member_list_entries > 1)
- first_trans = 0;
-
- cman_send_confchg(member_list, member_list_entries,
- saved_left_list, saved_left_list_entries,
- joined_list, joined_list_entries);
- }
-}
-
-void corosync_shutdown(void)
-{
- corosync->shutdown_request();
-}
-
-/* Write an error message down the CMAN startup pipe so
- that cman_tool can display it */
-int write_cman_pipe(const 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 44b1a8c..0000000
--- a/cman/daemon/ais.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <corosync/engine/quorum.h>
-/* 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;
-extern quorum_set_quorate_fn_t corosync_set_quorum;
-extern struct memb_ring_id cman_ring_id;
-extern void corosync_shutdown(void);
diff --git a/cman/daemon/barrier.c b/cman/daemon/barrier.c
deleted file mode 100644
index c356abe..0000000
--- a/cman/daemon/barrier.c
+++ /dev/null
@@ -1,469 +0,0 @@
-#include <getopt.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/utsname.h>
-#include <sys/un.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/signal.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <sys/errno.h>
-
-#include <corosync/corotypes.h>
-#include <corosync/coroipc_types.h>
-#include <corosync/coroipcc.h>
-#include <corosync/corodefs.h>
-#include <corosync/mar_gen.h>
-#include <corosync/engine/coroapi.h>
-#include <corosync/engine/logsys.h>
-#include "list.h"
-#include "cnxman-socket.h"
-#include "cnxman-private.h"
-#include "daemon.h"
-#include "commands.h"
-#include "barrier.h"
-#include "cman.h"
-#include "ais.h"
-
-extern int we_are_a_cluster_member;
-
-LOGSYS_DECLARE_SUBSYS (CMAN_NAME);
-
-/* 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;
- strncpy(bmsg.name, barrier->name, MAX_BARRIER_NAME_LEN - 1);
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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)
-{
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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));
-
- strncpy(barrier->name, name, MAX_BARRIER_NAME_LEN - 1);
- 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;
-
- /* Ignore other peoples' messages */
- if (!we_are_a_cluster_member)
- return;
-
- barrier = find_barrier(msg->name);
- if (!barrier)
- return;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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:
- /* 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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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 ((!barrier) || (!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;
- strncpy(bmsg.name, barrier->name, MAX_BARRIER_NAME_LEN - 1);
-
- 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);
- }
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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->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 08b5ecf..0000000
--- a/cman/daemon/cman-preconfig.c
+++ /dev/null
@@ -1,1781 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/utsname.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/errno.h>
-#include <netdb.h>
-#include <fcntl.h>
-#define SYSLOG_NAMES
-#include <sys/syslog.h>
-#include <ifaddrs.h>
-#include <arpa/inet.h>
-
-/* corosync headers */
-#include <corosync/engine/logsys.h>
-#include <corosync/lcr/lcr_comp.h>
-#include <corosync/engine/objdb.h>
-#include <corosync/engine/config.h>
-
-#include "cman.h"
-#define OBJDB_API struct objdb_iface_ver0
-#include "cnxman-socket.h"
-#include "nodelist.h"
-#include "fnvhash.h"
-
-#define MAX_PATH_LEN PATH_MAX
-
-enum tx_mech {
- TX_MECH_UDP,
- TX_MECH_UDPB,
- TX_MECH_UDPU,
- TX_MECH_RDMA,
-};
-
-static unsigned int debug;
-static int cmanpre_readconfig(struct objdb_iface_ver0 *objdb, const char **error_string);
-static int cmanpre_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, const 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 int num_nodenames;
-static char *key_filename=NULL;
-static char *cluster_name;
-static char error_reason[1024] = { '\0' };
-static hdb_handle_t cluster_parent_handle;
-static int use_hashed_cluster_id = 0;
-static unsigned int portnum = 0;
-static unsigned int altportnum = 0;
-static char *mcast_name = NULL;
-static char *altmcast_name = NULL;
-static unsigned int ttl = 1;
-static unsigned int altttl = 1;
-
-
-/*
- * 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;
-
- if (addr1->ss_family != addr2->ss_family)
- return 0;
-
- if (addr1->ss_family == AF_INET) {
- addrlen = sizeof(struct sockaddr_in);
- }
- if (addr1->ss_family == AF_INET6) {
- addrlen = sizeof(struct sockaddr_in6);
- }
- assert(addrlen);
-
- if (memcmp(addr1, addr2, addrlen) == 0)
- return 1;
- else
- return 0;
-
-}
-
-/* Build a localhost ip_address */
-static int get_localhost(int family, struct sockaddr_storage *localhost)
-{
- const 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, int family_hint)
-{
- 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;
- ahints.ai_family = family_hint;
-
- /* 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 hdb_handle_t find_cman_logger(struct objdb_iface_ver0 *objdb, hdb_handle_t object_handle)
-{
- hdb_handle_t subsys_handle;
- hdb_handle_t find_handle;
- char *str;
-
- objdb->object_find_create(object_handle, "logger_subsys", strlen("logger_subsys"), &find_handle);
- while (!objdb->object_find_next(find_handle, &subsys_handle)) {
- if (!objdb_get_string(objdb, subsys_handle, "subsys", &str)) {
- if (strncmp(str, CMAN_NAME, 4) == 0) {
- objdb->object_find_destroy(find_handle);
- return subsys_handle;
- }
- }
- }
- objdb->object_find_destroy(find_handle);
-
- return -1;
-
-}
-
-static int add_udpu_members(struct objdb_iface_ver0 *objdb, hdb_handle_t interface_object_handle)
-{
- char *cur_nodename;
- hdb_handle_t altname_handle;
- hdb_handle_t find_handle = 0;
- hdb_handle_t find_handle2 = 0;
- hdb_handle_t member_object_handle;
- hdb_handle_t nodes_handle;
- int cur_altname_depth;
-
- nodes_handle = nodeslist_init(objdb, cluster_parent_handle, &find_handle);
- while (nodes_handle) {
- if (num_interfaces == 0) {
- if (objdb_get_string(objdb, nodes_handle, "name", &cur_nodename)) {
- nodes_handle = nodeslist_next(objdb, find_handle);
- continue;
- }
- } else {
- objdb->object_find_create(nodes_handle, "altname", strlen("altname"), &find_handle2);
-
- cur_altname_depth = 0;
- while (objdb->object_find_next(find_handle2, &altname_handle) == 0 &&
- cur_altname_depth < num_interfaces)
- cur_altname_depth++;
-
- if (cur_altname_depth == num_interfaces) {
- if (objdb_get_string(objdb, altname_handle, "name", &cur_nodename)) {
- nodes_handle = nodeslist_next(objdb, find_handle);
- continue;
- }
- } else {
- nodes_handle = nodeslist_next(objdb, find_handle);
- continue;
- }
- objdb->object_find_destroy(find_handle2);
- }
-
- if (objdb->object_create(interface_object_handle, &member_object_handle,
- "member", strlen("member")) == 0) {
- objdb->object_key_create_typed(member_object_handle, "memberaddr",
- cur_nodename, strlen(cur_nodename)+1, OBJDB_VALUETYPE_STRING);
- }
-
- nodes_handle = nodeslist_next(objdb, find_handle);
- }
- objdb->object_find_destroy(find_handle);
-
- return 0;
-}
-
-#define PRIMARY_IFACE 0
-#define ALT_IFACE 1
-
-static int add_ifaddr(struct objdb_iface_ver0 *objdb, char *mcast, char *ifaddr, int port, int intttl, int altiface, enum tx_mech transport)
-{
- hdb_handle_t totem_object_handle;
- hdb_handle_t find_handle;
- hdb_handle_t interface_object_handle;
- struct sockaddr_storage if_addr, localhost, mcast_addr;
- char tmp[132];
- char *transportstr;
- int ret = 0;
- const char *tx_mech_to_str[] = {
- [TX_MECH_UDP] = "udp",
- [TX_MECH_UDPB] = "udp",
- [TX_MECH_UDPU] = "udpu",
- [TX_MECH_RDMA] = "iba",
- };
-
- if (num_interfaces >= 2) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Configuration of more than 2 rings is not supported");
- return -1;
- }
-
- memset(&mcast_addr, 0, sizeof(mcast_addr));
- memset(&localhost, 0, sizeof(localhost));
- memset(&if_addr, 0, sizeof(if_addr));
-
- /* Check the families match */
- if (address_family(mcast, &mcast_addr, 0) !=
- address_family(ifaddr, &if_addr, mcast_addr.ss_family)) {
- snprintf(error_reason, sizeof(error_reason) - 1, "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)) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Node name resolves to localhost, please check /etc/hosts and assign this node a network IP 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 (!altiface) {
- if (objdb_get_string(objdb, totem_object_handle, "transport", &transportstr)) {
- objdb->object_key_create_typed(totem_object_handle, "transport",
- tx_mech_to_str[transport], strlen(tx_mech_to_str[transport]) + 1, OBJDB_VALUETYPE_STRING);
- } else {
- snprintf(error_reason, sizeof(error_reason) - 1, "Transport should not be specified within <totem .../>, use <cman transport=\"...\" /> instead");
- return -1;
- }
- }
-
- if (objdb->object_create(totem_object_handle, &interface_object_handle,
- "interface", strlen("interface")) == 0) {
- struct sockaddr_in *in = (struct sockaddr_in *)&if_addr;
- struct sockaddr_in6 *in6= (struct sockaddr_in6 *)&if_addr;
- void *addrptr;
-
- snprintf(tmp, sizeof(tmp) - 1, "%d", num_interfaces);
- objdb->object_key_create_typed(interface_object_handle, "ringnumber",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- if (if_addr.ss_family == AF_INET)
- addrptr = &in->sin_addr;
- else
- addrptr = &in6->sin6_addr;
- inet_ntop(if_addr.ss_family, addrptr, tmp, sizeof(tmp));
- objdb->object_key_create_typed(interface_object_handle, "bindnetaddr",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- switch (transport) {
- case TX_MECH_UDPB:
- objdb->object_key_create_typed(interface_object_handle, "broadcast",
- "yes", strlen("yes")+1, OBJDB_VALUETYPE_STRING);
- break;
- case TX_MECH_UDP:
- case TX_MECH_RDMA:
- objdb->object_key_create_typed(interface_object_handle, "mcastaddr",
- mcast, strlen(mcast)+1, OBJDB_VALUETYPE_STRING);
- break;
- case TX_MECH_UDPU:
- add_udpu_members(objdb, interface_object_handle);
- break;
- }
-
- snprintf(tmp, sizeof(tmp) - 1, "%d", port);
- objdb->object_key_create_typed(interface_object_handle, "mcastport",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- /* paranoia check. corosync already does it */
- if ((intttl < 0) || (intttl > 255)) {
- snprintf(error_reason, sizeof(error_reason) - 1, "TTL value (%u) out of range (0 - 255)", ttl);
- return -1;
- }
-
- /* add the key to the objdb only if value is not default */
- if (intttl != 1) {
- snprintf(tmp, sizeof(tmp) - 1, "%d", ttl);
- objdb->object_key_create_typed(interface_object_handle, "ttl",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
- }
-
- num_interfaces++;
- }
- return ret;
-}
-
-static uint16_t generate_cluster_id(char *name)
-{
- int i;
- int value = 0;
-
- for (i=0; i<strlen(name); i++) {
- value <<= 1;
- value += name[i];
- }
- return value & 0xFFFF;
-}
-
-static char *default_mcast(char *node, int altiface)
-{
- struct addrinfo *ainfo;
- struct addrinfo ahints;
- int ret;
- int family;
- static char addr[132];
- uint16_t clusterid = cluster_id + altiface;
-
- memset(&ahints, 0, sizeof(ahints));
-
- /* Lookup the the nodename address and use it's IP type to
- default a multicast address */
- ret = getaddrinfo(node, NULL, &ahints, &ainfo);
- if (ret) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Can't determine address family of nodename %s\n", node);
- write_cman_pipe("Can't determine address family of nodename");
- return NULL;
- }
-
- family = ainfo->ai_family;
- freeaddrinfo(ainfo);
-
- if (family == AF_INET) {
- snprintf(addr, sizeof(addr), "239.192.%d.%d", clusterid >> 8, clusterid % 0xFF);
- return strdup(addr);
- }
- if (family == AF_INET6) {
- snprintf(addr, sizeof(addr), "ff15::%x", clusterid);
- return strdup(addr);
- }
-
- return NULL;
-}
-
-static int verify_nodename(struct objdb_iface_ver0 *objdb, char *node)
-{
- 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;
- hdb_handle_t nodes_handle;
- hdb_handle_t find_handle = 0;
- int found = 0;
-
- /* nodename is either from commandline or from uname */
- if (nodelist_byname(objdb, cluster_parent_handle, node))
- return 0;
-
- /* If nodename was from uname, try a domain-less version of it */
- strncpy(nodename2, node, sizeof(nodename2) - 1);
- dot = strchr(nodename2, '.');
- if (dot) {
- *dot = '\0';
-
- if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
- strncpy(node, nodename2, MAX_CLUSTER_MEMBER_NAME_LEN - 1);
- 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);
- while (nodes_handle) {
- int len;
-
- if (objdb_get_string(objdb, nodes_handle, "name", &str)) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Cannot get node name");
- nodes_handle = nodeslist_next(objdb, find_handle);
- continue;
- }
-
- strncpy(nodename3, str, sizeof(nodename3) - 1);
- dot = strchr(nodename3, '.');
- if (dot)
- len = dot-nodename3;
- else
- len = strlen(nodename3);
-
- if (strlen(nodename2) == len &&
- !strncmp(nodename2, nodename3, len)) {
- strncpy(node, str, sizeof(nodename) - 1);
- return 0;
- }
- nodes_handle = nodeslist_next(objdb, find_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.
- */
- if (getifaddrs(&ifa_list))
- return -1;
-
- for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
- socklen_t salen = 0;
-
- /* Restore this */
- strncpy(nodename2, node, sizeof(nodename2) - 1);
- sa = ifa->ifa_addr;
- if (!sa)
- continue;
- if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6)
- continue;
-
- if (sa->sa_family == AF_INET)
- salen = sizeof(struct sockaddr_in);
- if (sa->sa_family == AF_INET6)
- salen = sizeof(struct sockaddr_in6);
-
- if (getnameinfo(sa, salen,
- nodename2, sizeof(nodename2),
- NULL, 0, 0) == 0) {
-
- if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
- strncpy(node, nodename2, sizeof(nodename) - 1);
- found = 1;
- goto out;
- }
-
- /* Truncate this name and try again */
- dot = strchr(nodename2, '.');
- if (dot) {
- *dot = '\0';
-
- if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
- strncpy(node, nodename2, sizeof(nodename) - 1);
- found = 1;
- goto out;
- }
- }
- }
-
- /* See if it's the IP address that's in cluster.conf */
- if (getnameinfo(sa, sizeof(*sa),
- nodename2, sizeof(nodename2),
- NULL, 0, NI_NUMERICHOST))
- continue;
-
- if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
- strncpy(node, nodename2, sizeof(nodename) - 1);
- found = 1;
- goto out;
- }
- }
-
- out:
- if (found) {
- freeifaddrs(ifa_list);
- return 0;
- }
-
- /*
- * This section covers the usecase where the nodename specified in cluster.conf
- * is an alias specified in /etc/hosts. For example:
- * <ipaddr> hostname alias1 alias2
- * and <clusternode name="alias2">
- * the above calls use uname and getnameinfo does not return aliases.
- * here we take the name specified in cluster.conf, resolve it to an address
- * and then compare against all known local ip addresses.
- * if we have a match, we found our nodename. In theory this chunk of code
- * could replace all the checks above, but let's avoid any possible regressions
- * and use it as last.
- */
-
- nodes_handle = nodeslist_init(objdb, cluster_parent_handle, &find_handle);
- while (nodes_handle) {
- char *dbnodename = NULL;
- struct addrinfo hints;
- struct addrinfo *result = NULL, *rp = NULL;
-
- if (objdb_get_string(objdb, nodes_handle, "name", &dbnodename)) {
- goto next;
- }
-
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_flags = 0;
- hints.ai_protocol = IPPROTO_UDP;
-
- if (getaddrinfo(dbnodename, NULL, &hints, &result))
- goto next;
-
- for (rp = result; rp != NULL; rp = rp->ai_next) {
- for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
- if (ipaddr_equal((struct sockaddr_storage *)rp->ai_addr,
- (struct sockaddr_storage *)ifa->ifa_addr)) {
- freeaddrinfo(result);
- strncpy(node, dbnodename, sizeof(nodename) - 1);
- found = 1;
- goto out2;
- }
- }
- }
-
- freeaddrinfo(result);
- next:
- nodes_handle = nodeslist_next(objdb, find_handle);
- }
- out2:
- objdb->object_find_destroy(find_handle);
- freeifaddrs(ifa_list);
-
- if (found) {
- return 0;
- }
-
- return -1;
-}
-
-/* Get any environment variable overrides */
-static int get_env_overrides(void)
-{
- 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 alternate port */
- if (getenv("CMAN_IP_ALTPORT")) {
- altportnum = atoi(getenv("CMAN_IP_ALTPORT"));
- }
-
- /* 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_ALTMCAST_ADDR")) {
- altmcast_name = getenv("CMAN_ALTMCAST_ADDR");
- }
-
- if (getenv("CMAN_2NODE")) {
- two_node = 1;
- expected_votes = 1;
- votes = 1;
- }
- if (getenv("CMAN_DEBUG")) {
- debug = atoi(getenv("CMAN_DEBUG"));
- if (debug > 0)
- debug = 1;
- }
-
- return 0;
-}
-
-
-static int get_nodename(struct objdb_iface_ver0 *objdb)
-{
- char *nodeid_str = NULL;
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
- hdb_handle_t node_object_handle;
- hdb_handle_t mcast_handle;
- hdb_handle_t alt_object;
- enum tx_mech transport = TX_MECH_UDP;
- char *str;
- int error;
- unsigned int mcast_portnum = DEFAULT_PORT;
- unsigned int altmcast_portnum = DEFAULT_PORT;
- char *altmcast_name_tmp = NULL;
- int broadcast = 0;
-
- if (!getenv("CMAN_NOCONFIG")) {
- /* our nodename */
- if (nodename_env != NULL) {
- if (strlen(nodename_env) >= sizeof(nodename)) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Overridden node name %s is too long", nodename);
- write_cman_pipe("Overridden node name is too long");
- error = -1;
- goto out;
- }
-
- strncpy(nodename, nodename_env, sizeof(nodename) - 1);
-
- if (!(node_object_handle = nodelist_byname(objdb, cluster_parent_handle, nodename))) {
- snprintf(error_reason, sizeof(error_reason) - 1, "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) {
- snprintf(error_reason, sizeof(error_reason) - 1, "cannot get node name, uname failed");
- write_cman_pipe("Can't determine local node name, uname failed");
- error = -1;
- goto out;
- }
-
- if (strlen(utsname.nodename) >= sizeof(nodename)) {
- snprintf(error_reason, sizeof(error_reason) - 1, "node name from uname is too long");
- write_cman_pipe("local node name is too long");
- error = -1;
- goto out;
- }
-
- strncpy(nodename, utsname.nodename, sizeof(nodename) - 1);
- }
- if (verify_nodename(objdb, nodename)) {
- write_cman_pipe("Cannot find node name in cluster.conf");
- return -1;
- }
-
- }
-
- /* Add <cman> 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)) {
- snprintf(error_reason, sizeof(error_reason) - 1, "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)) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Unable to find cman in config db");
- write_cman_pipe(error_reason);
- return -1;
- }
- objdb->object_find_destroy(find_handle);
-
- /* Check for broadcast */
- if (!objdb_get_string(objdb, object_handle, "broadcast", &str)) {
- if (strcmp(str, "yes") == 0) {
- broadcast = 1;
- transport = TX_MECH_UDPB;
- }
- }
-
- /* Check for transport */
- if (!objdb_get_string(objdb, object_handle, "transport", &str)) {
- if ((broadcast) && (strcmp(str, "udpb"))) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Transport and broadcast option are mutually exclusive");
- write_cman_pipe(error_reason);
- return -1;
- }
- if (strcmp(str, "udp") == 0) {
- transport = TX_MECH_UDP;
- } else if (strcmp(str, "udpb") == 0) {
- broadcast = 1;
- transport = TX_MECH_UDPB;
- } else if (strcmp(str, "udpu") == 0) {
- transport = TX_MECH_UDPU;
- } else if (strcmp(str, "rdma") == 0) {
- transport = TX_MECH_RDMA;
- } else {
- snprintf(error_reason, sizeof(error_reason) - 1, "Transport option value can be one of udp, udpb, udpu, rdma");
- write_cman_pipe(error_reason);
- return -1;
- }
- }
-
- if (broadcast) {
- mcast_name = strdup("255.255.255.255");
- if (!mcast_name) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Unable to set mcast_name");
- write_cman_pipe(error_reason);
- return -1;
- }
- altmcast_name = strdup("255.255.255.255");
- if (!altmcast_name) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Unable to set altmcast_name");
- write_cman_pipe(error_reason);
- return -1;
- }
- altmcast_portnum = DEFAULT_PORT + 2;
- }
-
- objdb->object_find_create(object_handle, "multicast", strlen("multicast"), &find_handle);
- if (objdb->object_find_next(find_handle, &mcast_handle) == 0) {
- if (!mcast_name)
- objdb_get_string(objdb, mcast_handle, "addr", &mcast_name);
- objdb_get_int(objdb, mcast_handle, "ttl", &ttl, ttl);
- objdb_get_int(objdb, mcast_handle, "port", &mcast_portnum, DEFAULT_PORT);
- }
- objdb->object_find_destroy(find_handle);
-
- if (!mcast_name) {
- mcast_name = default_mcast(nodename, PRIMARY_IFACE);
- }
-
- if (!mcast_name) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Unable to set mcast_name");
- write_cman_pipe(error_reason);
- return -1;
- }
-
- objdb->object_find_create(object_handle, "altmulticast", strlen("altmulticast"), &find_handle);
- if (objdb->object_find_next(find_handle, &mcast_handle) == 0) {
- objdb_get_string(objdb, mcast_handle, "addr", &altmcast_name_tmp);
- objdb_get_int(objdb, mcast_handle, "ttl", &altttl, ttl);
- if (!broadcast) {
- objdb_get_int(objdb, mcast_handle, "port", &altmcast_portnum, DEFAULT_PORT);
- } else {
- objdb_get_int(objdb, mcast_handle, "port", &altmcast_portnum, DEFAULT_PORT + 2);
- }
- }
- objdb->object_find_destroy(find_handle);
-
- /* 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_typed(object_handle, "nodename",
- nodename, strlen(nodename)+1, OBJDB_VALUETYPE_STRING);
-
- if (!nodeid_str) {
- snprintf(error_reason, sizeof(error_reason) - 1, "This node has no nodeid in cluster.conf");
- write_cman_pipe("This node has no nodeid in cluster.conf");
- return -1;
- }
-
- nodeid = atoi(nodeid_str);
- error = 0;
-
- /* optional port */
- if (!portnum) {
- objdb_get_int(objdb, object_handle, "port", &portnum, mcast_portnum);
- }
-
- if (add_ifaddr(objdb, mcast_name, nodename, portnum, ttl,
- PRIMARY_IFACE, transport)) {
- write_cman_pipe(error_reason);
- 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) {
- char *node;
-
- if (objdb_get_string(objdb, alt_object, "name", &node)) {
- continue;
- }
-
- objdb_get_int(objdb, alt_object, "port", &altportnum, altmcast_portnum);
-
- objdb_get_int(objdb, alt_object, "ttl", &altttl, altttl);
-
- if (!altmcast_name) {
- if (objdb_get_string(objdb, alt_object, "mcast", &altmcast_name)) {
- if (altmcast_name_tmp) {
- altmcast_name = altmcast_name_tmp;
- } else {
- altmcast_name = default_mcast(nodename, ALT_IFACE);
- }
- }
- }
-
- if (!altmcast_name) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Unable to determine alternate multicast name");
- write_cman_pipe(error_reason);
- return -1;
- }
-
- if (!strcmp(altmcast_name, mcast_name) &&
- ((altportnum == portnum) || (altportnum == portnum - 1) || (portnum == altportnum - 1))) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Alternate communication channel (mcast: %s ports: %d,%d) cannot use\n"
- "same address and ports of primary channel (mcast: %s ports: %d,%d)",
- altmcast_name, altportnum, altportnum - 1,
- mcast_name, portnum, portnum - 1);
- write_cman_pipe(error_reason);
- return -1;
- }
-
- if (add_ifaddr(objdb, altmcast_name, node, altportnum, altttl,
- ALT_IFACE, transport)) {
- write_cman_pipe(error_reason);
- return -1;
- }
-
- num_nodenames++;
- }
- objdb->object_find_destroy(find_handle);
-
-out:
- return error;
-}
-
-static void add_logging_overrides(struct objdb_iface_ver0 *objdb)
-{
- char *logstr;
- const char *logfacility;
- const char *loglevel;
- hdb_handle_t object_handle;
- hdb_handle_t 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);
- if (!logfacility)
- logfacility = "LOG_LOCAL4";
- loglevel = priority_name_get(SYSLOGLEVEL);
- if (!loglevel)
- loglevel = "LOG_INFO";
-
- /* enable timestamps on logging */
- if (objdb_get_string(objdb, object_handle, "timestamp", &logstr)) {
- objdb->object_key_create_typed(object_handle, "timestamp",
- "on", strlen("on")+1, OBJDB_VALUETYPE_STRING);
- }
-
- /* configure logfile */
- if (objdb_get_string(objdb, object_handle, "to_logfile", &logstr)) {
- objdb->object_key_create_typed(object_handle, "to_logfile",
- "yes", strlen("yes")+1, OBJDB_VALUETYPE_STRING);
- }
-
- if (objdb_get_string(objdb, object_handle, "logfile", &logstr)) {
- objdb->object_key_create_typed(object_handle, "logfile",
- LOGDIR "/corosync.log", strlen(LOGDIR "/corosync.log")+1, OBJDB_VALUETYPE_STRING);
- }
-
- if (objdb_get_string(objdb, object_handle, "logfile_priority", &logstr)) {
- objdb->object_key_create_typed(object_handle, "logfile_priority",
- loglevel, strlen(loglevel)+1, OBJDB_VALUETYPE_STRING);
- }
-
- /* syslog */
- if (objdb_get_string(objdb, object_handle, "to_syslog", &logstr)) {
- objdb->object_key_create_typed(object_handle, "to_syslog",
- "yes", strlen("yes")+1, OBJDB_VALUETYPE_STRING);
- }
-
- if (objdb_get_string(objdb, object_handle, "syslog_facility", &logstr)) {
- objdb->object_key_create_typed(object_handle, "syslog_facility",
- logfacility, strlen(logfacility)+1, OBJDB_VALUETYPE_STRING);
- }
-
- if (objdb_get_string(objdb, object_handle, "syslog_priority", &logstr)) {
- objdb->object_key_create_typed(object_handle, "syslog_priority",
- loglevel, strlen(loglevel)+1, OBJDB_VALUETYPE_STRING);
- }
-
- if (!debug) {
- hdb_handle_t logger_object_handle;
-
- if (!objdb_get_string(objdb, object_handle, "debug", &logstr)) {
- if (!strncmp(logstr, "on", 2)) {
- debug=1;
- }
- }
-
- logger_object_handle = find_cman_logger(objdb, object_handle);
- if (logger_object_handle > -1) {
- if (!objdb_get_string(objdb, logger_object_handle, "debug", &logstr)) {
- if (!strncmp(logstr, "on", 2)) {
- debug=1;
- }
- if (!strncmp(logstr, "off", 3)) {
- debug=0;
- }
- }
- }
- }
-
- if (debug) {
- objdb->object_key_create_typed(object_handle, "to_stderr",
- "yes", strlen("yes")+1, OBJDB_VALUETYPE_STRING);
- }
-
-
-}
-
-static int count_configured_nodes(struct objdb_iface_ver0 *objdb)
-{
- hdb_handle_t find_handle = 0;
- hdb_handle_t nodes_handle;
- int count = 0;
-
- nodes_handle = nodeslist_init(objdb, cluster_parent_handle, &find_handle);
- while (nodes_handle) {
- count++;
- nodes_handle = nodeslist_next(objdb, find_handle);
- }
- objdb->object_find_destroy(find_handle);
-
- return count;
-}
-
-/* These are basically cman overrides to the totem config bits */
-static void add_cman_overrides(struct objdb_iface_ver0 *objdb)
-{
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
- int node_count = 0;
- 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_typed(object_handle, "version",
- "2", 2, OBJDB_VALUETYPE_STRING);
-
- snprintf(tmp, sizeof(tmp) - 1, "%d", nodeid);
- objdb->object_key_create_typed(object_handle, "nodeid",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- objdb->object_key_create_typed(object_handle, "vsftype",
- "none", strlen("none")+1, OBJDB_VALUETYPE_STRING);
-
- /* 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)) {
- snprintf(tmp, sizeof(tmp) - 1, "%d", DEFAULT_TOKEN_TIMEOUT);
- objdb->object_key_create_typed(object_handle, "token",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
- }
-
- /* Extend join timeouts per bz#214290 */
- if (objdb_get_string(objdb, object_handle, "join", &value)) {
- objdb->object_key_create_typed(object_handle, "join",
- "60", strlen("60")+1, OBJDB_VALUETYPE_STRING);
- }
- /* Extend fail_to_recv_const, see bz#587078 */
- if (objdb_get_string(objdb, object_handle, "fail_recv_const", &value)) {
- objdb->object_key_create_typed(object_handle, "fail_recv_const",
- "2500", strlen("2500")+1, OBJDB_VALUETYPE_STRING);
- }
-
- /*
- * consensus should be:
- * 2 nodes - 200 ms <= consensus = token * 0.2 <= 2000
- * > 2 nodes - consensus = token + 2000
- *
- * autoconfig clusters will work as > 2 nodes
- *
- * See 611391#c19
- */
-
- node_count=count_configured_nodes(objdb);
-
- /* if we are running in autoconfig or we can't count the nodes, then play safe */
- if ((getenv("CMAN_NOCONFIG")) || (node_count == 0))
- node_count=3;
-
- if (objdb_get_string(objdb, object_handle, "consensus", &value)) {
- unsigned int token=0;
- unsigned int consensus;
- char calc_consensus[64];
-
- objdb_get_int(objdb, object_handle, "token", &token, DEFAULT_TOKEN_TIMEOUT);
-
- if (node_count > 2) {
- consensus = (float)token+2000;
- } else {
- consensus = (float)token*0.2;
- if (consensus < 200)
- consensus = 200;
- if (consensus > 2000)
- consensus = 2000;
- }
-
- snprintf(calc_consensus, sizeof(calc_consensus) - 1, "%d", consensus);
- objdb->object_key_create_typed(object_handle, "consensus",
- calc_consensus, strlen(calc_consensus)+1, OBJDB_VALUETYPE_STRING);
- }
-
- /* Set RRP mode appropriately */
- if (objdb_get_string(objdb, object_handle, "rrp_mode", &value)) {
- if (num_interfaces > 1) {
- objdb->object_key_create_typed(object_handle, "rrp_mode",
- "passive", strlen("passive")+1, OBJDB_VALUETYPE_STRING);
- }
- else {
- objdb->object_key_create_typed(object_handle, "rrp_mode",
- "none", strlen("none")+1, OBJDB_VALUETYPE_STRING);
- }
- }
-
- if (objdb_get_string(objdb, object_handle, "rrp_problem_count_threshold", &value)) {
- if (num_interfaces > 1) {
- objdb->object_key_create_typed(object_handle, "rrp_problem_count_threshold",
- "3", 2, OBJDB_VALUETYPE_STRING);
- }
- }
-
- if (objdb_get_string(objdb, object_handle, "secauth", &value)) {
- snprintf(tmp, sizeof(tmp) - 1, "%d", 1);
- objdb->object_key_create_typed(object_handle, "secauth",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
- }
-
- /* optional security key filename */
- if (!key_filename) {
- objdb_get_string(objdb, object_handle, "keyfile", &key_filename);
- }
- else {
- objdb->object_key_create_typed(object_handle, "keyfile",
- key_filename, strlen(key_filename)+1, OBJDB_VALUETYPE_STRING);
- }
- 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));
-
- strncpy(tmp, cluster_name, sizeof(tmp) - 1);
-
- /* Key length must be a multiple of 4 */
- keylen = (strlen(cluster_name)+4) & 0xFC;
- objdb->object_key_create_typed(object_handle, "key",
- tmp, keylen, OBJDB_VALUETYPE_STRING);
- }
- }
- objdb->object_find_destroy(find_handle);
-
- add_logging_overrides(objdb);
-
- /* Make sure we allow connections from user/group "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_typed(object_handle, "user",
- "ais", strlen("ais") + 1, OBJDB_VALUETYPE_STRING);
- objdb->object_key_create_typed(object_handle, "group",
- "ais", strlen("ais") + 1, OBJDB_VALUETYPE_STRING);
-
- 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];
-
- snprintf(str, sizeof(str) - 1, "%d", cluster_id);
-
- objdb->object_key_create_typed(object_handle, "cluster_id",
- str, strlen(str) + 1, OBJDB_VALUETYPE_STRING);
-
- if (two_node) {
- snprintf(str, sizeof(str) - 1, "%d", 1);
- objdb->object_key_create_typed(object_handle, "two_node",
- str, strlen(str) + 1, OBJDB_VALUETYPE_STRING);
- }
- }
- objdb->object_find_destroy(find_handle);
-
- /* Load the quorum service */
- objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
- "service", strlen("service"));
- objdb->object_key_create_typed(object_handle, "name",
- "corosync_quorum", strlen("corosync_quorum") + 1, OBJDB_VALUETYPE_STRING);
- objdb->object_key_create_typed(object_handle, "ver",
- "0", 2, OBJDB_VALUETYPE_STRING);
-
- /* 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_typed(object_handle, "name",
- "corosync_cman", strlen("corosync_cman") + 1, OBJDB_VALUETYPE_STRING);
- objdb->object_key_create_typed(object_handle, "ver",
- "0", 2, OBJDB_VALUETYPE_STRING);
-
- /* Define cman as the quorum provider for corosync */
- objdb->object_find_create(OBJECT_PARENT_HANDLE, "quorum", strlen("quorum"), &find_handle);
- if (objdb->object_find_next(find_handle, &object_handle) != 0) {
- objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
- "quorum", strlen("quorum"));
- }
- objdb->object_find_destroy(find_handle);
-
- objdb->object_key_create_typed(object_handle, "provider",
- "quorum_cman", strlen("quorum_cman") + 1, OBJDB_VALUETYPE_STRING);
-}
-
-/* If ccs is not available then use some defaults */
-static int set_noccs_defaults(struct objdb_iface_ver0 *objdb)
-{
- char tmp[255];
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
-
- /* Enforce key */
- key_filename = strdup(NOCCS_KEY_FILENAME);
- if (!key_filename) {
- snprintf(error_reason, sizeof(error_reason) - 1, "cannot allocate memory for key file name");
- write_cman_pipe("cannot allocate memory for key file name");
- return -1;
- }
-
- if (!cluster_name)
- cluster_name = strdup(DEFAULT_CLUSTER_NAME);
-
- if (!cluster_name) {
- snprintf(error_reason, sizeof(error_reason) - 1, "cannot allocate memory for cluster_name");
- write_cman_pipe("cannot allocate memory for cluster_name");
- return -1;
- }
-
- if (!cluster_id) {
- if (use_hashed_cluster_id)
- cluster_id = fnv_hash(cluster_name);
- else
- cluster_id = generate_cluster_id(cluster_name);
-
- snprintf(error_reason, sizeof(error_reason) - 1, "Generated cluster id for '%s' is %d\n", cluster_name, cluster_id);
- }
-
- if (!nodename_env) {
- int error;
- struct utsname utsname;
-
- error = uname(&utsname);
- if (error) {
- snprintf(error_reason, sizeof(error_reason) - 1, "cannot get node name, uname failed");
- write_cman_pipe("Can't determine local node name");
- return -1;
- }
-
- nodename_env = (char *)&utsname.nodename;
- }
- strncpy(nodename, nodename_env, sizeof(nodename) - 1);
- num_nodenames = 1;
-
- if (!mcast_name) {
- mcast_name = default_mcast(nodename, PRIMARY_IFACE);
- }
-
- /* 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) {
- snprintf(error_reason, sizeof(error_reason) - 1, "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 <clusternode> 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_typed(object_handle, "name",
- nodename, strlen(nodename)+1, OBJDB_VALUETYPE_STRING);
-
- snprintf(tmp, sizeof(tmp) - 1, "%d", votes);
- objdb->object_key_create_typed(object_handle, "votes",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- snprintf(tmp, sizeof(tmp) - 1, "%d", nodeid);
- objdb->object_key_create_typed(object_handle, "nodeid",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- /* Write the default cluster name & ID in here too */
- objdb->object_key_create_typed(cluster_parent_handle, "name",
- cluster_name, strlen(cluster_name)+1, OBJDB_VALUETYPE_STRING);
-
-
- 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"));
- }
- snprintf(tmp, sizeof(tmp) - 1, "%d", cluster_id);
- objdb->object_key_create_typed(object_handle, "cluster_id",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- snprintf(tmp, sizeof(tmp) - 1, "%d", expected_votes);
- objdb->object_key_create_typed(object_handle, "expected_votes",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- objdb->object_find_destroy(find_handle);
- return 0;
-}
-
-/* Move an object/key tree */
-static int copy_config_tree(struct objdb_iface_ver0 *objdb, hdb_handle_t source_object, hdb_handle_t target_parent_object, int always_create)
-{
- hdb_handle_t object_handle;
- hdb_handle_t new_object;
- hdb_handle_t find_handle;
- char object_name[1024];
- size_t object_name_len;
- void *key_name;
- size_t key_name_len;
- void *key_value;
- size_t 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, &new_object))
- 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_typed(new_object, key_name,
- key_value, key_value_len, OBJDB_VALUETYPE_STRING);
- }
-
- /* Create sub-objects */
- res = objdb->object_find_create(source_object, NULL, 0, &find_handle);
- if (res) {
- snprintf(error_reason, sizeof(error_reason) - 1, "error resetting object iterator for object %ud: %d\n", (unsigned int)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, always_create);
- }
- 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, const char *name, int always_create)
-{
- hdb_handle_t find_handle;
- hdb_handle_t 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)
-{
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
- char *use_hash;
-
- objdb_get_string(objdb, cluster_parent_handle, "name", &cluster_name);
- if (!cluster_name) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Unable to determine cluster name.\n");
- write_cman_pipe("Unable to determine cluster name.\n");
- return -1;
- }
-
- if (strlen(cluster_name) > 15) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Invalid cluster name. It must be 15 characters or fewer\n\n");
- write_cman_pipe("Invalid cluster name. It must be 15 characters or fewer\n");
- return -1;
- }
-
- /* Get the <cman> bits that override <totem> bits */
- objdb->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle);
- if (objdb->object_find_next(find_handle, &object_handle) == 0) {
- if (!key_filename)
- objdb_get_string(objdb, object_handle, "keyfile", &key_filename);
-
- objdb_get_string(objdb, object_handle, "hash_cluster_id", &use_hash);
- if (use_hash) {
- if (strncasecmp(use_hash, "yes", 3) == 0 || strncasecmp(use_hash, "on", 2) == 0)
- use_hashed_cluster_id = 1;
- }
-
- if (!cluster_id)
- objdb_get_int(objdb, object_handle, "cluster_id", &cluster_id, 0);
-
- if (!cluster_id) {
- if (use_hashed_cluster_id)
- cluster_id = fnv_hash(cluster_name);
- else
- cluster_id = generate_cluster_id(cluster_name);
-
- snprintf(error_reason, sizeof(error_reason) - 1, "Generated cluster id for '%s' is %d\n", cluster_name, cluster_id);
- }
- }
- objdb->object_find_destroy(find_handle);
- return 0;
-}
-
-static int cmanpre_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, const char **error_string)
-{
- int ret = -1;
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
- hdb_handle_t cluster_parent_handle_new;
- unsigned int config_version = 0, config_version_new = 0;
- char *config_value = NULL;
- char str[255];
-
- /* don't reload if we've been told to run configless */
- if (getenv("CMAN_NOCONFIG")) {
- snprintf(error_reason, sizeof(error_reason) - 1, "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);
- objdb->object_find_next(find_handle, &cluster_parent_handle_new);
- objdb->object_find_destroy(find_handle);
- if (!cluster_parent_handle) {
- snprintf (error_reason, sizeof(error_reason) - 1, "Cannot find old /cluster/ key in configuration\n");
- goto err;
- }
- if (!cluster_parent_handle_new) {
- snprintf (error_reason, sizeof(error_reason) - 1, "Cannot find new /cluster/ key in configuration\n");
- goto err;
- }
-
- if (!objdb->object_key_get(cluster_parent_handle, "config_version", strlen("config_version"), (void *)&config_value, NULL)) {
- if (config_value) {
- config_version = atoi(config_value);
- } else {
- /* it should never ever happen.. */
- snprintf (error_reason, sizeof(error_reason) - 1, "Cannot find old /cluster/config_version key in configuration\n");
- goto err;
- }
- }
-
- config_value = NULL;
-
- if (!objdb->object_key_get(cluster_parent_handle_new, "config_version", strlen("config_version"), (void *)&config_value, NULL)) {
- if (config_value) {
- config_version_new = atoi(config_value);
- } else {
- objdb->object_destroy(cluster_parent_handle_new);
- snprintf (error_reason, sizeof(error_reason) - 1,"Cannot find new /cluster/config_version key in configuration\n");
- goto err;
- }
- }
-
- if (config_version_new <= config_version) {
- objdb->object_destroy(cluster_parent_handle_new);
- snprintf (error_reason, sizeof(error_reason) - 1, "New configuration version has to be newer than current running configuration\n");
- goto err;
- }
-
- /* destroy the old one */
- objdb->object_destroy(cluster_parent_handle);
-
- /*
- * create cluster.cman in the new config if it doesn't exist
- */
- objdb->object_find_create(cluster_parent_handle_new, "cman", strlen("cman"), &find_handle);
- if (objdb->object_find_next(find_handle, &object_handle)) {
- objdb->object_create(cluster_parent_handle_new, &object_handle,
- "cman", strlen("cman"));
- }
- objdb->object_find_destroy(find_handle);
-
- /*
- * write cluster_id/two_node/nodename
- */
- snprintf(str, sizeof(str) - 1, "%d", cluster_id);
- objdb->object_key_create_typed(object_handle, "cluster_id",
- str, strlen(str) + 1, OBJDB_VALUETYPE_STRING);
-
- if (two_node) {
- snprintf(str, sizeof(str) - 1, "%d", 1);
- objdb->object_key_create_typed(object_handle, "two_node",
- str, strlen(str) + 1, OBJDB_VALUETYPE_STRING);
- }
-
- objdb->object_key_create_typed(object_handle, "nodename",
- nodename, strlen(nodename)+1, OBJDB_VALUETYPE_STRING);
-
- /* 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);
- ret = objdb->object_find_next(find_handle, &object_handle);
- objdb->object_find_destroy(find_handle);
- if (!ret) {
- objdb->object_destroy(object_handle);
- }
-
- /* copy /cluster/logging to /logging */
- ret = copy_tree_to_root(objdb, "logging", 1);
-
- /* Note: we do NOT delete /totem as corosync stores other things in there that
- it needs! */
-
- /* copy /cluster/totem to /totem */
- ret = copy_tree_to_root(objdb, "totem", 0);
-
- add_logging_overrides(objdb);
-
- return 0;
-
-err:
- *error_string = error_reason;
- return ret;
-}
-
-
-static hdb_handle_t find_or_create_object(struct objdb_iface_ver0 *objdb, const char *name, hdb_handle_t parent_handle)
-{
- hdb_handle_t find_handle;
- hdb_handle_t ret_handle = 0;
-
- objdb->object_find_create(parent_handle, name, strlen(name), &find_handle);
- objdb->object_find_next(find_handle, &ret_handle);
- objdb->object_find_destroy(find_handle);
-
- if (!ret_handle) {
- objdb->object_create(parent_handle, &ret_handle, name, strlen(name));
- }
-
- return ret_handle;
-}
-
-static const char *groupd_compat="groupd_compat";
-static const char *clvmd_interface="interface";
-static const char *cman_disallowed="disallowed";
-static const char *totem_crypto="crypto_accept";
-static const char *plock_ownership="plock_ownership";
-
-/*
- * Flags to set:
- * - groupd:
- * - clvmd
- * - disallowed (on)
- * - rgmanager
- */
-static void setup_old_compat(struct objdb_iface_ver0 *objdb, hdb_handle_t cluster_handle)
-{
- hdb_handle_t groupd_handle;
- hdb_handle_t clvmd_handle;
- hdb_handle_t cman_handle;
- hdb_handle_t totem_handle;
- hdb_handle_t gfs_handle;
- char *value;
-
- use_hashed_cluster_id = 0;
-
- /* Set groupd to backwards compatibility mode */
- groupd_handle = find_or_create_object(objdb, "group", cluster_handle);
- if (objdb->object_key_get(groupd_handle, groupd_compat, strlen(groupd_compat),
- (void *)&value, NULL) ||
- !value) {
- objdb->object_key_create_typed(groupd_handle, groupd_compat,
- "1", 2, OBJDB_VALUETYPE_STRING);
- }
-
- /* Make clvmd use cman */
- clvmd_handle = find_or_create_object(objdb, "clvmd", cluster_handle);
- if (objdb->object_key_get(clvmd_handle, clvmd_interface, strlen(clvmd_interface),
- (void *)&value, NULL) ||
- !value) {
- objdb->object_key_create_typed(clvmd_handle, clvmd_interface,
- "cman", 5, OBJDB_VALUETYPE_STRING);
- }
-
- /* Make cman use disallowed mode */
- cman_handle = find_or_create_object(objdb, "cman", cluster_handle);
- if (objdb->object_key_get(cman_handle, cman_disallowed, strlen(cman_disallowed),
- (void *)&value, NULL) ||
- !value) {
- objdb->object_key_create_typed(cman_handle, cman_disallowed,
- "1", 2, OBJDB_VALUETYPE_STRING);
- }
-
- /* Make totem use the old communications method */
- totem_handle = find_or_create_object(objdb, "totem", OBJECT_PARENT_HANDLE);
- if (objdb->object_key_get(totem_handle, totem_crypto, strlen(totem_crypto),
- (void *)&value, NULL) ||
- !value) {
- objdb->object_key_create_typed(totem_handle, totem_crypto,
- "old", 4, OBJDB_VALUETYPE_STRING);
- }
-
- /* Disable plock ownership */
- gfs_handle = find_or_create_object(objdb, "gfs_controld", OBJECT_PARENT_HANDLE);
- if (objdb->object_key_get(gfs_handle, plock_ownership, strlen(plock_ownership),
- (void *)&value, NULL) ||
- !value) {
- objdb->object_key_create_typed(gfs_handle, plock_ownership,
- "0", 2, OBJDB_VALUETYPE_STRING);
- }
-}
-
-static int cmanpre_readconfig(struct objdb_iface_ver0 *objdb, const char **error_string)
-{
- int ret = 0;
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
- char *str;
-
- 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", 1);
- 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);
- ret = copy_tree_to_root(objdb, "uidgid", 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);
-
- /* Set up STABLE2/RHEL5 compatibility modes */
- objdb_get_string(objdb, object_handle, "upgrading", &str);
- if (str && (strcasecmp(str, "on")==0 || strcasecmp(str, "yes")==0)) {
- setup_old_compat(objdb, cluster_parent_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_typed(object_handle, "next_handle",
- &next_handle, sizeof(uint32_t), OBJDB_VALUETYPE_UINT32);
- }
- 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) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Successfully parsed cman config\n");
- }
- else {
- if (error_reason[0] == '\0')
- snprintf(error_reason, sizeof(error_reason) - 1, "Error parsing cman config\n");
- }
- *error_string = error_reason;
-
-
- /* nullify stderr, because cman_tool tells corosync not to.
- This helps pass error messages back to the command-line, when
- debug is enabled.
- */
- if (!debug) {
- int tmpfd;
- tmpfd = open("/dev/null", O_RDWR);
- if (tmpfd > -1 && tmpfd != STDERR_FILENO) {
- dup2(tmpfd, STDERR_FILENO);
- close(tmpfd);
- }
-
- }
- return ret;
-}
-
-/* Write an error message down the CMAN startup pipe so
- that cman_tool can display it */
-int write_cman_pipe(const 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 1ec7eca..0000000
--- a/cman/daemon/cman.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* General cman bits */
-extern int write_cman_pipe(const char *message);
-extern void close_cman_pipe(void);
-extern int our_nodeid(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_TOKEN_TIMEOUT 10000
-#define DEFAULT_QUORUMDEV_POLL 10000
-#define DEFAULT_SHUTDOWN_TIMEOUT 5000
-#define DEFAULT_CCSD_POLL 1000
-#define DEFAULT_DISALLOWED 0
-#define DEFAULT_STARTUP_CONFIG_TIMEOUT 0
diff --git a/cman/daemon/cmanconfig.c b/cman/daemon/cmanconfig.c
deleted file mode 100644
index ca95609..0000000
--- a/cman/daemon/cmanconfig.c
+++ /dev/null
@@ -1,312 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <netinet/in.h>
-#include <syslog.h>
-#include <string.h>
-#include <errno.h>
-#include <netdb.h>
-
-#include <corosync/corotypes.h>
-#include <corosync/coroipc_types.h>
-#include <corosync/coroipcc.h>
-#include <corosync/corodefs.h>
-#include <corosync/mar_gen.h>
-#include <corosync/engine/coroapi.h>
-#include <corosync/engine/logsys.h>
-
-#include "list.h"
-#include "cnxman-socket.h"
-#include "cnxman-private.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);
-
-/* 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;
- unsigned int total_votes = 0;
- hdb_handle_t object_handle;
- hdb_handle_t nodes_handle;
- hdb_handle_t find_handle;
- char *nodename;
- int this_nodeid;
- hdb_handle_t 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);
- if (objdb_get_string(corosync, object_handle, "nodename", &our_nodename) != 0) {
- char message[132];
- snprintf(message, sizeof(message),
- "cman was unable to determine our node name!\n");
- log_printf(LOG_ERR, "%s", message);
- write_cman_pipe(message);
- error = -EINVAL;
- goto out_err;
- }
- 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 *)&this_nodeid, 0);
- if (check_nodeids && this_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;
- }
-
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: Got node %s from ccs (id=%d, votes=%d)\n", nodename, this_nodeid, votes);
- add_ccs_node(nodename, this_nodeid, votes, expected);
- nodes_handle = nodeslist_next(corosync, find_handle);
- total_votes += votes;
- } while (nodes_handle);
- corosync->object_find_destroy(find_handle);
-
- if (!expected)
- expected = total_votes;
-
- 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;
- hdb_handle_t object_handle;
- hdb_handle_t node_object;
- hdb_handle_t nodes_handle;
- hdb_handle_t find_handle;
- hdb_handle_t 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;
- }
-
- strncpy(cluster_name, cname, sizeof(cluster_name) - 1);
-
- 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 nodevotes;
-
- node_count++;
-
- objdb_get_int(corosync, nodes_handle, "votes", (unsigned int *)&nodevotes, 1);
- if (nodevotes < 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 += nodevotes;
- 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 (!votes && !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 > 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 is set but there are not 2 nodes in cluster.conf");
- 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 e6bb5dd..0000000
--- a/cman/daemon/cnxman-socket.h
+++ /dev/null
@@ -1,289 +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_UPDATE_QUORUMDEV 0x800000b8
-#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_GETNODE_EXTRA 0x000000c5
-
-#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 */
-#define CLUSTER_PORT_QDISKD 178 /* Quorum disk 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
-#define CMAN_EXTRA_FLAG_DISALLOWED_ENABLED 32
-
-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
- <n>*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;
-};
-
-struct cl_node_extra
-{
- int nodeid;
- int state;
- int votes;
- int expected_votes;
- int leave_reason;
-};
-
-
-/* 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 bbbc460..0000000
--- a/cman/daemon/commands.c
+++ /dev/null
@@ -1,2459 +0,0 @@
-#include <getopt.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <syslog.h>
-#include <string.h>
-#include <time.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/utsname.h>
-#include <sys/un.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/signal.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <sys/errno.h>
-#include <dlfcn.h>
-
-#include <corosync/corotypes.h>
-#include <corosync/coroipc_types.h>
-#include <corosync/coroipcc.h>
-#include <corosync/corodefs.h>
-#include <corosync/mar_gen.h>
-#include <corosync/engine/coroapi.h>
-#include <corosync/engine/logsys.h>
-#include "list.h"
-#include "cman.h"
-#include "cnxman-socket.h"
-#include "cnxman-private.h"
-#include "daemon.h"
-#include "barrier.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);
-
-/* 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;
- unsigned int enable_disallowed=DEFAULT_DISALLOWED;
- unsigned int startup_config_timeout=DEFAULT_STARTUP_CONFIG_TIMEOUT;
-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 int local_first_trans;
-
-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 int ccsd_timer_active = 0;
-
-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 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 const char *killmsg_reason(int reason);
-static void ccsd_timer_fn(void *arg);
-static int reload_config(int new_version, int should_broadcast);
-
-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<<bit;
-}
-
-static void clear_port_bit(struct cluster_node *node, uint8_t port)
-{
- int byte;
- int bit;
-
- byte = port/8;
- bit = port%8;
-
- node->port_bits[byte] &= ~(1<<bit);
-}
-
-static int get_port_bit(struct cluster_node *node, uint8_t port)
-{
- int byte;
- int bit;
-
- byte = port/8;
- bit = port%8;
-
- return ((node->port_bits[byte] & (1<<bit)) != 0);
-}
-
-static int have_disallowed(void)
-{
- struct cluster_node *node;
-
- if (!enable_disallowed)
- return 0;
-
- list_iterate_items(node, &cluster_members_list) {
- if (node->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;
- unsigned int nodelist[PROCESSOR_COUNT_MAX];
- int nodecount = 0;
- struct cluster_node *node = NULL;
- struct list *tmp;
-
- 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) {
-
- 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;
-
- /* Inform corosync subsystems */
- list_iterate(tmp, &cluster_members_list) {
- node = list_item(tmp, struct cluster_node);
- if (node->state == NODESTATE_MEMBER) {
- nodelist[nodecount++] = node->node_id;
- }
- }
-
- corosync_set_quorum(nodelist, nodecount, quorate, &cman_ring_id);
-}
-
-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 = strdup(name);
- if (!newnode->name) {
- if (newalloc)
- free(newnode);
- return NULL;
- }
- }
-
- 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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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 */
-
- strncpy(unode->name, node->name, MAX_CLUSTER_MEMBER_NAME_LEN - 1);
- 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 - 1);
- 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;
- if (uname(&un)) {
- return -EINVAL;
- }
- strncpy(nodename, un.nodename, sizeof(nodename) - 1);
- }
-
- 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;
-
- return reload_config(version->config, 1);
-}
-
-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;
- hdb_handle_t totem_object_handle;
- hdb_handle_t object_handle;
- hdb_handle_t totem_find_handle;
- hdb_handle_t 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));
- if (*retbuf == NULL)
- return -ENOMEM;
- outbuf = *retbuf + offset;
- einfo = (struct cl_extra_info *)outbuf;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
- if (enable_disallowed)
- einfo->flags |= CMAN_EXTRA_FLAG_DISALLOWED_ENABLED;
-
- 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_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);
- /* If this fails, it must be using broadcast*/
- if (!mcast)
- mcast = (char*)"255.255.255.255";
- 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);
- }
- corosync->object_find_destroy(totem_find_handle);
-
- for (i=0; i<num_interfaces; i++) {
- ss = (struct sockaddr_storage *)ptr;
- totemip_to_sockaddr(&node_ifs[i], 0, ss, &addrlen);
- ptr += sizeof(struct sockaddr_storage);
- }
-
- *retlen = ptr - outbuf;
- return 0;
-}
-
-static int do_cmd_get_all_members(char *cmdbuf, char **retbuf, int retsize, int *retlen, int offset)
-{
- struct cluster_node *node;
- struct cl_cluster_node *user_node;
- struct list *nodelist;
- char *outbuf = *retbuf + offset;
- int num_nodes = 0;
- int total_nodes = 0;
-
- if (!we_are_a_cluster_member)
- return -ENOENT;
-
- /* Count nodes */
- list_iterate(nodelist, &cluster_members_list) {
- total_nodes++;
- }
- if (quorum_device)
- total_nodes++;
-
- /* if retsize == 0 then don't return node information */
- if (retsize) {
- /* If there is not enough space in the default buffer, allocate some more. */
- if ((retsize / sizeof(struct cl_cluster_node)) < total_nodes) {
- *retbuf = malloc(sizeof(struct cl_cluster_node) * total_nodes + offset);
- if (!*retbuf)
- return -ENOMEM;
- outbuf = *retbuf + offset;
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: get_all_members: allocated new buffer (retsize=%d)\n", retsize);
- }
- }
- user_node = (struct cl_cluster_node *)outbuf;
-
- /* This returns the full list */
- list_iterate_items(node, &cluster_members_list) {
- if (retsize) {
- copy_to_usernode(node, user_node);
-
- user_node++;
- num_nodes++;
- }
- }
-
- if (quorum_device) {
- copy_to_usernode(quorum_device, user_node);
- user_node++;
- num_nodes++;
- }
-
- *retlen = sizeof(struct cl_cluster_node) * num_nodes;
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: get_all_members: retlen = %d\n", *retlen);
- return num_nodes;
-}
-
-
-static int do_cmd_get_cluster(char *cmdbuf, char *retbuf, int *retlen)
-{
- struct cl_cluster_info *info = (struct cl_cluster_info *)retbuf;
-
- info->number = 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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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_get_node_extra(char *cmdbuf, char *retbuf, int *retlen)
-{
- struct cluster_node *node;
- struct cl_node_extra *r_node = (struct cl_node_extra *)retbuf;
- int nodeid;
-
- if (!we_are_a_cluster_member)
- return -ENOENT;
-
- memcpy(&nodeid, cmdbuf, sizeof(int));
-
- if (nodeid == CLUSTER_GETNODE_QUORUMDEV) {
- return -EINVAL;
- }
- node = find_node_by_nodeid(nodeid);
- if (nodeid == 0)
- node = us;
- if (!node)
- return -EINVAL;
-
- r_node->votes = node->votes;
- r_node->expected_votes = node->expected_votes;
- r_node->state = node->state;
- r_node->leave_reason = node->leave_reason;
- r_node->nodeid = nodeid;
-
- *retlen = sizeof(struct cl_node_extra);
-
- 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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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)) {
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: islistening, no data for node %d, sending PORTENQ\n", nodeid);
- send_port_enquire(rem_node->node_id);
-
- /* Admit our ignorance */
- return -EBUSY;
- }
- else {
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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));
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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) {
- cman_finish();
- 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(void)
-{
- int reply;
- int leaveflags = CLUSTER_LEAVEFLAG_DOWN;
-
- /* All replies safely gathered in ? */
- if (shutdown_yes + shutdown_no >= shutdown_expected) {
-
- if (shutdown_timer)
- 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;
- }
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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)
-{
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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 || quit_threads)
- 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) {
- shutdown_timer = 0;
- check_shutdown_status();
- }
- 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;
- }
- return 0;
-}
-
-static void free_quorum_device(void)
-{
- if (!quorum_device)
- return;
-
- if (quorum_device->name)
- free(quorum_device->name);
-
- free(quorum_device);
-
- quorum_device = NULL;
-}
-
-static void quorum_device_update_votes(int votes)
-{
- int oldvotes;
-
- /* Update votes even if it existed before */
- oldvotes = quorum_device->votes;
- quorum_device->votes = votes;
-
- /* If it is a member and votes changed, recalculate quorum */
- if (quorum_device->state == NODESTATE_MEMBER &&
- oldvotes != votes) {
- recalculate_quorum(1, 0);
- }
-}
-
-static int do_cmd_register_quorum_device(char *cmdbuf, int *retlen)
-{
- int votes;
- char *name = cmdbuf+sizeof(int);
-
- if (!ais_running) {
- log_printf(LOG_ERR, "unable to register quorum device: corosync is not running\n");
- return -ENOTCONN;
- }
-
- if (!we_are_a_cluster_member) {
- log_printf(LOG_ERR, "unable to register quorum device: this node is not part of a cluster\n");
- return -ENOENT;
- }
-
- if (strlen(name) > MAX_CLUSTER_MEMBER_NAME_LEN) {
- log_printf(LOG_ERR, "unable to register quorum device: name is too long\n");
- /* this should probably return -E2BIG? */
- return -EINVAL;
- }
-
- /* Allow re-registering of a quorum device if the name is the same */
- if (quorum_device && strcmp(name, quorum_device->name)) {
- log_printf(LOG_ERR, "unable to re-register quorum device: device names do not match\n");
- log_printf(LOG_DEBUG, "memb: old name: %s new name: %s\n", quorum_device->name, name);
- return -EBUSY;
- }
-
- if (find_node_by_name(name)) {
- log_printf(LOG_ERR, "unable to register quorum device: a node with the same name (%s) already exists\n", name);
- return -EALREADY;
- }
-
- memcpy(&votes, cmdbuf, sizeof(int));
-
- /* A new quorum device */
- if (!quorum_device)
- {
- quorum_device = malloc(sizeof(struct cluster_node));
- if (!quorum_device) {
- log_printf(LOG_ERR, "unable to register quorum device: not enough memory\n");
- return -ENOMEM;
- }
- memset(quorum_device, 0, sizeof(struct cluster_node));
-
- quorum_device->name = strdup(name);
- if (!quorum_device->name) {
- log_printf(LOG_ERR, "unable to register quorum device: not enough memory\n");
- free_quorum_device();
- return -ENOMEM;
- }
-
- 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");
- }
- else
- {
- log_printf(LOG_INFO, "quorum device re-registered\n");
- }
-
- quorum_device_update_votes(votes);
-
- return 0;
-}
-
-static int do_cmd_unregister_quorum_device(char *cmdbuf, int *retlen)
-{
- if (!quorum_device) {
- log_printf(LOG_DEBUG, "memb: failed to unregister a non existing quorum device\n");
- return -EINVAL;
- }
-
- if (quorum_device->state == NODESTATE_MEMBER) {
- log_printf(LOG_DEBUG, "memb: failed to unregister: quorum device still active.\n");
- return -EBUSY;
- }
-
- free_quorum_device();
-
- log_printf(LOG_INFO, "quorum device unregistered\n");
- return 0;
-}
-
-static int do_cmd_update_quorum_device(char *cmdbuf, int *retlen)
-{
- int votes, ret = 0;
- char *name = cmdbuf+sizeof(int);
-
- if (!quorum_device) {
- log_printf(LOG_DEBUG, "memb: failed to update a non-existing quorum device\n");
- return -EINVAL;
- }
-
- memcpy(&votes, cmdbuf, sizeof(int));
-
- /* allow name change of the quorum device */
- if (quorum_device && strcmp(name, quorum_device->name)) {
- char *newname = NULL;
- char *oldname = NULL;
-
- log_printf(LOG_DEBUG, "memb: old name: %s new name: %s\n", quorum_device->name, name);
- newname = strdup(name);
- if (!newname) {
- log_printf(LOG_ERR, "memb: unable to update quorum device name: out of memory\n");
- ret = -ENOMEM;
- goto out;
- }
- log_printf(LOG_INFO, "quorum device name changed to %s\n", name);
- oldname = quorum_device->name;
- quorum_device->name = newname;
- free(oldname);
- }
-
-out:
- quorum_device_update_votes(votes);
-
- return ret;
-}
-
-static int reload_config(int new_version, int should_broadcast)
-{
- const char *reload_err = NULL;
-
- if (config_version == new_version) {
- log_printf(LOG_DEBUG, "We are already using config version [%d]\n",
- config_version);
- return 0;
- }
-
- if (new_version > 0 && new_version < config_version) {
- log_printf(LOG_ERR, "Requested version [%d] older than running version [%d]\n",
- new_version, config_version);
- return -1;
- }
-
- wanted_config_version = new_version;
-
- /* Tell objdb to reload */
- config_error = corosync->object_reload_config(1, &reload_err);
- if (config_error)
- log_printf(LOG_ERR, "Unable to load new config in corosync: %s\n",
- reload_err);
-
- if (!config_error)
- config_error = read_cman_nodes(corosync, &config_version, 0);
-
- if (config_error) {
- if (wanted_config_version) {
- log_printf(LOG_ERR, "Can't get updated config version %d: %s.\n",
- wanted_config_version, reload_err?reload_err:"version mismatch on this node");
- } else {
- log_printf(LOG_ERR, "Can't get updated config version: %s.\n",
- reload_err?reload_err:"version mismatch on this node");
- }
-
- if (should_broadcast) {
- log_printf(LOG_ERR, "Continuing activity with old configuration\n");
- config_error=0;
- return -2;
- } else {
- log_printf(LOG_ERR, "Activity suspended on this node\n");
-
- if (!ccsd_timer_active) {
- log_printf(LOG_ERR, "Error reloading the configuration, will retry every second\n");
- corosync->timer_add_duration((unsigned long long)ccsd_poll_interval*1000000, NULL,
- ccsd_timer_fn, &ccsd_timer);
- ccsd_timer_active = 1;
- }
- }
- } else {
-
- /*
- * at this point we know:
- * config is loaded in objdb with a newer version than the previous one
- * we have been able to activate it in cman (via read_cman_nodes)
- */
-
- if (should_broadcast) {
- log_printf(LOG_DEBUG, "Sending reconfigure message to all nodes\n");
- send_reconfigure(us->node_id, RECONFIG_PARAM_CONFIG_VERSION, config_version);
- }
-
- log_printf(LOG_DEBUG, "Recalculating quorum\n");
- recalculate_quorum(1, 0);
-
- log_printf(LOG_DEBUG, "Notify all listeners\n");
- notify_listeners(NULL, EVENT_REASON_CONFIG_UPDATE, config_version);
- }
- return config_error;
-}
-
-static void ccsd_timer_fn(void *arg)
-{
- log_printf(LOG_DEBUG, "Polling configuration for updated information\n");
-
- ccsd_timer_active = 0;
-
- if (!reload_config(wanted_config_version, 0) &&
- config_version >= wanted_config_version) {
- log_printf(LOG_DEBUG, "ccsd_timer_fn got the new config\n");
- config_error = 0;
- return;
- }
-
- if (local_first_trans) {
- time_t now;
- now = time(NULL);
-
- if (now > join_time+startup_config_timeout) {
- log_printf(LOG_ERR, "Checking for startup failure: time=%d\n", (int)(now - join_time));
- log_printf(LOG_ERR, "Failed to get an up-to-date config file, wanted %d, only got %d. Will exit\n",
- wanted_config_version, config_version);
- log_printf(LOG_ERR, "Check your configuration distribution method is working correctly\n");
- cman_finish();
- corosync_shutdown();
- }
- }
-}
-
-static void quorum_device_timer_fn(void *arg)
-{
- struct timeval now;
- unsigned long long timediff_us;
- if (!quorum_device || quorum_device->state == NODESTATE_DEAD)
- return;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: quorum_device_timer_fn\n");
- gettimeofday(&now, NULL);
- timediff_us=((now.tv_sec - quorum_device->last_hello.tv_sec)*1000000 + (now.tv_usec - quorum_device->last_hello.tv_usec));
- if (timediff_us >= quorumdev_poll*1000) {
- quorum_device->state = NODESTATE_DEAD;
- log_printf(LOG_INFO, "lost contact with quorum device\n");
- recalculate_quorum(0, 0);
- }
- else {
- corosync->timer_add_duration(1000*(quorumdev_poll*1000 - timediff_us),
- 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;
- strncpy(fence_msg->agent, f->fence_agent, MAX_FENCE_AGENT_NAME_LEN - 1);
- comms_send_message(msg, sizeof(msg), 0,0, 0, 0);
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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)
- strncpy(f->fence_agent, node->fence_agent, MAX_FENCE_AGENT_NAME_LEN - 1);
- 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) {
- addrs->numaddrs = 0;
- *retlen = sizeof(struct cl_get_node_addrs);
- return 0;
- }
-
- if (corosync->totem_ifaces_get(nodeid, node_ifs, &status, (unsigned int *)&addrs->numaddrs))
- return -errno;
-
- for (i=0; i<addrs->numaddrs; 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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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));
- /* sanitize input value */
- if (value > 0)
- value = 1;
-
- logsys_config_debug_set(CMAN_NAME, value);
- err = 0;
- break;
- 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_GETNODE_EXTRA:
- err = do_cmd_get_node_extra(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_UPDATE_QUORUMDEV:
- err = do_cmd_update_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;
- }
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: command return code is %d\n", err);
- return err;
-}
-
-
-int send_to_userport(unsigned char fromport, unsigned char toport,
- int nodeid, int tgtid,
- const char *recv_buf, int len,
- int endian_conv)
-{
- int ret = -1;
-
- if (toport == 0) {
-
- /* We need to make a private copy here so that the internal command
- * processors can do byteswapping.
- */
- char *newmsg = alloca(len);
- if (!newmsg)
- return -1;
- memcpy(newmsg, recv_buf, len);
- process_internal_message(newmsg, nodeid, endian_conv);
- ret = 0;
- }
- else {
- /* Send to external listener */
- if (port_array[toport]) {
- struct connection *c = port_array[toport];
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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(const unsigned int *member_list, size_t member_list_entries,
- const unsigned int *left_list, size_t left_list_entries,
- const unsigned int *joined_list, size_t 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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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(void)
-{
- 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;
- }
-
- if (local_first_trans) {
- time_t now;
- now = time(NULL);
-
- if (now > join_time+startup_config_timeout) {
- log_printf(LOG_DEBUG, "ccs: disable startup transition check\n");
- local_first_trans = 0;
- }
- }
-
- /* New config version - try to read new file */
- if (msg->config_version > config_version) {
- log_printf(LOG_DEBUG, "Reloading config from TRANSITION message\n");
- if (reload_config(msg->config_version, 0)) {
- 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;
- }
- }
- }
-
- if ((msg->config_version == config_version) && (nodeid != us->node_id)) {
- log_printf(LOG_DEBUG, "Completed first transition with nodes on the same config versions\n");
- local_first_trans = 0;
- }
-
- 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;
- local_first_trans = first_trans;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
- memcpy(msg->clustername, cluster_name, MAX_CLUSTER_NAME_LEN);
- if (us->fence_agent)
- {
- strncpy(msg->fence_agent, us->fence_agent, MAX_FENCE_AGENT_NAME_LEN - 1);
- 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_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:
- 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;
-
- /* We must be fully started by now */
- local_first_trans = 0;
-
- 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:
- reload_config(msg->value, 0);
- break;
- }
-}
-
-static void do_fence_msg(void *data)
-{
- struct cl_fencemsg *msg = data;
- struct cluster_node *node;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
- unsigned int old_expected;
- nodestate_t old_state;
-
- if (valid_transition_msg(nodeid, msg) != 0) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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 and we want to join,
- then we can't, as we don't know the full state */
- if (enable_disallowed &&
- local_first_trans && 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");
- cman_finish();
- 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);
- old_expected = node->expected_votes;
- old_state = node->state;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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 (enable_disallowed) {
- if ( (msg->flags & NODE_FLAGS_DIRTY && (node->flags & NODE_FLAGS_BEENDOWN)) ||
- (msg->flags & NODE_FLAGS_DIRTY && msg->first_trans && !node->us && (us->flags & NODE_FLAGS_DIRTY))) {
- /* Don't duplicate messages */
- if (node->state != NODESTATE_AISONLY) {
- if (cluster_is_quorate) {
- node->state = NODESTATE_AISONLY;
-
- /* Oh, this gets even more complicated. Don't send a KILL message if we are in a two_node
- * cluster and that node has a lower node ID than us.
- * This allows fencing time to startup and caters for the situation where
- * a node rejoins REALLY quickly, before fencing has had time to work.
- * I've split this up a bit partly for clarity, but mainly so allow us to
- * print out helpful messages as to what we are up to here.
- */
- if (two_node) {
- if (node->node_id > us->node_id) {
- log_printf(LOG_CRIT, "Killing node %s because it has rejoined the cluster with existing state and has higher node ID", node->name);
- send_kill(nodeid, CLUSTER_KILL_REJOIN);
- }
- else {
- log_printf(LOG_CRIT, "Not killing node %s despite it rejoining the cluster with existing state, it has a lower node ID", node->name);
- }
- }
- else {
- log_printf(LOG_CRIT, "Killing node %s because it has rejoined the cluster with existing state", node->name);
- send_kill(nodeid, CLUSTER_KILL_REJOIN);
- }
- }
- else {
- 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) {
- 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 {
- 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);
- }
- }
- else {
- add_ais_node(nodeid, incarnation, num_ais_nodes);
- }
-
- /* If the new node is joining and the existing 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 (enable_disallowed &&
- msg->first_trans && !node->us && have_disallowed())
- 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;
- us->expected_votes = max(us->expected_votes, msg->expected_votes);
-
- if (old_state != node->state || old_expected != node->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 fencemsg[sizeof(struct cl_fencemsg)+strlen(node->fence_agent)+1];
- struct cl_fencemsg *fence_msg = (struct cl_fencemsg *)fencemsg;
-
- fence_msg->cmd = CLUSTER_MSG_FENCESTATUS;
- fence_msg->nodeid = nodeid;
- fence_msg->timesec = node->fence_time;
- fence_msg->fenced = 0;
- strncpy(fence_msg->agent, node->fence_agent, MAX_FENCE_AGENT_NAME_LEN - 1);
- comms_send_message(fencemsg, sizeof(fencemsg), 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];
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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);
- log_printf(LOGSYS_LEVEL_DEBUG, "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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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:
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: got TRANSITION from node %d\n", nodeid);
- do_process_transition(nodeid, data);
- break;
-
- case CLUSTER_MSG_KILLNODE:
- killmsg = (struct cl_killmsg *)data;
- log_printf(LOGSYS_LEVEL_DEBUG, "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));
- cman_finish();
- exit(1);
- }
- break;
-
- case CLUSTER_MSG_LEAVE:
- leavemsg = (struct cl_leavemsg *)data;
- log_printf(LOGSYS_LEVEL_DEBUG, "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);
- cman_finish();
- corosync_shutdown();
- }
-
- /* 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 *node, int nodeid, int votes, int expected_votes)
-{
- /* Update node entry */
- add_new_node(node, nodeid, votes, expected_votes, NODESTATE_DEAD);
-}
-
-void add_ais_node(int nodeid, uint64_t incar, int total_members)
-{
- struct cluster_node *node;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: add_ais_node ID=%d, incarnation = %" PRIu64 "\n",nodeid, incar);
-
- node = find_node_by_nodeid(nodeid);
- if (!node && total_members == 1) {
- node = us;
- log_printf(LOGSYS_LEVEL_DEBUG, "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 */
- snprintf(tempname, sizeof(tempname) - 1, "Node%d", nodeid);
- node = add_new_node(tempname, nodeid, 1, total_members, NODESTATE_DEAD);
- if (!node) {
- log_printf(LOG_ERR, "Unable to add newnode!\n");
- return;
- }
- }
-
- if (node->state == NODESTATE_DEAD || node->state == NODESTATE_LEAVING) {
- gettimeofday(&node->join_time, NULL);
- node->incarnation = incar;
- node->leave_reason = 0;
- /* If a node rejoins before it completes a leave,
- * we should not increment cluster_members */
- if (node->state != NODESTATE_LEAVING)
- cluster_members++;
- node->state = NODESTATE_MEMBER;
- recalculate_quorum(0, 0);
- }
-}
-
-void del_ais_node(int nodeid)
-{
- struct cluster_node *node;
- time_t t;
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
- memset(&node->port_bits, 0, sizeof(node->port_bits));
- cluster_members--;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: del_ais_node %s, leave_reason=%x\n", node->name, node->leave_reason);
- if (node->leave_reason == CLUSTER_LEAVEFLAG_REMOVED)
- recalculate_quorum(1, 1);
- else
- recalculate_quorum(0, 0);
- break;
-
- case NODESTATE_JOINING:
- case NODESTATE_DEAD:
- break;
- }
-}
-
-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 const 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:
- snprintf(msg, sizeof(msg) - 1, "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 af0b17a..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,
- const 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(const unsigned int *member_list, size_t member_list_entries,
- const unsigned int *left_list, size_t left_list_entries,
- const unsigned int *joined_list, size_t 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 b85557d..0000000
--- a/cman/daemon/daemon.c
+++ /dev/null
@@ -1,528 +0,0 @@
-#include <getopt.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <sys/stat.h>
-#include <sys/poll.h>
-#include <sys/socket.h>
-#include <sys/signal.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <sys/errno.h>
-
-#include <corosync/corotypes.h>
-#include <corosync/coroipc_types.h>
-#include <corosync/coroipcc.h>
-#include <corosync/corodefs.h>
-#include <corosync/mar_gen.h>
-#include <corosync/engine/coroapi.h>
-#include <corosync/engine/logsys.h>
-#include <corosync/totem/coropoll.h>
-
-#include "list.h"
-#include "cnxman-socket.h"
-#include "cnxman-private.h"
-#include "daemon.h"
-#include "commands.h"
-#include "barrier.h"
-#include "ais.h"
-#include "cman.h"
-
-LOGSYS_DECLARE_SUBSYS (CMAN_NAME);
-
-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;
-hdb_handle_t cs_poll_handle;
-uint32_t max_outstanding_messages = DEFAULT_MAX_QUEUED;
-
-static int process_client(hdb_handle_t handle, int fd, int revent, void *data);
-static void remove_client(hdb_handle_t 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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "daemon: Disconnecting. client has more that %d replies outstanding (%d)\n", max_outstanding_messages, con->num_write_msgs);
- remove_client(cs_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++;
- log_printf(LOGSYS_LEVEL_DEBUG, "daemon: queued last message, count is %d\n", con->num_write_msgs);
- poll_dispatch_modify(cs_poll_handle, con->fd, POLLIN | POLLOUT, process_client);
- }
- return 0;
-}
-
-static void remove_client(hdb_handle_t 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++;
- }
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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 */
- log_printf(LOGSYS_LEVEL_DEBUG, "daemon: Removing POLLOUT from fd %d\n", con->fd);
- poll_dispatch_modify(cs_poll_handle, con->fd, POLLIN, process_client);
- }
-}
-
-/* Dispatch a request from a CLIENT or ADMIN socket */
-static int process_client(hdb_handle_t 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));
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "daemon: bad magic in client command %x\n", msg->magic);
- send_status_return(con, msg->command, -EINVAL);
- return 0;
- }
- if (msg->version != CMAN_VERSION) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
- }
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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 *databuf = (char *)msg;
- int ret;
- uint8_t port;
- struct sock_data_header *dmsg = (struct sock_data_header *)msg;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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);
-
- databuf += 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(databuf, 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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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(hdb_handle_t 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, hdb_handle_t handle, con_type_t 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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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, const 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);
- }
-}
-
-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;
-}
-
-int cman_init(struct corosync_api_v1 *api)
-{
- int fd;
- struct sigaction sa;
-
- cs_poll_handle = api->poll_handle_get();
- 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, cs_poll_handle, CON_CLIENT);
- if (fd < 0)
- return -2;
-
- fd = open_local_sock(ADMIN_SOCKNAME, sizeof(ADMIN_SOCKNAME), 0600, cs_poll_handle, CON_ADMIN);
- if (fd < 0)
- return -2;
-
- /* Shutdown trap */
- sa.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &sa, NULL);
- sigaction(SIGINT, &sa, NULL);
- sigaction(SIGTERM, &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 49611b1..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, const 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(struct corosync_api_v1 *api);
-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/fnvhash.c b/cman/daemon/fnvhash.c
deleted file mode 100644
index 47e221a..0000000
--- a/cman/daemon/fnvhash.c
+++ /dev/null
@@ -1,93 +0,0 @@
-#include <stdint.h>
-#include "fnvhash.h"
-
-/***
- *
- * Fowler/Noll/Vo hash
- *
- * The basis of this hash algorithm was taken from an idea sent
- * as reviewer comments to the IEEE POSIX P1003.2 committee by:
- *
- * Phong Vo (http://www.research.att.com/info/kpv/)
- * Glenn Fowler (http://www.research.att.com/~gsf/)
- *
- * In a subsequent ballot round:
- *
- * Landon Curt Noll (http://www.isthe.com/chongo/)
- *
- * improved on their algorithm. Some people tried this hash
- * and found that it worked rather well. In an EMail message
- * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
- *
- * FNV hashes are designed to be fast while maintaining a low
- * collision rate. The FNV speed allows one to quickly hash lots
- * of data while maintaining a reasonable collision rate. See:
- *
- * http://www.isthe.com/chongo/tech/comp/fnv/index.html
- *
- * for more details as well as other forms of the FNV hash.
- ***
- *
- * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the
- * Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str().
- *
- ***
- *
- * Please do not copyright this code. This code is in the public domain.
- *
- * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
- * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
- * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * By:
- * chongo <Landon Curt Noll> /\oo/\
- * http://www.isthe.com/chongo/
- *
- * Share and Enjoy! :-)
- */
-
-/*
- * Modified to be a little more simple to understand and to provide a 16 bit
- * value rather then 32 bit for cluster id generation
- *
- * sdake(a)redhat.com
- */
-
-/* 32 bit magic FNV-1a prime */
-#define FNV_32_PRIME ((uint32_t)0x01000193)
-
-/* Default initialization for FNV-1a */
-#define FNV_32_INIT ((uint32_t)0x811c9dc5)
-
-uint16_t fnv_hash(char *str)
-{
- unsigned char *s = (unsigned char *)str;
- uint32_t hval = FNV_32_INIT;
- uint32_t ret;
-
- /*
- * FNV-1a hash each octet in the buffer
- */
- while (*s) {
- /*
- * xor the bottom with the current octet
- */
- hval ^= (uint32_t)*s++;
- /*
- * multiply by the 32 bit FNV magic prime mod 2^32
- */
- hval *= FNV_32_PRIME;
- }
-
- /*
- * Use XOR folding as recommended by authors of algorithm
- * to create a different hash size that is a power of two
- */
- ret = (hval >> 16) ^ (hval & 0xFFFF);
-
- return (ret);
-}
diff --git a/cman/daemon/fnvhash.h b/cman/daemon/fnvhash.h
deleted file mode 100644
index 65e9c11..0000000
--- a/cman/daemon/fnvhash.h
+++ /dev/null
@@ -1 +0,0 @@
-uint16_t fnv_hash(char *str);
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 <assert.h>
-
-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/nodelist.h b/cman/daemon/nodelist.h
deleted file mode 100644
index 4851387..0000000
--- a/cman/daemon/nodelist.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* These just make the access a little neater */
-static inline int objdb_get_string(OBJDB_API *corosync, hdb_handle_t object_service_handle,
- const char *key, char **value)
-{
- *value = NULL;
- if ( !(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, hdb_handle_t object_service_handle,
- const 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 hdb_handle_t nodeslist_init(OBJDB_API *corosync,
- hdb_handle_t cluster_parent_handle,
- hdb_handle_t *find_handle)
-{
- hdb_handle_t object_handle;
- hdb_handle_t find_handle1;
- hdb_handle_t find_handle2;
-
- corosync->object_find_create(cluster_parent_handle,"clusternodes", strlen("clusternodes"), &find_handle1);
- if (corosync->object_find_next(find_handle1, &object_handle) == 0)
- {
- hdb_handle_t 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 hdb_handle_t nodeslist_next(OBJDB_API *corosync, hdb_handle_t find_handle)
-{
- hdb_handle_t nodes_handle;
-
- if (corosync->object_find_next(find_handle, &nodes_handle) == 0)
- return nodes_handle;
- else
- return 0;
-}
-
-static inline hdb_handle_t nodelist_byname(OBJDB_API *corosync,
- hdb_handle_t cluster_parent_handle,
- char *name)
-{
- char *nodename;
- hdb_handle_t nodes_handle;
- hdb_handle_t 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 1ce42d6..0000000
--- a/cman/init.d/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-TARGET=cman cman.init.defaults
-
-INITDT=cman
-
-all: $(TARGET)
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-%: $(S)/%.in
- cat $^ | sed \
- -e 's#@SBINDIR@#${sbindir}#g' \
- -e 's#@INITDDIR@#${initddir}#g' \
- -e 's#@NOTIFYDDIR@#${notifyddir}#g' \
- -e 's#@CONFDIR@#${CONFDIR}#g' \
- -e 's#@CONFFILE@#${CONFFILE}#g' \
- > $@
-
-clean: generalclean
diff --git a/cman/init.d/cman.in b/cman/init.d/cman.in
deleted file mode 100644
index eb3c2d1..0000000
--- a/cman/init.d/cman.in
+++ /dev/null
@@ -1,1038 +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 fence_sanlockd
-# Required-Stop: $network $time fence_sanlockd
-# Default-Start:
-# Default-Stop:
-# Short-Description: Starts and stops cman
-# Description: Starts and stops the Cluster Manager set of daemons
-### END INIT INFO
-
-# set secure PATH
-PATH="/bin:/usr/bin:/sbin:/usr/sbin:@SBINDIR@"
-
-chkconfig2()
-{
- case "$1" in
- --levels)
- ls /etc/rc${2}.d/S*${3} > /dev/null 2>/dev/null
- return $?
- ;;
- *)
- ls /etc/rc*.d/S*${1} > /dev/null 2>/dev/null
- return $?
- ;;
- esac
-}
-
-success()
-{
- echo -ne "[ OK ]\r"
-}
-
-failure()
-{
- echo -ne "[FAILED]\r"
-}
-
-status()
-{
- pid=$(pidof $1 2>/dev/null)
- statusrtrn=$?
- if [ $statusrtrn -ne 0 ]; then
- echo "$1 is stopped"
- else
- echo "$1 (pid $pid) is running..."
- fi
- return $statusrtrn
-}
-
-# 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"
- netmanager=NetworkManager
-fi
-
-# deb based distros
-if [ ! -d /etc/sysconfig ]; then
- [ -f /etc/default/cluster ] && . /etc/default/cluster
- [ -f /etc/default/cman ] && . /etc/default/cman
- [ -z "$LOCK_FILE" ] && LOCK_FILE="/var/lock/cman"
- netmanager=network-manager
-fi
-
-# 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=60
-
-# 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 zero, quorum will
-# be ignored.
-[ -z "$CMAN_QUORUM_TIMEOUT" ] && CMAN_QUORUM_TIMEOUT=45
-
-# 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
-
-# CMAN_NOTIFYD_START - control the startup behaviour for cmannotifyd
-# the variable can take 3 values:
-# yes | will always start cmannotifyd
-# no | will never start cmannotifyd
-# conditional (default) | will start cmannotifyd only if scriptlets
-# are found in @NOTIFYDDIR@
-[ -z "$CMAN_NOTIFYD_START" ] && CMAN_NOTIFYD_START=conditional
-
-# CMAN_SSHD_START - control sshd startup behaviour
-# the variable can take 2 values:
-# yes | cman will start sshd as early as possible
-# no (default) | cman will not start sshd
-[ -z "$CMAN_SSHD_START" ] && CMAN_SSHD_START=no
-
-# CMAN_DAEMONS_START -- Set to "no" to disable {dlm,gfs,ocfs2}-controld daemons
-# execution from within cman init script
-# (Can be useful for some pacemaker-based setups).
-# values:
-# no | cman init will NOT start the daemons
-# empty or any other value (default) | cman init will start the daemons
-#CMAN_DAEMONS_START=
-
-# DLM_CONTROLD_OPTS -- allow extra options to be passed to dlm_controld daemon.
-[ -z "$DLM_CONTROLD_OPTS" ] && DLM_CONTROLD_OPTS=""
-
-# Allow tuning of DLM kernel config.
-# do NOT change unless instructed to do so.
-[ -z "$DLM_LKBTBL_SIZE" ] && DLM_LKBTBL_SIZE=""
-[ -z "$DLM_RSBTBL_SIZE" ] && DLM_RSBTBL_SIZE=""
-[ -z "$DLM_DIRTBL_SIZE" ] && DLM_DIRTBL_SIZE=""
-[ -z "$DLM_TCP_PORT" ] && DLM_TCP_PORT=""
-
-# FENCE_JOIN_TIMEOUT -- seconds to wait for fence domain join to
-# complete. If the join hasn't completed in this time, fence_tool join
-# exits with an error, and this script exits with an error. To wait
-# indefinitely set the value to -1.
-[ -z "$FENCE_JOIN_TIMEOUT" ] && FENCE_JOIN_TIMEOUT=20
-
-# 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").
-# When setting FENCE_JOIN to "no", it is important to also set
-# DLM_CONTROLD_OPTS="-f0" (at least) for correct operation.
-# Please note that clusters without fencing are not
-# supported by Red Hat except for MRG installations.
-[ -z "$FENCE_JOIN" ] && FENCE_JOIN="yes"
-
-# FENCED_OPTS -- allow extra options to be passed to fence daemon.
-[ -z "$FENCED_OPTS" ] && FENCED_OPTS=""
-
-# 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"
-
-# CMAN_JOIN_OPTS -- allows extra options to be passed to cman_tool when join
-# operation is performed.
-# NOTES:
-# $CLUSTERNAME automatically appends "-c $CLUSTERNAME"
-# $NODENAME automatically appends "-n $NODENAME"
-# $CONFIG_LOADER automatically appends "-C $CONFIG_LOADER"
-
-[ -n "$CMAN_JOIN_OPTS" ] && cman_join_opts="$CMAN_JOIN_OPTS"
-
-[ -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: COROSYNC_LDAP_URL or/and COROSYNC_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.
-[ -n "$CONFIG_LOADER" ] && cman_join_opts+=" -C $CONFIG_LOADER"
-
-# CONFIG_VALIDATION -- select default config validation behaviour
-# This can be:
-# FAIL - Use a very strict checking. The config will not be loaded if there
-# for any kind of warnings/errors.
-# WARN - Same as FAIL, but will allow the config to load (this is temporary
-# the default behaviour)
-# NONE - Disable config validation. Highly discouraged.
-[ -z "$CONFIG_VALIDATION" ] && CONFIG_VALIDATION=WARN
-cman_join_opts+=" -D$CONFIG_VALIDATION"
-
-# CMAN_LEAVE_OPTS -- allows extra options to be passed to cman_tool when leave
-# operation is performed.
-[ -n "$CMAN_LEAVE_OPTS" ] && cman_leave_opts="$CMAN_LEAVE_OPTS"
-
-# INITLOGLEVEL -- select how verbose the init script should be
-# possible values:
-# quiet - only one line notification for start/stop operations
-# terse (default) - show only required activity
-# full - show everything
-[ -z "$INITLOGLEVEL" ] && INITLOGLEVEL=terse
-
-# INITBREAKPOINT -- select cman init break point during startup
-# possible values:
-# setup - exit before executing cman
-# join - exit after executing cman
-# notify - exit after starting up notifyd (if enabled) and before quorum
-# quorum - exit after start qdiskd (if enabled) and wait for quorum
-# daemons - exit after starting all other daemons (if enabled)
-# all (default) - start all the stack
-#
-# invoking cman init with /etc/init.d/cman start <selected_breakpoint>
-# overrides configured breakpoint from default settings
-[ -z "$INITBREAKPOINT" ] && INITBREAKPOINT=""
-
-### generic wrapper functions
-
-ok() {
- if [ "$INITLOGLEVEL" != "quiet" ]; then
- success
- echo
- fi
-}
-
-nok() {
- echo -e "$errmsg"
- failure
- echo
- if [ "$currentaction" = "start" ]; then
- stop && rm -f $LOCK_FILE
- fi
- exit 1
-}
-
-none()
-{
- return 0
-}
-
-runwrap()
-{
- function=$1
- shift
- conditional=$1
- shift
- message="$@"
-
- if ! $conditional; then
- if [ "$INITLOGLEVEL" = "full" ]; then
- echo " $message... action not required"
- fi
- return 0
- fi
-
- if [ "$INITLOGLEVEL" != "quiet" ]; then
- echo -n " $message... "
- fi
- if $function; then
- ok
- else
- nok
- fi
-}
-
-check_exec()
-{
- exec=$1
-
- realexec="$(type -p $exec)"
- if [ -z "$realexec" ]; then
- errmsg="Unable to find $exec in PATH"
- return 1
- fi
- if [ ! -x "$realexec" ]; then
- errmsg="$realexec not executable"
- return 1
- fi
- return 0
-}
-
-start_daemon()
-{
- daemon=$1
- shift
- args="$@"
-
- check_exec $daemon || return $?
- status $daemon > /dev/null 2>&1 && return 0
- errmsg=$( $daemon $args 2>&1 )
-}
-
-check_sleep()
-{
- if ! sleep 0.01 > /dev/null 2>&1; then
- return 1
- fi
-}
-
-stop_daemon()
-{
- daemon=$1
- shift
- retryforsec=$1
-
- [ -z "$retryforsec" ] && retryforsec=30
- retries=0
-
- if check_sleep; then
- sleepfor=0.25
- retryforsec=$(($retryforsec * 4))
- else
- sleepfor=1
- fi
-
- while status $daemon > /dev/null 2>&1 && \
- [ $retries -lt $retryforsec ]; do
-
- errmsg=$( pkill -TERM $daemon ) || return 1
- sleep $sleepfor
- ((retries++))
- done
-
- ! status $daemon > /dev/null 2>&1
-}
-
-### check functions (enable/disable) (on/off)
-
-sshd_enabled()
-{
- case "$CMAN_SSHD_START" in
- yes)
- return 0
- ;;
- esac
- return 1
-}
-
-control_daemons_enabled()
-{
- [ "$CMAN_DAEMONS_START" = "no" ] && return 1
- return 0
-}
-
-dlm_controld_enabled()
-{
- control_daemons_enabled
- return $?
-}
-
-gfs_controld_enabled()
-{
- ! control_daemons_enabled && return 1
-
- if [ -f @INITDDIR@/gfs2-cluster ] && ! chkconfig2 gfs2-cluster; then
- return 0
- fi
- return 1
-}
-
-cluster_disabled_at_boot()
-{
- if grep -q nocluster /proc/cmdline && \
- [ "$(tty)" = "/dev/console" ]; then
- errmsg="not configured to run at boot"
- return 1
- fi
- return 0
-}
-
-network_manager_enabled()
-{
- if status $netmanager > /dev/null 2>&1 || \
- chkconfig2 $netmanager; then
- errmsg="\nNetwork Manager is either running or configured to run. Please disable it in the cluster."
- return 1
- fi
- return 0
-}
-
-mtab_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
-}
-
-cman_running()
-{
- cman_tool status > /dev/null 2>&1
-}
-
-# NOTE: this could probably grow a bit to do config sanity checks
-cman_checkconfig()
-{
- case "$CONFIG_LOADER" in
- ldapconfig)
- if [ -n "$COROSYNC_LDAP_URL" ] || [ -n "$COROSYNC_LDAP_BASEDN" ]; then
- if [ -n "$COROSYNC_LDAP_BINDDN" ]; then
- if [ -z "$LDAP_BINDPWD" ]; then
- errmsg="ldapconfig has been selected \
- but LDAP_BINDPWD is not set"
- return 1
- fi
- fi
- if [ -n "$LDAP_BINDPWD" ]; then
- if [ -z "$COROSYNC_LDAP_BINDDN" ]; then
- errmsg="ldapconfig has been selected \
- but LDAP_BINDDN is not set"
- return 1
- fi
- fi
- else
- errmsg="ldapconfig has been selected but neither \
- COROSYNC_LDAP_URL or COROSYNC_LDAP_BASEDN have been set"
- return 1
- fi
- ;;
- xmlconfig|"")
- configfile=@CONFDIR@/@CONFFILE@
- [ -n "$COROSYNC_CLUSTER_CONFIG_FILE" ] && \
- configfile=$COROSYNC_CLUSTER_CONFIG_FILE
-
- if [ ! -f $configfile ]; then
- errmsg="xmlconfig cannot find $configfile"
- return 1
- fi
- ;;
- esac
-}
-
-xend_bridged_net_enabled() {
- # Not a xen kernel
- [ -d /proc/xen ] || return 1
-
- # uanble to determine current runlevel
- current_runlevel=$( runlevel 2>/dev/null | \
- awk '{ print $2 }' 2>/dev/null )
- [ -z "$current_runlevel" ] && return 1
-
- # xend doesn't start at this runlevel.
- ! chkconfig2 --levels "$current_runlevel" xend 2>/dev/null && return 1
-
- # xend isn't configured to use bridged networking.
- [ ! -f /etc/xen/xend-config.sxp ] && return 1
-
- # xend isn't configured to use bridged networking.
- ! egrep \
- "^[[:blank:]]*\([[:blank:]]*network-script[[:blank:]]+(')?[[:blank:]]*${NETWORK_BRIDGE_SCRIPT}([[:blank:]]*\)|[[:blank:]]+)" \
- /etc/xen/xend-config.sxp >&/dev/null && return 1
-}
-
-qdiskd_enabled()
-{
- ccs_tool query /cluster/quorumd >/dev/null 2>&1
-}
-
-groupd_enabled()
-{
- groupd_compat="$(ccs_tool query /cluster/group/@groupd_compat \
- 2>/dev/null || true)"
-
- [ -z "$groupd_compat" ] && return 1
- [ "$groupd_compat" = 0 ] && return 1
- return 0
-}
-
-ocfs2_enabled()
-{
- ! control_daemons_enabled && return 1
- ocfs2_cluster="$(cat /sys/fs/ocfs2/cluster_stack 2>/dev/null || true)"
- [ "$ocfs2_cluster" != cman ] && return 1
- return 0
-}
-
-cmannotifyd_enabled()
-{
- case "$CMAN_NOTIFYD_START" in
- yes)
- return 0
- ;;
- conditional)
- if [ -n "$(ls -1 @NOTIFYDDIR@ 2>/dev/null)" ]; then
- return 0
- fi
- ;;
- esac
- return 1
-}
-
-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
- fi
-}
-
-### the real stuff starts here
-
-start_global()
-{
- ## global bits
- # guarantee enough limits
- ulimit -c unlimited
- # required for distributions that use tmpfs for /var/run
- mkdir -p /var/run/cluster
-}
-
-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
-
- modprobe netbk >& /dev/null || true
- modprobe netloop >& /dev/null || true
-
- 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 )
-}
-
-load_kernel_modules()
-{
- errmsg=$( modprobe configfs 2>&1 ) || return 1
- errmsg=$( modprobe dlm 2>&1 ) || return 1
-}
-
-unload_kernel_modules()
-{
- modprobe -r dlm > /dev/null 2>&1 || true
-}
-
-start_configfs()
-{
- mtab_configfs && return 0
- errmsg=$( mount -t configfs none /sys/kernel/config 2>&1 )
-}
-
-stop_configfs()
-{
- if mtab_configfs && \
- [ -z "$(ls -1 /sys/kernel/config)" ] && \
- [ -z "$(lsof -l +D /sys/kernel/config 2>/dev/null)" ]; then
- errmsg=$( umount /sys/kernel/config 2>&1 ) || return 1
- modprobe -r configfs > /dev/null 2>&1 || true
- fi
-}
-
-corosync_running()
-{
- [ -f /var/run/corosync.pid ] || return 1
-
- read corosync_pid foo < /var/run/corosync.pid
- if [ "$(pidof corosync)" == "$corosync_pid" ];then
- errmsg="Corosync Cluster Engine is already running"
- return 0
- fi
-
- return 1
-}
-
-start_cman()
-{
- check_exec cman_tool || return $?
- cman_running && return 0
- cman_checkconfig || return 1
- corosync_running && return 1
-
- tmpfile=$(mktemp -t cmanstartup.XXXXXXXXXX)
- if [ -z "$tmpfile" ]; then
- errmsg="Unable to create temporary file"
- return 1
- fi
-
- cman_tool -z -t $CMAN_CLUSTER_TIMEOUT -w join $cman_join_opts > $tmpfile 2>&1 &
-
- while status cman_tool >/dev/null 2>&1; do
- sleep 0.2
- done
-
- sleep 2
-
- if ! cman_running; then
- errmsg="$(cat $tmpfile) Check cluster logs for details"
- ret=1
- else
- if [ "$CONFIG_VALIDATION" = "WARN" ] && \
- [ -s $tmpfile ] && \
- grep -q Relax-NG $tmpfile ; then
- cat $tmpfile >&2
- fi
- pidof /usr/sbin/corosync > /var/run/cman.pid
- ret=0
- fi
-
- rm -f $tmpfile
- return $ret
-}
-
-wait_for_quorum()
-{
- if [ $CMAN_QUORUM_TIMEOUT -gt 0 ]; then
- errmsg=$( cman_tool -t $CMAN_QUORUM_TIMEOUT \
- -q wait 2>&1 ) || return 1
- fi
-}
-
-stop_cman()
-{
- if cman_running; then
- errmsg=$( cman_tool $cman_leave_opts -t $CMAN_SHUTDOWN_TIMEOUT \
- -w leave $cmanremove 2>&1 ) || return 1
- ok
- echo -n " Waiting for corosync to shutdown:"
- while status corosync > /dev/null 2>&1; do
- sleep 1
- echo -n "."
- done
- rm -f /var/run/cman.pid
- fi
- return 0
-}
-
-start_qdiskd()
-{
- start_daemon qdiskd "-Q" || return 1
-
- if [ "$INITLOGLEVEL" = "full" ]; then
- ok
- echo -n " Waiting for qdiskd to be active: "
- fi
- retries=0
- while ! cman_tool status |grep -q "Quorum device" && \
- status qdiskd > /dev/null 2>&1 && \
- [ $retries -lt 10 ]; do
- sleep 2
- if [ "$INITLOGLEVEL" = "full" ]; then
- echo -n "$retries "
- fi
- ((retries++))
- done
- status qdiskd > /dev/null 2>&1
-}
-
-stop_qdiskd()
-{
- stop_daemon qdiskd
-}
-
-start_groupd()
-{
- start_daemon groupd || return 1
-
- if [ "$INITLOGLEVEL" = "full" ]; then
- ok
- echo -n " Waiting groupd protocol negotiation: "
- fi
- retries=0
- while group_tool ls | \
- grep -q pending && [ $retries -lt 10 ]; do
- sleep 1
- if [ "$INITLOGLEVEL" = "full" ]; then
- echo -n "$retries "
- fi
- ((retries++))
- done
- return 0
-}
-
-stop_groupd()
-{
- stop_daemon groupd
-}
-
-start_fenced()
-{
- start_daemon fenced "$FENCED_OPTS"
-}
-
-stop_fenced()
-{
- stop_daemon fenced
-}
-
-start_dlm_controld()
-{
- start_daemon dlm_controld "$DLM_CONTROLD_OPTS" || return 1
-
- if [ "$INITLOGLEVEL" = "full" ]; then
- ok
- echo -n " Waiting dlm_controld to complete initialization: "
- fi
-
- retries=0
- while ! dlm_tool ls >/dev/null 2>&1 && [ $retries -lt 10 ]; do
- sleep 1
- if [ "$INITLOGLEVEL" = "full" ]; then
- echo -n "$retries "
- fi
- ((retries++))
- done
-
- return 0
-}
-
-stop_dlm_controld()
-{
- stop_daemon dlm_controld
-}
-
-start_ocfs2_controld()
-{
- start_daemon ocfs2_controld.cman
-}
-
-start_cmannotifyd()
-{
- start_daemon cmannotifyd
-}
-
-stop_cmannotifyd()
-{
- stop_daemon cmannotifyd
-}
-
-fence_sanlock_check()
-{
- service fence_sanlockd status > /dev/null 2>&1 &&
- echo " fence_sanlockd detected. Unfencing might take several minutes!"
- return 0
-}
-
-unfence_self()
-{
- # fence_node returns 0 on success, 1 on failure, 2 if unconfigured
- # 0 and 2 are ok. Everything else should report error.
- fence_err=$(fence_node -U 2>&1)
- case $? in
- 0|2)
- return 0
- ;;
- esac
- errmsg="$fence_err"
- return 1
-}
-
-join_fence_domain()
-{
- if ! cman_tool status | grep Flags | grep 2node \
- > /dev/null 2>&1; then
- errmsg=$( fence_tool join -w $FENCE_JOIN_TIMEOUT \
- 2>&1 ) || return 1
- else
- errmsg=$( fence_tool join -w $FENCE_JOIN_TIMEOUT \
- -m $FENCED_MEMBER_DELAY join \
- 2>&1 ) || return 1
- fi
-}
-
-leave_fence_domain()
-{
- if status fenced > /dev/null 2>&1; then
- errmsg=$( fence_tool leave -w 30 2>&1 )
- return $?
- fi
-}
-
-tune_dlm_config()
-{
- dlmdir="/sys/kernel/config/dlm/cluster"
-
- [ -n "$DLM_LKBTBL_SIZE" ] && [ -f $dlmdir/lkbtbl_size ] && \
- echo $DLM_LKBTBL_SIZE > $dlmdir/lkbtbl_size
-
- [ -n "$DLM_RSBTBL_SIZE" ] && [ -f $dlmdir/rsbtbl_size ] && \
- echo $DLM_RSBTBL_SIZE > $dlmdir/rsbtbl_size
-
- [ -n "$DLM_DIRTBL_SIZE" ] && [ -f $dlmdir/dirtbl_size ] && \
- echo $DLM_DIRTBL_SIZE > $dlmdir/dirtbl_size
-
- [ -n "$DLM_TCP_PORT" ] && [ -f $dlmdir/tcp_port ] && \
- echo $DLM_TCP_PORT > $dlmdir/tcp_port
-
- return 0
-}
-
-start()
-{
- currentaction="start"
- [ -n "$INITBREAKPOINT" ] && breakpoint="$INITBREAKPOINT"
- [ -n "$1" ] && breakpoint="$1"
-
- sshd_enabled && cd @INITDDIR@ && ./sshd start
-
- if [ "$INITLOGLEVEL" = "quiet" ]; then
- echoarg="-n"
- fi
-
- echo $echoarg "Starting cluster: "
-
- runwrap cluster_disabled_at_boot \
- none \
- "Checking if cluster has been disabled at boot"
-
- runwrap network_manager_enabled \
- none \
- "Checking Network Manager"
-
- runwrap start_global \
- none \
- "Global setup"
-
- runwrap xend_bridged_net_start \
- xend_bridged_net_enabled \
- "Enable Xend bridge net workaround"
-
- runwrap load_kernel_modules \
- none \
- "Loading kernel modules"
-
- runwrap start_configfs \
- none \
- "Mounting configfs"
-
- [ "$breakpoint" = "setup" ] && return 0
-
- runwrap start_cman \
- none \
- "Starting cman"
-
- [ "$breakpoint" = "join" ] && return 0
-
- runwrap start_cmannotifyd \
- cmannotifyd_enabled \
- "Starting cmannotifyd"
-
- [ "$breakpoint" = "notify" ] && return 0
-
- runwrap start_qdiskd \
- qdiskd_enabled \
- "Starting qdiskd"
-
- runwrap wait_for_quorum \
- none \
- "Waiting for quorum"
-
- [ "$breakpoint" = "quorum" ] && return 0
-
- runwrap start_groupd \
- groupd_enabled \
- "Starting groupd"
-
- runwrap start_fenced \
- none \
- "Starting fenced"
-
- runwrap start_dlm_controld \
- dlm_controld_enabled \
- "Starting dlm_controld"
-
- runwrap tune_dlm_config \
- none \
- "Tuning DLM kernel config"
-
- gfs_controld_enabled && cd @INITDDIR@ && ./gfs2-cluster start
-
- runwrap start_ocfs2_controld \
- ocfs2_enabled \
- "Starting ocfs2_controld"
-
- [ "$breakpoint" = "daemons" ] && return 0
-
- fence_sanlock_check
-
- runwrap unfence_self \
- none \
- "Unfencing self"
-
- runwrap join_fence_domain \
- fence_join_enabled \
- "Joining fence domain"
-}
-
-stop()
-{
- if [ "$INITLOGLEVEL" = "quiet" ]; then
- echoarg="-n"
- fi
-
- echo $echoarg "Stopping cluster: "
-
- runwrap leave_fence_domain \
- fence_join_enabled \
- "Leaving fence domain"
-
- gfs_controld_enabled && cd @INITDDIR@ && ./gfs2-cluster stop
-
- runwrap stop_dlm_controld \
- dlm_controld_enabled \
- "Stopping dlm_controld"
-
- runwrap stop_fenced \
- none \
- "Stopping fenced"
-
- runwrap stop_groupd \
- groupd_enabled \
- "Stopping groupd"
-
- runwrap stop_qdiskd \
- qdiskd_enabled \
- "Stopping qdiskd"
-
- runwrap stop_cman \
- none \
- "Stopping cman"
-
- runwrap stop_cmannotifyd \
- cmannotifyd_enabled \
- "Stopping cmannotifyd"
-
- runwrap unload_kernel_modules \
- none \
- "Unloading kernel modules"
-
- runwrap stop_configfs \
- none \
- "Unmounting configfs"
-}
-
-cmanstatus()
-{
- errmsg=$( status corosync 2>&1 )
- ret=$?
- if [ "$ret" != "0" ]; then
- if [ -f /var/run/cman.pid ]; then
- errmsg="Found stale pid file"
- return 1
- fi
- if [ -f $LOCK_FILE ]; then
- errmsg="Found stale lock file"
- return 2
- fi
- return $ret
- fi
-
- if ! cman_running; then
- errmsg="cman is not running"
- return 3
- fi
-
- if qdiskd_enabled; then
- errmsg=$( status qdiskd 2>&1 ) || return $?
- fi
-
- if groupd_enabled; then
- errmsg=$( status groupd 2>&1 ) || return $?
- fi
-
- errmsg=$( status fenced 2>&1 ) || return $?
- errmsg=$( status dlm_controld 2>&1 ) || return $?
-
- if cmannotifyd_enabled; then
- errmsg=$( status cmannotifyd 2>&1 ) || return $?
- fi
-}
-
-rtrn=0
-
-if [ "$EUID" != "0" ]; then
- echo "Only root can execute $0 script"
- exit 4
-fi
-
-# See how we were called.
-case "$1" in
-start)
- start "$2" && touch $LOCK_FILE
- if [ "$INITLOGLEVEL" = "quiet" ]; then
- success
- echo
- fi
-;;
-stop)
- cmanremove=""
- if [ -n "$2" ] && [ "$2" = "remove" ]; then
- cmanremove=remove
- fi
- stop && rm -f $LOCK_FILE
- if [ "$INITLOGLEVEL" = "quiet" ]; then
- success
- echo
- fi
-;;
-restart|reload|force-reload)
- cmanremove=remove
- stop && rm -f $LOCK_FILE
- start && touch $LOCK_FILE
-;;
-condrestart|try-restart)
- if cmanstatus; then
- cmanremove=remove
- stop && rm -f $LOCK_FILE
- start && touch $LOCK_FILE
- fi
-;;
-status)
- cmanstatus
- rtrn=$?
- if [ "$rtrn" = 0 ]; then
- echo "cluster is running."
- else
- echo -e "$errmsg"
- fi
-;;
-*)
- echo "Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
- rtrn=2
-;;
-esac
-
-exit $rtrn
diff --git a/cman/init.d/cman.init.defaults.in b/cman/init.d/cman.init.defaults.in
deleted file mode 100644
index e94f676..0000000
--- a/cman/init.d/cman.init.defaults.in
+++ /dev/null
@@ -1,132 +0,0 @@
-# CMAN_CLUSTER_TIMEOUT -- amount of time to wait for joinging a cluster
-# before giving up. If CMAN_CLUSTER_TIMEOUT is positive, then we will
-# wait CMAN_CLUSTER_TIMEOUT seconds before giving up and failing when
-# a cluster is not joined. If CMAN_CLUSTER_TIMEOUT is zero, then
-# wait indefinately for a cluster join. If CMAN_CLUSTER_TIMEOUT is
-# negative, do not check to see that the cluster has been joined
-#CMAN_CLUSTER_TIMEOUT=60
-
-# 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 zero, quorum will
-# be ignored.
-#CMAN_QUORUM_TIMEOUT=45
-
-# 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
-#CMAN_SHUTDOWN_TIMEOUT=60
-
-# CMAN_NOTIFYD_START - control the startup behaviour for cmannotifyd
-# the variable can take 3 values:
-# yes | will always start cmannotifyd
-# no | will never start cmannotifyd
-# conditional (default) | will start cmannotifyd only if scriptlets
-# are found in @NOTIFYDDIR@
-#CMAN_NOTIFYD_START=conditional
-
-# CMAN_SSHD_START - control sshd startup behaviour
-# the variable can take 2 values:
-# yes | cman will start sshd as early as possible
-# no (default) | cman will not start sshd
-#CMAN_SSHD_START=no
-
-# CMAN_DAEMONS_START -- Set to "no" to disable {dlm,gfs,ocfs2}-controld daemons
-# execution from within cman init script
-# (Can be useful for some pacemaker-based setups).
-# values:
-# no | cman init will NOT start the daemons
-# empty or any other value (default) | cman init will start the daemons
-#CMAN_DAEMONS_START=
-
-# DLM_CONTROLD_OPTS -- allow extra options to be passed to dlm_controld daemon.
-#DLM_CONTROLD_OPTS=""
-
-# Allow tuning of DLM kernel config.
-# do NOT change unless instructed to do so.
-#DLM_LKBTBL_SIZE=""
-#DLM_RSBTBL_SIZE=""
-#DLM_DIRTBL_SIZE=""
-#DLM_TCP_PORT=""
-
-# FENCE_JOIN_TIMEOUT -- seconds to wait for fence domain join to
-# complete. If the join hasn't completed in this time, fence_tool join
-# exits with an error, and this script exits with an error. To wait
-# indefinitely set the value to -1.
-#FENCE_JOIN_TIMEOUT=20
-
-# FENCED_MEMBER_DELAY -- amount of time to delay fence_tool join to allow
-# all nodes in cluster.conf to become cluster members. In seconds.
-#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").
-# When setting FENCE_JOIN to "no", it is important to also set
-# DLM_CONTROLD_OPTS="-f0" (at least) for correct operation.
-# Please note that clusters without fencing are not
-# supported by Red Hat except for MRG installations.
-#FENCE_JOIN="yes"
-
-# FENCED_OPTS -- allow extra options to be passed to fence daemon.
-#FENCED_OPTS=""
-
-# 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".
-#NETWORK_BRIDGE_SCRIPT="network-bridge"
-
-# CLUSTERNAME -- override clustername as specified in cluster.conf
-#CLUSTERNAME=""
-
-# NODENAME -- specify the nodename of this node. Default autodetected
-#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: COROSYNC_LDAP_URL or/and COROSYNC_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.
-#CONFIG_LOADER=xmlconfig
-
-# CONFIG_VALIDATION -- select default config validation behaviour
-# This can be:
-# FAIL - Use a very strict checking. The config will not be loaded if there
-# for any kind of warnings/errors.
-# WARN - Same as FAIL, but will allow the config to load (this is temporary
-# the default behaviour)
-# NONE - Disable config validation. Highly discouraged.
-#CONFIG_VALIDATION=WARN
-
-# CMAN_LEAVE_OPTS -- allows extra options to be passed to cman_tool when leave
-# operation is performed.
-#CMAN_LEAVE_OPTS=""
-
-# INITLOGLEVEL -- select how verbose the init script should be
-# possible values:
-# quiet - only one line notification for start/stop operations
-# terse (default) - show only required activity
-# full - show everything
-#INITLOGLEVEL=terse
-
-# INITBREAKPOINT -- select cman init break point during startup
-# possible values:
-# setup - exit before executing cman
-# join - exit after executing cman
-# notify - exit after starting up notifyd (if enabled) and before quorum
-# quorum - exit after start qdiskd (if enabled) and wait for quorum
-# daemons - exit after starting all other daemons (if enabled)
-# all (default) - start all the stack
-#
-# invoking cman init with /etc/init.d/cman start <selected_breakpoint>
-# overrides configured breakpoint from default settings
-#INITBREAKPOINT="all"
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 367129c..0000000
--- a/cman/lib/libcman.c
+++ /dev/null
@@ -1,1145 +0,0 @@
-#include <sys/types.h>
-#include <sys/un.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#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;
- strncpy(unode->cn_name, knode->name, sizeof(unode->cn_name) - 1);
- 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;
- struct msghdr msg;
-
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
-
- while (iovlen > 0)
- {
- msg.msg_iov = iovptr;
- msg.msg_iovlen = iovlen;
-
- len = sendmsg(fd, &msg, MSG_NOSIGNAL);
- 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 = (char *)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;
- int 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, FD_CLOEXEC); /* 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;
- } else
- fcntl(h->zero_fd, F_SETFD, FD_CLOEXEC); /* Set close-on-exec */
-
- 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->msg);
- free(smsg);
- if (res || (flags & CMAN_DISPATCH_TYPE_MASK) == 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->msg);
- free(smsg);
- if (res || (flags & CMAN_DISPATCH_TYPE_MASK) == 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->msg);
- free(smsg);
- if (res || (flags & CMAN_DISPATCH_TYPE_MASK) == 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) {
- if (bufptr != buf)
- free(bufptr);
- errno = EHOSTDOWN;
- return -1;
- }
-
- if (len < 0 &&
- (errno == EINTR || errno == EAGAIN)) {
- if (bufptr != buf)
- free(bufptr);
- return 0;
- }
-
- if (len < 0) {
- if (bufptr != buf)
- free(bufptr);
- 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;
- strncpy(cman_node.name, node->cn_name, sizeof(cman_node.name) - 1);
- 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_node_extra(cman_handle_t handle, int nodeid, cman_node_extra_t *node)
-{
- struct cman_handle *h = (struct cman_handle *)handle;
- int status;
- VALIDATE_HANDLE(h);
-
- status = info_call(h, CMAN_CMD_GETNODE_EXTRA, &nodeid, sizeof(int),
- node, sizeof(cman_node_extra_t));
- if (status < 0)
- return -1;
-
- 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;
- strncpy(binfo.name, name, sizeof(binfo.name) - 1);
- 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;
- strncpy(binfo.name, name, sizeof(binfo.name) - 1);
- 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;
- strncpy(binfo.name, name, sizeof(binfo.name) - 1);
-
- 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;
- strncpy(binfo.name, name, sizeof(binfo.name) - 1);
-
- 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;
-}
-
-static int cman_set_quorum_device(cman_handle_t handle,
- int ops,
- char *name, int votes)
-{
- struct cman_handle *h = (struct cman_handle *)handle;
- char buf[strlen(name)+1 + sizeof(int)];
- VALIDATE_HANDLE(h);
-
- memcpy(buf, &votes, sizeof(int));
- strncpy(buf+sizeof(int), name, strlen(name)+1 + sizeof(int) - 1);
- return info_call(h, ops, buf, strlen(name)+1+sizeof(int), NULL, 0);
-}
-
-int cman_register_quorum_device(cman_handle_t handle, char *name, int votes)
-{
- if ((!name) || (strlen(name) > MAX_CLUSTER_MEMBER_NAME_LEN) || (votes < 0))
- {
- errno = EINVAL;
- return -1;
- }
- return cman_set_quorum_device(handle, CMAN_CMD_REG_QUORUMDEV, name, votes);
-}
-
-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) {
- strncpy(info->qi_name, cman_node.name, sizeof(info->qi_name) - 1);
- info->qi_state = cman_node.state;
- info->qi_votes = cman_node.votes;
- }
- return ret;
-}
-
-int cman_update_quorum_device(cman_handle_t handle, char *name, int votes)
-{
- if ((!name) || (strlen(name) > MAX_CLUSTER_MEMBER_NAME_LEN) || (votes < 0))
- {
- errno = EINVAL;
- return -1;
- }
- return cman_set_quorum_device(handle, CMAN_CMD_UPDATE_QUORUMDEV, name, votes);
-}
-
-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)
- strncpy(agent, f.fence_agent, sizeof(f.fence_agent) - 1);
- *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;
- strncpy(f.fence_agent, agent, sizeof(f.fence_agent) - 1);
- return info_call(h, CMAN_CMD_UPDATE_FENCE_INFO, &f, sizeof(f), NULL, 0);
-}
diff --git a/cman/lib/libcman.h b/cman/lib/libcman.h
deleted file mode 100644
index 9f97875..0000000
--- a/cman/lib/libcman.h
+++ /dev/null
@@ -1,457 +0,0 @@
-#ifndef _LIBCMAN_H_
-#define _LIBCMAN_H_
-
-#include <netinet/in.h>
-
-#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;
-
-/*
- * Return from cman_get_node_extra()
- */
-typedef struct cman_node_extra
-{
- int cnx_nodeid;
- int cnx_state;
- int cnx_votes;
- int cnx_expected_votes;
- int cnx_leave_reason;
-} cman_node_extra_t;
-
-#define CLUSTER_LEAVEREASON_DOWN 0 /* Normal shutdown */
-#define CLUSTER_LEAVEREASON_KILLED 1 /* probably buy cman_tool */
-#define CLUSTER_LEAVEREASON_PANIC 2 /* Just disappeared */
-#define CLUSTER_LEAVEREASON_REMOVED 3 /* This one can reduce quorum */
-#define CLUSTER_LEAVEREASON_REJECTED 4 /* Not allowed into the cluster in the first place */
-#define CLUSTER_LEAVEREASON_INCONSISTENT 5 /* Our view of the cluster is in a minority */
-#define CLUSTER_LEAVEREASON_DEAD 6 /* Discovered to be dead */
-#define CLUSTER_LEAVEREASON_NORESPONSE 7 /* Didn't ACK message */
-
-#define CLUSTER_NODESTATE_JOINING 1
-#define CLUSTER_NODESTATE_MEMBER 2
-#define CLUSTER_NODESTATE_DEAD 3
-#define CLUSTER_NODESTATE_LEAVING 4
-#define CLUSTER_NODESTATE_DISALLOWED 5
-
-
-/*
- * 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
-#define CMAN_EXTRA_FLAG_DISALLOWED_ENABLED 32
-
-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);
-
-/*
- * This always gets info by nodeid.
- */
-int cman_get_node_extra(cman_handle_t handle, int nodeid, cman_node_extra_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);
-
-/*
- * These two fencing-related API calls are DEPRECATED from cluster3.
- * libfenced should be used instead.
- */
-int cman_get_fenceinfo(cman_handle_t handle, int nodeid, uint64_t *fence_time, int *fenced, char *agent);
-int cman_node_fenced(cman_handle_t handle, int nodeid, uint64_t fence_time, 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);
-
-/*
- * -----------------------------------------------------------------------------
- * 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);
-
-/*
- * 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
- *
- * register_quorum and update_quorum arguments are mandatory.
- * name has to be a valid null-terminated string and votes >= 0.
- *
- * 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);
-int cman_update_quorum_device(cman_handle_t handle, char *name, int votes);
-
-/*
- * 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/lib/libcman.pc.in b/cman/lib/libcman.pc.in
deleted file mode 100644
index 6084efd..0000000
--- a/cman/lib/libcman.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: libcman
-Version: @VERSION@
-Description: Cluster Manager library
-Requires:
-Libs: -L${libdir} -lcman
-Cflags: -I${includedir}
diff --git a/cman/man/Makefile b/cman/man/Makefile
deleted file mode 100644
index f7fbebf..0000000
--- a/cman/man/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-MANTARGET= \
- cman.5 \
- qdisk.5 \
- cman_tool.8 \
- qdiskd.8 \
- mkqdisk.8 \
- cmannotifyd.8 \
- cman_notify.8 \
- checkquorum.8
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-all:
-
-clean:
diff --git a/cman/man/checkquorum.8 b/cman/man/checkquorum.8
deleted file mode 100644
index 96f61f0..0000000
--- a/cman/man/checkquorum.8
+++ /dev/null
@@ -1,29 +0,0 @@
-.TH "checkquorum" "8" "February 2011" "" "Check Quorum Watchdog Script"
-.SH "NAME"
-checkquorum \- Check Quorum Watchdog Script
-.SH "SYNOPSIS"
-\fBcheckquorum
-.SH "DESCRIPTION"
-.PP
-The \fBcheckquorum\fP watchdog script, when copied to the
-.IR /etc/watchdog.d
-directory and after enabling/starting the watchdog daemon causes the node to reboot if quorum is
-lost and not regained within a user configurable amount of time (default: 60 seconds).
-.SH "OPTIONS"
-The checkquorum script includes several options which can be set by editing
-the script with a text editor.
-.TP
-.BR $wait_time
-Amount of time in seconds to wait after quorum is lost before trigger a reboot
-(Default: 60 seconds).
-.TP
-.BR $hardreboot
-Instantly reboot the machine without cleanly shutting down the system.
-Useful when the machine may hang on reboot. Set to 1 to hard reboot the
-system, 0 to do a normal reboot.
-.SH "NOTES"
-\fBcheckquorum\fP should never be called outside of watchdog except for
-debugging purposes.
-
-.SH "SEE ALSO"
-watchdog(8)
diff --git a/cman/man/cman.5 b/cman/man/cman.5
deleted file mode 100644
index 0311412..0000000
--- a/cman/man/cman.5
+++ /dev/null
@@ -1,211 +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 <cman> </cman> section of
-\fBcluster.conf\fP. Per-node configuration related to cman is placed
-in the standard <clusternode> </clusternode> sections. All cman
-configuration settings are optional; usually none are used. The <cman>
-section is placed under the <cluster> section in cluster.conf.
-
- <cluster>
- <cman>
- </cman>
- ...
- </cluster>
-.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:
-
- <cman port="6809">
- </cman>
-
-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:
-
- <cman expected_votes="3">
- </cman>
-
-If the cluster becomes partitioned, improper use of this option can result
-in more than one partition gaining quorum. In that event, nodes in each
-partition will enable cluster services.
-.in -7
-
-
-\fITwo node clusters\fR
-.in +7
-Ordinarily, the loss of quorum after one out of two nodes fails will prevent
-the remaining node from continuing (if both nodes have one vote.) Special
-configuration options can be set to allow the one remaining node to continue
-operating if the other fails. To do this only two nodes, each with one vote,
-can be defined in cluster.conf. The two_node and expected_votes values must
-then be set to 1 in the cman section as follows.
-
- <cman two_node="1" expected_votes="1">
- </cman>
-.in -7
-
-
-\fINode votes\fR
-.in +7
-By default, a node is given one vote toward the calculation of quorum.
-This can be changed by giving a node a specific number of votes as
-follows:
-
- <clusternode name="nd1" votes="2">
- </clusternode>
-.in -7
-
-
-\fINode ID\fR
-.in +7
-
-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.
-
- <clusternode name="nd1" nodeid="1">
- </clusternode>
-
-.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 corosync 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. Only one altname (2 interfaces
-in total) is valid for each node.
-
-Note that if you are using the DLM with cman/corosync then you MUST tell it
-to use SCTP as it's communications protocol as TCP does not support multihoming.
-
- <clusternode name="nd1" nodeid="1">
- <altname name="nd1a" port="6809" mcast="239.192.0.2"/>
- </clusternode>
-
- <dlm protocol="sctp"/>
-.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:
-
- <cman>
- <multicast addr="239.192.0.1"/>
- </cman>
-
-.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.
-
- <cman cluster_id="669">
- </cman>
-
-.in -7
-
-\fIcorosync security key\fR
-.in +7
-All traffic sent out by cman/corosync 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.
-
- <cman keyfile="/etc/cluster/corosync.key">
- </cman>
-
-Note that this only applies to cluster communication. The DLM does not encrypt
-traffic.
-.in -7
-
-
-\fIOther corosync parameters\fR
-.in +7
-When corosync is started by cman (cman_tool runs corosync), the corosync.conf
-file is not used. Many of the configuration parameters listed in
-corosync.conf can be set in cluster.conf instead. Cman will read
-corosync parameters from the following sections in cluster.conf and load
-them into corosync:
-
- <cluster>
- <totem />
- <event />
- <aisexec />
- <group />
- </cluster>
-
-See the
-.B corosync.conf(5)
-man page for more information on keys that are valid for these sections.
-Note that settings in the <clusternodes> 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 <clusternodes>.
-
-Cman uses different defaults for some of the corosync parameters listed in
-corosync.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:
-
- <totem
- vsftype="none"
- token="10000"
- token_retransmits_before_loss_const="20"
- join="60"
- consensus="4800"
- rrp_mode="none"
- <!-- or rrp_mode="active" if altname is present >
- />
- <aisexec user="root" group="root" />
-
-Here's how to set the token timeout to five seconds:
-
- <totem token="5000"/>
-
-.in -7
-
-
-.sp
-
-.SH "SEE ALSO"
-
-cluster.conf(5), corosync.conf(5), cman_tool(8)
-
diff --git a/cman/man/cman_notify.8 b/cman/man/cman_notify.8
deleted file mode 100644
index 446bf12..0000000
--- a/cman/man/cman_notify.8
+++ /dev/null
@@ -1,17 +0,0 @@
-.TH "cman_notify" "8" "November 2008" "" "CMAN Notification Daemon"
-.SH "NAME"
-cman_notify \- CMAN Notification Daemon run-part alike script
-.SH "SYNOPSIS"
-\fBcman_notify
-.SH "DESCRIPTION"
-.PP
-The \fBcmannotifyd\fP daemon talks to CMAN and provides a mechanism to notify
-external entities about cluster changes.
-\fBcman_notify\fP script is in charge to execute all notification scripts
-in a run-part alike way.
-.SH "NOTES"
-\fBcman_notify\fP should never be called standalone except for debugging
-purposes.
-
-.SH "SEE ALSO"
-cmannotifyd(8)
diff --git a/cman/man/cman_tool.8 b/cman/man/cman_tool.8
deleted file mode 100644
index 2f402a6..0000000
--- a/cman/man/cman_tool.8
+++ /dev/null
@@ -1,442 +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
-The recalculation takes into account the number of currently
-active nodes, so this option should not be used in an attempt to
-artificially lower the quorum value in advance of a planned shutdown of
-cluster nodes. Instead, the 'cman_tool leave remove' command should be
-used (see the 'leave' subcommand above).
-.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 the cluster configuration.
-.br
-If -r is specified, cman will read the configuration file,
-validate it, distribute it around the cluster (if necessary) an
-activate it. See the VERSION OPTIONS section below for additional
-options to the \fBversion\fP command.
-
-.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 <seconds>
-If -w is also specified then -t dictates the maximum amount of time cman_tool
-is prepared to wait. If the operation times out then a status of 2 is returned.
-.TP
-.I force
-Shuts down the cluster manager without first telling any of the subsystems
-to close down. Use this option with extreme care as it could easily cause data
-loss.
-.TP
-.I remove
-Tells the rest of the cluster to recalculate quorum such that activity can
-continue without this node.
-
-.SH "EXPECTED" OPTIONS
-.TP
-.I -e <expected-votes>
-The new value of expected votes to use. This will usually be enough
-to bring the cluster back to life. Values that would cause incorrect
-quorum will be rejected.
-
-.SH "KILL" OPTIONS
-.TP
-.I -n <nodename>
-The node name of the node to be killed. This should be the unqualified node
-name as it appears in 'cman_tool nodes'.
-
-.SH "VERSION" OPTIONS
-.TP
-.I -r
-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. The version present in the
-new configuration must be higher than the one currently in use by cman.
-.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 possibly not update immediately after you have run
-cman_tool version -r.
-.TP
-.I -D<option>
-see "JOIN" options
-.TP
-.I -S
-By default cman_tool version will try to distribute the new cluster.conf
-file using ccs_sync and ricci. If you have distributed the file yourself
-and/or do not have ricci installed then the -S option will skip this step.
-NOTE: it is still important that all nodes in the cluster have the
-same version of the file. Make sure that this is the case before using
-this option.
-.SH "WAIT" OPTIONS
-.TP
-.I -q
-Waits until the cluster is quorate before returning.
-.I -t <seconds>
-Dictates the maximum amount of time cman_tool is prepared to wait.
-If the operation times out then a status of 2 is returned.
-
-.br
-.SH "JOIN" OPTIONS
-.TP
-.I -c <clustername>
-Provides a text name for the cluster. You can have several clusters on one
-LAN and they are distinguished by this name. Note that the name is hashed to
-provide a unique number which is what actually distinguishes the cluster, so
-it is possible that two different names can clash. If this happens, the node
-will not be allowed into the existing cluster and you will have to pick
-another name or use different port number for cluster communication.
-.TP
-.I -p <port>
-UDP port number used for cluster communication. This defaults to 5405.
-.TP
-.I -v <votes>
-Number of votes this node has in the cluster. Defaults to 1.
-.TP
-.I -e <expected votes>
-Number of expected votes for the whole cluster. If different nodes
-provide different values then the highest is used. The cluster will
-only operate when quorum is reached - that is more than half the
-available votes are available to the cluster. 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 <nodename>
-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 <nodeid>
-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 <nodename>
-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 <multicast-address>
-Specifies a multicast address to use for cluster communication. This
-is required for IPv6 operation. You should also specify an ethernet
-interface to bind to this multicast address using the -i option.
-.TP
-.I -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 <keyfile>
-All traffic sent out by cman/corosync 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 <seconds>
-If -w or -q is also specified then -t dictates the maximum amount of time cman_tool
-is prepared to wait. If the operation times out then a status of 2 is returned.
-Note that just because cman_tool has given up, does not mean that cman itself
-has stopped trying to join a cluster.
-.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<nodeid>. 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
-corosync-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 xmlconfig (cluster.conf) 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 'xmlconfig'. 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 'openaisserviceenablestable' 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.
-.TP
-.I -D
-Tells cman_tool whether to validate the configuration before loading or reloading it.
-By default the configuration
-.B is
-validated, which is equivalent to -Dfail.
-.br
--Dwarn will validate the configuration and print any messages arising, but will attempt
-to use it regardless of its validity.
-.br
--Dnone (or just -D) will skip the validation completely.
-.br
-The -D switch does not take a space between -D and the parameter. so '-D fail' will cause
-an error. Use -Dfail.
-.SH "NODES" OPTIONS
-.TP
-.I -a
-Shows the IP address(es) the nodes are communicating on.
-.br
-.TP
-.I -n <nodename>
-Shows node information for a specific node. This should be the unqualified node
-name as it appears in 'cman_tool nodes'.
-.br
-.TP
-.I -F <format>
-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<value>
-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 Corosync
-.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 Corosync, 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 corosync.
-.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 corosync 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 corosync. 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 corosync. The first, 'xmlconfig', 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 corosync node name and nodeID
-and formats the information in a similar manner to corosync.conf(5). Corosync 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 xmlconfig, ie when 'cman_tool join' is run with -X switch (this removes xmlconfig 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 corosync 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.
-.br
-Most of the extra keys that cmanpreconfig adds are outside of the /cluster/ tree and will only be seen if you dump the whole of
-corosync's object database. However it does add some keys into /cluster/cman that you would not normally see in a normal cluster.conf
-file. These are harmless, though could be confusing. The most obvious of these is the "nodename" option which is passed from
-cmanpreconfig to the name cman module, to save it recalculating the node name again.
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 938ed69..0000000
--- a/cman/man/qdisk.5
+++ /dev/null
@@ -1,530 +0,0 @@
-.TH "QDisk" "5" "12 Oct 2011" "" "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 must all be 1.
-
-* 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. See section 3.3.1 for specific
-details.
-
-* 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 leave qdisk's vote count unset. 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
-.bi
-(b) that node has made enough consecutive, timely writes
-.in 16
-to the quorum disk, and
-.in 12
-(c) the node has a high enough score to consider itself online.
-.in 0
-
-.SH "3. Configuration"
-.SH "3.1. The <quorumd> tag"
-This tag is a child of the top-level <cluster> tag.
-
-.in 8
-\fB<quorumd\fP
-.in 9
-\fIinterval\fP\fB="\fP1\fB"\fP
-.in 12
-This is the frequency of read/write cycles, in seconds.
-
-.in 9
-\fItko\fP\fB="\fP10\fB"\fP
-.in 12
-This is the number of cycles a node must miss in order to be declared dead.
-The default for this number is dependent on the configured token timeout.
-
-.in 9
-\fItko_up\fP\fB="\fPX\fB"\fP
-.in 12
-This is the number of cycles a node must be seen in order to be declared
-online. Default is \fBfloor(tko/3)\fP.
-
-.in 9
-\fIupgrade_wait\fP\fB="\fP2\fB"\fP
-.in 12
-This is the number of cycles a node must wait before initiating a bid
-for master status after heuristic scoring becomes sufficient. The
-default is 2. This can not be set to 0, and should not exceed \fBtko\fP.
-
-.in 9
-\fImaster_wait\fP\fB="\fPX\fB"\fP
-.in 12
-This is the number of cycles a node must wait for votes before declaring
-itself master after making a bid. Default is \fBfloor(tko/2)\fP.
-This can not be less than 2, must be greater than tko_up, and should not
-exceed \fBtko\fP.
-
-.in 9
-\fIvotes\fP\fB="\fP3\fB"\fP
-.in 12
-This is the number of votes the quorum daemon advertises to CMAN when it
-has a high enough score. The default is the number of nodes in the cluster
-minus 1. For example, in a 4 node cluster, the default is 3. This value
-may change during normal operation, for example when adding or removing
-a node from the cluster.
-
-.in 9
-\fIlog_level\fP\fB="\fP4\fB"\fP
-.in 12
-This controls the verbosity of the quorum daemon in the system logs.
-0 = emergencies; 7 = debug. This option is deprecated.
-
-.in 9
-\fIlog_facility\fP\fB="\fPdaemon\fB"\fP
-.in 12
-This controls the syslog facility used by the quorum daemon when logging.
-For a complete list of available facilities, see \fBsyslog.conf(5)\fP.
-The default value for this is 'daemon'. This option is deprecated.
-
-.in 9
-\fIstatus_file\fP\fB="\fP/foo\fB"\fP
-.in 12
-Write internal states out to this file periodically ("-" = use stdout).
-This is primarily used for debugging. The default value for this
-attribute is undefined. This option can be changed while qdiskd is
-running.
-
-.in 9
-\fImin_score\fP\fB="\fP3\fB"\fP
-.in 12
-Absolute minimum score to be consider one's self "alive". If omitted,
-or set to 0, the default function "floor((n+1)/2)" is used, where \fIn\fP
-is the total of all of defined heuristics' \fIscore\fP attribute. This
-must never exceed the sum of the heuristic scores, or else the quorum
-disk will never be available.
-
-.in 9
-\fIreboot\fP\fB="\fP1\fB"\fP
-.in 12
-If set to 0 (off), qdiskd will *not* reboot after a negative transition
-as a result in a change in score (see section 2.2). The default for
-this value is 1 (on). This option can be changed while qdiskd is
-running.
-
-.in 9
-\fImaster_wins\fP\fB="\fP0\fB"\fP
-.in 12
-If set to 1 (on), only the qdiskd master will advertise its votes
-to CMAN. In a network partition, only the qdisk master will provide
-votes to CMAN. Consequently, that node will automatically "win" in
-a fence race.
-
-This option requires careful tuning of the CMAN timeout, the qdiskd
-timeout, and CMAN's quorum_dev_poll value. As a rule of thumb,
-CMAN's quorum_dev_poll value should be equal to Totem's token timeout
-and qdiskd's timeout (interval*tko) should be less than half of
-Totem's token timeout. See section 3.3.1 for more information.
-
-This option only takes effect if there are no heuristics
-configured and it is valid only for 2 node cluster.
-This option is automatically disabled if heuristics are
-defined or cluster has more than 2 nodes configured.
-
-In a two-node cluster with no heuristics and no defined vote
-count (see above), this mode is turned by default. If enabled in
-this way at startup and a node is later added to the cluster
-configuration or the vote count is set to a value other than 1, this
-mode will be disabled.
-
-.in 9
-\fIallow_kill\fP\fB="\fP1\fB"\fP
-.in 12
-If set to 0 (off), qdiskd will *not* instruct to kill nodes it thinks
-are dead (as a result of not writing to the quorum disk). The default
-for this value is 1 (on). This option can be changed while qdiskd
-is running.
-
-.in 9
-\fIparanoid\fP\fB="\fP0\fB"\fP
-.in 12
-If set to 1 (on), qdiskd will watch internal timers and reboot the node
-if it takes more than (interval * tko) seconds to complete a quorum disk
-pass. The default for this value is 0 (off). This option can be changed
-while qdiskd is running.
-
-.in 9
-\fIio_timeout\fP\fB="\fP0\fB"\fP
-.in 12
-If set to 1 (on), qdiskd will watch internal timers and reboot the node
-if qdisk is not able to write to disk after (interval * tko) seconds.
-The default for this value is 0 (off). If io_timeout is active
-max_error_cycles is overridden and set to off.
-
-.in 9
-\fIscheduler\fP\fB="\fPrr\fB"\fP
-.in 12
-Valid values are 'rr', 'fifo', and 'other'. Selects the scheduling queue
-in the Linux kernel for operation of the main & score threads (does not
-affect the heuristics; they are always run in the 'other' queue). Default
-is 'rr'. See sched_setscheduler(2) for more details.
-
-.in 9
-\fIpriority\fP\fB="\fP1\fB"\fP
-.in 12
-Valid values for 'rr' and 'fifo' are 1..100 inclusive. Valid values
-for 'other' are -20..20 inclusive. Sets the priority of the main & score
-threads. The default value is 1 (in the RR and FIFO queues, higher numbers
-denote higher priority; in OTHER, lower values denote higher priority).
-This option can be changed while qdiskd is running.
-
-.in 9
-\fIstop_cman\fP\fB="\fP0\fB"\fP
-.in 12
-Ordinarily, cluster membership is left up to CMAN, not qdisk.
-If this parameter is set to 1 (on), qdiskd will tell CMAN to leave the
-cluster if it is unable to initialize the quorum disk during startup. This
-can be used to prevent cluster participation by a node which has been
-disconnected from the SAN. The default for this value is 0 (off).
-This option can be changed while qdiskd is running.
-
-.in 9
-\fIuse_uptime\fP\fB="\fP1\fB"\fP
-.in 12
-If this parameter is set to 1 (on), qdiskd will use values from
-/proc/uptime for internal timings. This is a bit less precise
-than \fBgettimeofday(2)\fP, but the benefit is that changing the
-system clock will not affect qdiskd's behavior - even if \fBparanoid\fP
-is enabled. If set to 0, qdiskd will use \fBgettimeofday(2)\fP, which
-is more precise. The default for this value is 1 (on / use uptime).
-
-.in 9
-\fIdevice\fP\fB="\fP/dev/sda1\fB"\fP
-.in 12
-This is the device the quorum daemon will use. This device must be the
-same on all nodes.
-
-.in 9
-\fIlabel\fP\fB="\fPmylabel\fB"\fP
-.in 12
-This overrides the device field if present. If specified, the quorum
-daemon will read /proc/partitions and check for qdisk signatures
-on every block device found, comparing the label against the specified
-label. This is useful in configurations where the block device name
-differs on a per-node basis.
-
-.in 9
-\fIcman_label\fP\fB="\fPmylabel\fB"\fP
-.in 12
-This overrides the label advertised to CMAN if present. If specified,
-the quorum daemon will register with this name instead of the actual
-device name.
-
-.in 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). This option can be changed while
-qdiskd is running. This option is ignored if io_timeout is set to 1.
-
-.in 8
-\fB/>\fP
-.in 0
-
-.SH "3.3.1. Quorum Disk Timings"
-Qdiskd should not be used in environments requiring failure detection
-times of less than approximately 10 seconds.
-
-Qdiskd will attempt to automatically configure timings based on the
-totem timeout and the TKO. If configuring manually, Totem's token
-timeout \fBmust\fP be set to a value at least 1 interval greater than
-the the following function:
-
- interval * (tko + master_wait + upgrade_wait)
-
-So, if you have an interval of 2, a tko of 7, master_wait of 2 and
-upgrade_wait of 2, the token timeout should be at least 24 seconds
-(24000 msec).
-
-It is recommended to have at least 3 intervals to reduce the risk of
-quorum loss during heavy I/O load. As a rule of thumb, using a totem
-timeout more than 2x of qdiskd's timeout will result in good behavior.
-
-An improper timing configuration will cause CMAN to give up on qdiskd,
-causing a temporary loss of quorum during master transition.
-
-.SH "3.2. The <heuristic> tag"
-This tag is a child of the <quorumd> tag. Heuristics may not be changed
-while qdiskd is running.
-
-.in 8
-\fB<heuristic\fP
-.in 9
-\fIprogram\fP\fB="\fP/test.sh\fB"\fP
-.in 12
-This is the program used to determine if this heuristic is alive. This
-can be anything which may be executed by \fI/bin/sh -c\fP. A return
-value of zero indicates success; anything else indicates failure. This
-is required.
-
-.in 9
-\fIscore\fP\fB="\fP1\fB"\fP
-.in 12
-This is the weight of this heuristic. Be careful when determining scores
-for heuristics. The default score for each heuristic is 1.
-
-.in 9
-\fIinterval\fP\fB="\fP2\fB"\fP
-.in 12
-This is the frequency (in seconds) at which we poll the heuristic. The
-default interval is determined by the qdiskd timeout.
-.in 0
-
-.in 9
-\fItko\fP\fB="\fP1\fB"\fP
-.in 12
-After this many failed attempts to run the heuristic, it is considered DOWN,
-and its score is removed. The default tko for each heuristic is determined
-by the qdiskd timeout.
-.in 8
-\fB/>\fP
-.in 0
-
-
-.SH "3.3. Examples"
-.SH "3.3.1. 3 cluster nodes & 3 routers"
-.in 8
-<cman expected_votes="6" .../>
-.br
-<clusternodes>
-.in 12
-<clusternode name="node1" votes="1" ... />
-.br
-<clusternode name="node2" votes="1" ... />
-.br
-<clusternode name="node3" votes="1" ... />
-.in 8
-</clusternodes>
-.br
-<quorumd interval="1" tko="10" votes="3" label="testing">
-.in 12
-<heuristic program="ping A -c1 -w1" score="1" interval="2" tko="3"/>
-.br
-<heuristic program="ping B -c1 -w1" score="1" interval="2" tko="3"/>
-.br
-<heuristic program="ping C -c1 -w1" score="1" interval="2" tko="3"/>
-.br
-.in 8
-</quorumd>
-
-.SH "3.3.2. 2 cluster nodes & 1 IP tiebreaker"
-.in 8
-<cman two_node="0" expected_votes="3" .../>
-.br
-<clusternodes>
-.in 12
-<clusternode name="node1" votes="1" ... />
-.br
-<clusternode name="node2" votes="1" ... />
-.in 8
-</clusternodes>
-.br
-<quorumd interval="1" tko="10" votes="1" label="testing">
-.in 12
-<heuristic program="ping A -c1 -w1" score="1" interval="2" tko="3"/>
-.br
-.in 8
-</quorumd>
-.in 0
-
-
-.SH "3.4. Heuristic score considerations"
-* Heuristic timeouts should be set high enough to allow the previous run
-of a given heuristic to complete.
-
-* Heuristic scripts returning anything except 0 as their return code
-are considered failed.
-
-* The worst-case for improperly configured quorum heuristics is a race
-to fence where two partitions simultaneously try to kill each other.
-
-.SH "3.5. Creating a quorum disk partition"
-The mkqdisk utility can create and list currently configured quorum disks
-visible to the local node; see
-.B mkqdisk(8)
-for more details.
-
-.SH "SEE ALSO"
-mkqdisk(8), qdiskd(8), cman(5), syslog.conf(5), gettimeofday(2)
diff --git a/cman/man/qdiskd.8 b/cman/man/qdiskd.8
deleted file mode 100644
index 21bccbf..0000000
--- a/cman/man/qdiskd.8
+++ /dev/null
@@ -1,25 +0,0 @@
-.TH "qdiskd" "8" "July 2006" "" "Quorum Disk Management"
-.SH "NAME"
-qdiskd \- Cluster Quorum Disk Daemon
-.SH "SYNOPSIS"
-\fBqdiskd [\-f] [\-d]
-.SH "DESCRIPTION"
-.PP
-The \fBqdiskd\fP daemon talks to CMAN and provides a mechanism for determining
-node-fitness in a cluster environment. See
-.B
-qdisk(5)
-for configuration information.
-.SH "OPTIONS"
-.IP "\-f"
-Run in the foreground (do not fork / daemonize).
-.IP "\-d"
-Enable debug output.
-.IP "\-Q"
-Close stdin/out/err immediately before doing validations. This
-is primarily for use when being called from an init script. Using
-this option will stop all output, and can not be used with the -d
-option.
-
-.SH "SEE ALSO"
-mkqdisk(8), qdisk(5), cman(5)
diff --git a/cman/notifyd/Makefile b/cman/notifyd/Makefile
deleted file mode 100644
index 5676fe3..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=.Tpo)
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 4a9f868..0000000
--- a/cman/notifyd/main.c
+++ /dev/null
@@ -1,430 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <limits.h>
-#include <sched.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/select.h>
-
-#include <libcman.h>
-#include <ccs.h>
-#include <liblogthread.h>
-
-#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(void)
-{
- 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;
-
- }
-
- }
-
- if (getenv("CMANNOTIFYD_DEBUG"))
- debug = 1;
-
-}
-
-static void remove_lockfile(void)
-{
- unlink(LOCKFILE_NAME);
-}
-
-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);
- }
-
- snprintf(buf, sizeof(buf) - 1, "%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);
- }
-
- atexit(remove_lockfile);
-}
-
-static void sigterm_handler(int sig)
-{
- daemon_quit = 1;
-}
-
-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;
- int syslog_facility = SYSLOGFACILITY;
- int syslog_priority = SYSLOGLEVEL;
- char logfile[PATH_MAX];
- int logfile_priority = SYSLOGLEVEL;
-
- memset(logfile, 0, PATH_MAX);
- snprintf(logfile, sizeof(logfile) - 1, LOGDIR "/cmannotifyd.log");
-
- ccs_handle = ccs_connect();
- if (ccs_handle > 0) {
- ccs_read_logging(ccs_handle, "cmannotifyd", &debug, &mode,
- &syslog_facility, &syslog_priority, &logfile_priority, logfile);
- ccs_disconnect(ccs_handle);
- } else {
- if (debug) {
- logfile_priority = LOG_DEBUG;
- }
- }
-
- if (!daemonize)
- mode |= LOG_MODE_OUTPUT_STDERR;
-
- if (!reconf)
- logt_init("cmannotifyd", mode, syslog_facility, syslog_priority, logfile_priority, logfile);
- else
- logt_conf("cmannotifyd", mode, syslog_facility, syslog_priority, logfile_priority, logfile);
-}
-
-static void dispatch_notification(const 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, pid;
- int pidstatus;
- int err = 0;
-
- 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++] = strdup("cman_notify");
-
- argv[argvptr--] = NULL;
-
- switch ( (notify_pid = fork()) )
- {
- case -1:
- /* unable to fork */
- err = 1;
- goto out;
- break;
-
- case 0: /* child */
- execve(SBINDIR "/cman_notify", argv, envp);
- /* unable to execute cman_notify */
- err = 1;
- goto out;
- break;
-
- default: /* parent */
- pid = waitpid(notify_pid, &pidstatus, 0);
- if (pid < 0)
- logt_print(LOG_ERR, "Error waiting for " SBINDIR "/cman_notify execution\n");
-
- break;
- }
-
-out:
- while(envptr >= 0) {
- if (envp[envptr])
- free(envp[envptr]);
-
- envptr--;
- }
- while(argvptr >= 0) {
- if (argv[argvptr])
- free(argv[argvptr]);
-
- argvptr--;
- }
- if (err)
- exit(EXIT_FAILURE);
-}
-
-static void cman_callback(cman_handle_t ch, void *private, int reason, int arg)
-{
- const 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(void)
-{
- if (!cman_handle)
- return;
-
- cman_finish(cman_handle);
- cman_handle = NULL;
-}
-
-static void setup_cman(int forever)
-{
- int init = 0, active = 0;
- int quorate;
- const char *str = NULL;
-
-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);
- }
-
- logt_print(LOG_DEBUG, "Dispatching first cluster status\n");
- init_logging(1);
- str = "CMAN_REASON_CONFIG_UPDATE";
- dispatch_notification(str, 0);
- str = "CMAN_REASON_STATECHANGE";
- quorate = cman_is_quorate(cman_handle);
- dispatch_notification(str, &quorate);
-
- return;
-
-out:
- byebye_cman();
- exit(EXIT_SUCCESS);
-}
-
-static void loop(void)
-{
- int cd_result, se_result;
- fd_set read_fds;
- int cman_fd;
-
- do {
- FD_ZERO (&read_fds);
- cman_fd = cman_get_fd(cman_handle);
- FD_SET (cman_fd, &read_fds);
- se_result = select((cman_fd + 1), &read_fds, 0, 0, 0);
-
- if (daemon_quit)
- goto out;
-
- if (se_result == -1) {
- logt_print(LOG_CRIT, "Unable to select on cman_fd: %s\n", strerror(errno));
- byebye_cman();
- exit(EXIT_FAILURE);
- }
-
- if (FD_ISSET(cman_fd, &read_fds)) {
- cd_result = 1;
- while (cd_result > 0) {
- cd_result = cman_dispatch(cman_handle, CMAN_DISPATCH_ONE);
- if (cd_result == -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");
- }
- }
- }
- } while (se_result && !daemon_quit);
-
-out:
- logt_print(LOG_DEBUG, "shutting down...\n");
- byebye_cman();
-}
-
-int main(int argc, char **argv)
-{
-
- read_arguments(argc, argv);
- if (daemonize) {
- if (daemon(0, 0) < 0) {
- perror("Unable to daemonize");
- exit(EXIT_FAILURE);
- }
- }
- lockfile();
- init_logging(0);
- signal(SIGTERM, sigterm_handler);
- 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 f39c036..0000000
--- a/cman/qdisk/Makefile
+++ /dev/null
@@ -1,52 +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 += -I${ccsincdir} -I${cmanincdir} -I${logtincdir}
-CFLAGS += -I${zlibincdir}
-CFLAGS += -I$(S)
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${logtlibdir} -llogthread -lpthread
-LDFLAGS += -L${zliblibdir} -lz -lrt
-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 \
- disk_util.o \
- proc.o \
- scandisk.o \
- iostate.o
-
-${TARGET1}: ${SHAREDOBJS} ${OBJS1}
- $(CC) -o $@ $^ $(EXTRA_LDFLAGS) $(LDFLAGS)
-
-${TARGET2}: ${SHAREDOBJS} ${OBJS2}
- $(CC) -o $@ $^ $(EXTRA_LDFLAGS) $(LDFLAGS)
-
-depends:
- $(MAKE) -C ../lib all
-
-clean: generalclean
-
--include $(OBJS1:.o=.Tpo)
--include $(OBJS2:.o=.Tpo)
--include $(SHAREDOBJS:.o=.Tpo)
diff --git a/cman/qdisk/bitmap.c b/cman/qdisk/bitmap.c
deleted file mode 100644
index 094ad2f..0000000
--- a/cman/qdisk/bitmap.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/** @file
- * Bitmap and membership mask handling routines.
- */
-#include <stdint.h>
-
-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);
-
-/**
- * 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/daemon_init.c b/cman/qdisk/daemon_init.c
deleted file mode 100644
index 7c26f8a..0000000
--- a/cman/qdisk/daemon_init.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/** @file
- * daemon_init function, does sanity checks and calls daemon().
- *
- * Author: Jeff Moyer <jmoyer(a)redhat.com>
- */
-/*
- * TODO: Clean this up so that only one function constructs the
- * pidfile /var/run/loggerd.PID, and perhaps only one function
- * forms the /proc/PID/ path.
- *
- * Also need to add file locking for the pid file.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <sys/mman.h>
-#include <sys/errno.h>
-#include <libgen.h>
-#include <signal.h>
-#include <liblogthread.h>
-
-/*
- * This should ultimately go in a header file.
- */
-void daemon_init(char *prog);
-void daemon_cleanup(void);
-int check_process_running(char *prog, pid_t * pid);
-
-/*
- * Local prototypes.
- */
-static void update_pidfile(char *prog);
-static int setup_sigmask(void);
-static char pid_filename[PATH_MAX];
-
-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;
- size_t proc_cmdline_len = 0;
-
- memset(filename, 0, PATH_MAX);
- memset(dirpath, 0, PATH_MAX);
-
- snprintf(dirpath, sizeof (dirpath) - 1, "/proc/%d", pid);
- dir = opendir(dirpath);
- if (!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) - 1, "/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), 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);
-
- proc_cmdline_len = strlen(proc_cmdline);
- if (proc_cmdline_len) {
- s = &(proc_cmdline[proc_cmdline_len]);
- if (*s == '\n')
- *s = 0;
- }
-
- /*
- * Check to see if this is the same executable.
- */
- if (!strstr(proc_cmdline, prog)) {
- 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;
-
- if (!prog) {
- errno = EINVAL;
- return -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);
- if (!cmd)
- return -1;
-
- snprintf(filename, sizeof (filename) - 1, "/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;
-
- memset(pid_filename, 0, PATH_MAX);
-
- cmd = basename(prog);
- snprintf(pid_filename, sizeof (pid_filename), "/var/run/%s.pid", cmd);
-
- fp = fopen(pid_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)
-{
- if (getuid()) {
- logt_print(LOG_ERR,
- "daemon_init: Sorry, only root wants to run this.\n");
- exit(1);
- }
-
- if (setup_sigmask() < 0) {
- logt_print(LOG_ERR, "daemon_init: Unable to set signal mask.\n");
- exit(1);
- }
-
- if(daemon(0, 0)) {
- logt_print(LOG_ERR, "daemon_init: Unable to daemonize.\n");
- exit(1);
- }
-
- update_pidfile(prog);
-}
-
-
-void
-daemon_cleanup(void)
-{
- if (strlen(pid_filename))
- unlink(pid_filename);
-}
diff --git a/cman/qdisk/disk.c b/cman/qdisk/disk.c
deleted file mode 100644
index 9e43462..0000000
--- a/cman/qdisk/disk.c
+++ /dev/null
@@ -1,784 +0,0 @@
-/** @file
- * Single-block Raw/Direct I/O Functions
- */
-/*
- * author: Tim Burke <tburke at redhat.com>
- * description: Raw IO Interfaces.
- *
- * The RAW IO code we are using from 2.2.13 requires user buffers and
- * disk offsets to be 512 byte aligned. So this code consists of a
- * read and write routine which check to see if the user buffer is
- * aligned. If it isn't a temporary aligned buffer is allocated, a data
- * copy is performed along with the IO operation itself.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <string.h>
-#include <errno.h>
-#include <disk.h>
-#include <platform.h>
-#include <unistd.h>
-#include <time.h>
-#include <linux/types.h>
-#include <linux/fs.h>
-#include <liblogthread.h>
-#include <zlib.h>
-#include "iostate.h"
-
-static int diskRawRead(target_info_t *disk, char *buf, int len);
-
-/**
- * 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.
- */
-static uint32_t clu_crc32(const char *data, size_t count)
-{
- return (uint32_t)crc32(0L, (const Bytef *)data, (uInt)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 == le_swap32(SHARED_HEADER_MAGIC))
- return;
-
- hdr->h_magic = le_swap32(hdr->h_magic);
- hdr->h_hcrc = le_swap32(hdr->h_hcrc);
- hdr->h_dcrc = le_swap32(hdr->h_dcrc);
- hdr->h_length = le_swap32(hdr->h_length);
- hdr->h_view = le_swap64(hdr->h_view);
- hdr->h_timestamp = le_swap64(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;
-
- hdr->h_magic = le_swap32(hdr->h_magic);
- hdr->h_hcrc = le_swap32(hdr->h_hcrc);
- hdr->h_dcrc = le_swap32(hdr->h_dcrc);
- hdr->h_length = le_swap32(hdr->h_length);
- hdr->h_view = le_swap64(hdr->h_view);
- hdr->h_timestamp = le_swap64(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) {
- logt_print(LOG_ERR, "Invalid CRC32 generated on data!\n");
- return -1;
- }
- }
-
- hdr->h_timestamp = (uint64_t)time(NULL);
- header_encode(hdr);
- hdr->h_hcrc = 0;
- hdr->h_hcrc = le_swap32(clu_crc32((char *)hdr, sizeof(*hdr)));
-
- if (hdr->h_hcrc == 0) {
- logt_print(LOG_ERR, "Invalid CRC32 generated on header!\n");
- return -1;
- }
-
- 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;
-
- /*
- * 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;
-
- /* BUG: Headers are stored in little-endian form */
- bkupcrc = le_swap32(hdr->h_hcrc);
-
- hdr->h_hcrc = 0;
- crc = clu_crc32((char *)hdr, sizeof(*hdr));
- hdr->h_hcrc = bkupcrc;
- if (bkupcrc != crc) {
- logt_print(LOG_DEBUG, "Header CRC32 mismatch; Exp: 0x%08x "
- "Got: 0x%08x\n", bkupcrc, crc);
- return -1;
- }
-
- header_decode(hdr);
-
- /*
- * Verify the magic number.
- */
- if (hdr->h_magic != SHARED_HEADER_MAGIC) {
- logt_print(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) {
- logt_print(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) {
- logt_print(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.*/
- io_state(STATE_LSEEK);
- ret = lseek(disk->d_fd, END_OF_DISK(disk->d_blksz), SEEK_SET);
- io_state(STATE_NONE);
- if (ret < 0) {
- logt_print(LOG_DEBUG, "open_partition: seek");
- close(disk->d_fd);
- return -1;
- }
-
- if (ret < END_OF_DISK(disk->d_blksz)) {
- logt_print(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) {
- logt_print(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) {
- logt_print(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) {
- logt_print(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;
-*/
- logt_print(LOG_WARNING, "Warning: %s is not a block device\n",
- name);
- }
-
- /*
- * Verify read/write permission.
- */
- if (qdisk_open(name, &disk) < 0) {
- logt_print(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;
-
- io_state(STATE_LSEEK);
- ret = lseek(disk->d_fd, readOffset, SEEK_SET);
- io_state(STATE_NONE);
- if (ret != readOffset) {
- logt_print(LOG_DEBUG,
- "diskRawReadShadow: can't seek to offset %d.\n",
- (int) readOffset);
- errno = ENODATA;
- return -1;
- }
-
- ret = diskRawRead(disk, buf, len);
- if (ret != len) {
- logt_print(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);
-
- if (header_verify(hdrp, data, len)) {
- logt_print(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. */
- io_state(STATE_READ);
- readret = read(disk->d_fd, buf, len);
- io_state(STATE_NONE);
- return readret;
- }
-
- if (len > disk->d_blksz) {
- logt_print(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;
- }
-
- io_state(STATE_READ);
- readret = read(disk->d_fd, alignedBuf, readlen);
- io_state(STATE_NONE);
- if (readret > 0) {
- if (readret > len) {
- memcpy(buf, alignedBuf, len);
- readret = len;
- } else {
- memcpy(buf, alignedBuf, readret);
- }
- }
-
- free(alignedBuf);
- if (readret != len) {
- logt_print(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. */
- io_state(STATE_WRITE);
- ret = write(disk->d_fd, buf, len);
- io_state(STATE_NONE);
- return ret;
- }
-
- if (len > disk->d_blksz) {
- logt_print(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) {
- free(alignedBuf);
- logt_print(LOG_ERR,
- "diskRawWrite: not setup for larger than %d.\n",
- (int)disk->d_blksz);
- return (-1);
- }
-
- memcpy(alignedBuf, buf, len);
- io_state(STATE_WRITE);
- ret = write(disk->d_fd, alignedBuf, writelen);
- io_state(STATE_NONE);
- if (ret > len) {
- ret = len;
- }
-
- free(alignedBuf);
- if (ret != len) {
- logt_print(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)) {
- logt_print(LOG_ERR,
- "diskRawWriteShadow: writeOffset=%08x, "
- "len=%08x.\n", (int)writeOffset, len);
- return (-1);
- }
-
- io_state(STATE_LSEEK);
- retval_seek = lseek(disk->d_fd, writeOffset, SEEK_SET);
- io_state(STATE_NONE);
- if (retval_seek != writeOffset) {
- logt_print(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) {
- logt_print(LOG_ERR, "%s: %s\n", __FUNCTION__,
- strerror(errno));
- }
- logt_print(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 *bufin, int count)
-{
- shared_header_t *hdrp;
- void *ptr;
- char *data;
- size_t total;
- int rv;
- char *buf = (char *)bufin;
-
- /*
- * 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) {
- free(hdrp);
- 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, psz = disk->d_blksz; //sysconf(_SC_PAGESIZE);
- int rv = -1;
-
- maxsize = psz - (sizeof(shared_header_t));
- if (count >= (maxsize + sizeof(shared_header_t))) {
- logt_print(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) {
- logt_print(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;
- }
-
- /*
- * 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)
- logt_print(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) {
- logt_print(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) {
- logt_print(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) {
- logt_print(LOG_DEBUG, "qdisk_validate: %s\n", strerror(errno));
- return -1;
- }
-
- ret = qdisk_open(partname, &disk);
- if (ret < 0) {
- logt_print(LOG_ERR, "qdisk_open: %s\n", strerror(errno));
- return -1;
- }
-
- if (header_init(&disk, label) < 0) {
- return -1;
- }
-
- time(&t);
-
- memset(&ps, 0, sizeof(status_block_t));
-
- ps.ps_magic = STATE_MAGIC_NUMBER;
- ps.ps_timestamp = (uint64_t)t;
-
- /* 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 1d8f7c8..0000000
--- a/cman/qdisk/disk.h
+++ /dev/null
@@ -1,298 +0,0 @@
-/**
- @file Main quorum daemon include file
- */
-#ifndef _QUORUM_DISK_H
-#define _QUORUM_DISK_H
-
-#include <stdint.h>
-#include <pthread.h>
-#include <arpa/inet.h>
-#include <libcman.h>
-
-#define MAX_NODES_DISK 16
-#define MEMB_MASK_LEN ((MAX_NODES_DISK / 8) + \
- (!!(MAX_NODES_DISK % 8)))
-#define DISK_MEMB_MASK_LEN ((MEMB_MASK_LEN + 7) & ~7)
-
-/** The membership bitmask type */
-typedef uint8_t memb_mask_t [DISK_MEMB_MASK_LEN];
-
-typedef enum {
- S_NONE = 0x0, // Shutdown / not quorate / not running
- S_EVICT = 0x1, // Voted out / about to be fenced.
- /* ^^^ Fencing OK */
- S_INIT = 0x2, // Initializing. Hold your fire.
- /* vvv Fencing will kill a node */
- S_RUN = 0x5, // I think I'm running.
- S_MASTER= 0x6, // I know I'm running, and have advertised to
- // CMAN the availability of the disk vote for my
- // partition.
- S_EXIT = 0x7 // trigger master re-election before exit
- // status is set only by master in master-win | auto-masterwin
- // and next status _must_ be S_NONE
-} disk_node_state_t;
-
-
-typedef enum {
- M_NONE = 0x0,
- M_BID = 0x1,
- M_ACK = 0x2,
- M_NACK = 0x3,
- M_MASK = 0x4
-} disk_msg_id_t;
-
-
-typedef enum {
- FL_MSG = 0x1,
- FL_BID = 0x2,
- FL_VOTE = 0x4
-} disk_state_flag_t;
-
-
-typedef enum {
- RF_REBOOT = 0x1, /* Reboot if we go from master->none */
- RF_STOP_CMAN = 0x2,
- RF_DEBUG = 0x4,
- RF_PARANOID = 0x8,
- RF_ALLOW_KILL = 0x10,
- RF_UPTIME = 0x20,
- RF_CMAN_LABEL = 0x40,
- RF_IOTIMEOUT = 0x80,
- RF_MASTER_WINS = 0x100,
- RF_AUTO_VOTES = 0x200,
- RF_AUTO_MASTER_WINS = 0x400
-} 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_master; /* Master?! */
- int qc_config;
- int qc_token_timeout;
- int qc_auto_votes;
- disk_node_state_t qc_disk_status;
- disk_node_state_t qc_status;
- run_flag_t qc_flags;
- cman_handle_t qc_cman_admin;
- cman_handle_t qc_cman_user;
- 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;
-
-typedef struct {
- qd_ctx *ctx;
- node_info_t *ni;
- size_t ni_len;
-} qd_priv_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_admin,
- cman_handle_t ch_user, 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 6d6e93e..0000000
--- a/cman/qdisk/disk_util.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/**
- @file Misc. Quorum daemon context utilities / high-level functions
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <string.h>
-#include <errno.h>
-#include <disk.h>
-#include <platform.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <time.h>
-#include <liblogthread.h>
-
-inline void _diff_tv(struct timeval *dest, struct timeval *start, struct timeval *end);
-inline int get_time(struct timeval *tv, int use_uptime);
-
-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) {
- logt_print(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_admin, 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_cman_admin = ch_admin;
- ctx->qc_cman_user = ch;
- ctx->qc_my_id = me;
- ctx->qc_config = 0;
-
- 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/iostate.c b/cman/qdisk/iostate.c
deleted file mode 100644
index 9050276..0000000
--- a/cman/qdisk/iostate.c
+++ /dev/null
@@ -1,154 +0,0 @@
-#include <pthread.h>
-#include <libcman.h>
-#include <iostate.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/time.h>
-#include <liblogthread.h>
-#include <stdint.h>
-#include "platform.h"
-#include "iostate.h"
-#include "../daemon/cnxman-socket.h"
-
-static iostate_t main_state = 0;
-static int main_incarnation = 0;
-static int qdisk_timeout = 0, sleeptime = 0;
-static int thread_active = 0;
-static pthread_t io_nanny_tid = 0;
-static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t state_cond = PTHREAD_COND_INITIALIZER;
-
-struct state_table {
- iostate_t state;
- const char *value;
-};
-
-static struct state_table io_state_table[] = {
-{ STATE_NONE, "none" },
-{ STATE_WRITE, "write" },
-{ STATE_READ, "read" },
-{ STATE_LSEEK, "seek" },
-{ -1, NULL } };
-
-const char *
-state_to_string(iostate_t state)
-{
- static const char *ret = "unknown";
- int i;
-
- for (i=0; io_state_table[i].value; i++) {
- if (io_state_table[i].state == state) {
- ret = io_state_table[i].value;
- break;
- }
- }
-
- return ret;
-}
-
-
-void
-io_state(iostate_t state)
-{
- pthread_mutex_lock(&state_mutex);
- main_state = state;
- main_incarnation++; /* it does not matter if this wraps. */
-
- /* Optimization: Don't signal on STATE_NONE */
- if (state != STATE_NONE)
- pthread_cond_broadcast(&state_cond);
-
- pthread_mutex_unlock(&state_mutex);
-}
-
-
-static void *
-io_nanny_thread(void *arg)
-{
- struct timespec wait_time;
- iostate_t last_main_state = 0, current_main_state = 0;
- int last_main_incarnation = 0, current_main_incarnation = 0;
- int logged_incarnation = 0;
- cman_handle_t ch = (cman_handle_t)arg;
- int32_t whine_state;
-
- /* Start with wherever we're at now */
- pthread_mutex_lock(&state_mutex);
- current_main_state = last_main_state = main_state;
- current_main_incarnation = last_main_incarnation = main_incarnation;
- pthread_mutex_unlock(&state_mutex);
-
- while (thread_active) {
- pthread_mutex_lock(&state_mutex);
- clock_gettime(CLOCK_REALTIME, &wait_time);
- wait_time.tv_sec += sleeptime;
- pthread_cond_timedwait(&state_cond, &state_mutex, &wait_time);
- current_main_state = main_state;
- current_main_incarnation = main_incarnation;
- pthread_mutex_unlock(&state_mutex);
-
- if (!thread_active)
- break;
-
- if (!current_main_state)
- continue;
-
- /* if the state or incarnation changed, the main qdiskd
- * thread is healthy */
- if (current_main_state != last_main_state ||
- current_main_incarnation != last_main_incarnation) {
- last_main_state = current_main_state;
- last_main_incarnation = current_main_incarnation;
- continue;
- }
-
- /* Whine on CMAN api */
- whine_state = (int32_t)current_main_state;
- swab32(whine_state);
- cman_send_data(ch, &whine_state, sizeof(int32_t), 0, CLUSTER_PORT_QDISKD , 0);
-
- /* Don't log things twice */
- if (logged_incarnation == current_main_incarnation)
- continue;
- logged_incarnation = current_main_incarnation;
-
- logt_print(LOG_WARNING, "qdiskd: %s "
- "(system call) has hung for %d seconds\n",
- state_to_string(current_main_state), sleeptime);
- logt_print(LOG_WARNING,
- "In %d more seconds, we will be evicted\n",
- (qdisk_timeout-sleeptime));
- }
-
- return NULL;
-}
-
-
-int
-io_nanny_start(cman_handle_t ch, int timeout)
-{
- int ret;
-
- pthread_mutex_lock(&state_mutex);
-
- sleeptime = timeout / 2;
- qdisk_timeout = timeout;
- thread_active = 1;
-
- ret = pthread_create(&io_nanny_tid, NULL, io_nanny_thread, ch);
- pthread_mutex_unlock(&state_mutex);
-
- return ret;
-}
-
-
-int
-io_nanny_stop(void)
-{
- thread_active = 0;
- pthread_cond_broadcast(&state_cond);
- pthread_join(io_nanny_tid, NULL);
- io_nanny_tid = 0;
-
- return 0;
-}
diff --git a/cman/qdisk/iostate.h b/cman/qdisk/iostate.h
deleted file mode 100644
index a65b1d4..0000000
--- a/cman/qdisk/iostate.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _IOSTATE_H
-#define _IOSTATE_H
-
-typedef enum {
- STATE_NONE = 0,
- STATE_READ = 1,
- STATE_WRITE = 2,
- STATE_LSEEK = 3,
- STATE_UNKNOWN = 4
-} iostate_t;
-
-void io_state(iostate_t state);
-
-int io_nanny_start(cman_handle_t ch, int timeout);
-int io_nanny_stop(void);
-
-const char * state_to_string(iostate_t state);
-
-#endif
diff --git a/cman/qdisk/main.c b/cman/qdisk/main.c
deleted file mode 100644
index 9dee134..0000000
--- a/cman/qdisk/main.c
+++ /dev/null
@@ -1,2289 +0,0 @@
-/**
- @file Main loop / functions for disk-based quorum daemon.
- */
-#define SYSLOG_NAMES
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <string.h>
-#include <errno.h>
-#include <disk.h>
-#include <platform.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/reboot.h>
-#include <sys/time.h>
-#include <sys/un.h>
-#include <linux/reboot.h>
-#include <sched.h>
-#include <signal.h>
-#include <ccs.h>
-#include <liblogthread.h>
-#include "score.h"
-#include "../daemon/cman.h"
-#include "../daemon/cnxman-socket.h"
-#include <sys/syslog.h>
-
-#define LOG_DAEMON_NAME "qdiskd"
-#define LOG_MODE_DEFAULT LOG_MODE_OUTPUT_SYSLOG|LOG_MODE_OUTPUT_FILE
-#include "iostate.h"
-
-
-/* from main.c */
-void set_priority(int queue, int prio);
-
-/* from daemon_init.c */
-extern int daemon_init(char *);
-extern void daemon_cleanup(void);
-extern int check_process_running(char *, pid_t *);
-
-/* from proc.c */
-extern const 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 */
-extern int clear_bit(uint8_t *mask, uint32_t bitidx, uint32_t masklen);
-extern int set_bit(uint8_t *mask, uint32_t bitidx, uint32_t masklen);
-extern int is_bit_set(uint8_t *mask, uint32_t bitidx, uint32_t masklen);
-
-/* From disk_utils.c */
-extern inline int get_time(struct timeval *tv, int use_uptime);
-extern inline void _diff_tv(struct timeval *dest, struct timeval *start,
- struct timeval *end);
-
-static int _running = 1, _reconfig = 0, _cman_shutdown = 0;
-static int _debug = 0, _foreground = 0;
-
-/* */
-#define DEBUG_CONF 0x1
-#define DEBUG_CMDLINE 0x2
-
-static void update_local_status(qd_ctx *ctx, node_info_t *ni, int max, int score,
- int score_req, int score_max);
-static int get_config_data(qd_ctx *ctx, struct h_data *h, int maxh, int *cfh);
-static int cman_wait(cman_handle_t ch, struct timeval *_tv);
-
-static int fake_cfh = 0;
-
-static void
-int_handler(int sig)
-{
- _running = 0;
-}
-
-
-static void
-hup_handler(int sig)
-{
- _reconfig = 1;
-}
-
-
-static void
-usr1_handler(int sig)
-{
- if (_debug)
- /* Shut up debug mode */
- _debug = 0;
- else
- _debug = DEBUG_CMDLINE;
-}
-
-
-/**
- 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:
- logt_print(LOG_EMERG, "Unhandled state: %d\n", sb->ps_state);
- raise(SIGSTOP);
- break;
- }
-}
-
-
-/**
- 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.
- */
-static 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) {
- logt_print(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) &&
- (ni[x].ni_state != S_EXIT)) {
- if (ni[x].ni_state != S_NONE) {
- /* XXX check for average + allow grace */
- ni[x].ni_misses++;
- if (ni[x].ni_misses > 1) {
- logt_print(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 0: check if master node is about to leave
- */
- if (ni[x].ni_state == S_EXIT) {
- logt_print(LOG_NOTICE, "Node %d is about to leave\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;
- if (mask)
- clear_bit(mask, (ni[x].ni_status.ps_nodeid-1),
- sizeof(memb_mask_t));
- continue;
- }
-
- /*
- 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) {
- logt_print(LOG_NOTICE, "Node %d evicted\n",
- ni[x].ni_status.ps_nodeid);
- } else {
- /* State == S_NONE or incarnation change */
- logt_print(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) {
- logt_print(LOG_DEBUG, "Node %d DOWN\n",
- ni[x].ni_status.ps_nodeid);
- ni[x].ni_seen = 0;
- }
-
- ni[x].ni_state = S_EVICT;
- ni[x].ni_status.ps_state = S_EVICT;
- ni[x].ni_evil_incarnation =
- ni[x].ni_incarnation;
-
- /*
- Write eviction notice if we're the master.
- */
- if (ctx->qc_status == S_MASTER) {
- logt_print(LOG_NOTICE,
- "Writing eviction notice for node %d\n",
- ni[x].ni_status.ps_nodeid);
- if (qd_write_status(ctx, ni[x].ni_status.ps_nodeid,
- S_EVICT, NULL, NULL, NULL) != 0)
- logt_print(LOG_CRIT, "Unable to write eviction notice for node %d!\n",
- ni[x].ni_status.ps_nodeid);
- if (ctx->qc_flags & RF_ALLOW_KILL) {
- logt_print(LOG_DEBUG, "Telling CMAN to "
- "kill the node\n");
- cman_kill_node(ctx->qc_cman_admin,
- ni[x].ni_status.ps_nodeid);
- }
- }
-
- /* Clear our master mask for the node after eviction */
- if (mask)
- clear_bit(mask, (ni[x].ni_status.ps_nodeid-1),
- sizeof(memb_mask_t));
- continue;
- }
-
- /*
- Case 3: Check for node who is supposed to be dead, but
- has started writing to the disk again with the same
- incarnation.
-
- Transition from Offline -> Undead (BAD!!!)
- */
- if (ni[x].ni_evil_incarnation &&
- (ni[x].ni_evil_incarnation ==
- ni[x].ni_status.ps_incarnation) &&
- (ni[x].ni_status.ps_updatenode ==
- ni[x].ni_status.ps_nodeid)) {
- logt_print(LOG_CRIT, "Node %d is undead.\n",
- ni[x].ni_status.ps_nodeid);
-
- logt_print(LOG_ALERT,
- "Writing eviction notice (again) for node %d\n",
- ni[x].ni_status.ps_nodeid);
- if (qd_write_status(ctx, ni[x].ni_status.ps_nodeid,
- S_EVICT, NULL, NULL, NULL) != 0)
- logt_print(LOG_CRIT, "Unable to write eviction notice for node %d!\n",
- ni[x].ni_status.ps_nodeid);
- ni[x].ni_status.ps_state = S_EVICT;
-
- /* XXX Need to fence it again */
- if (ctx->qc_flags & RF_ALLOW_KILL) {
- logt_print(LOG_DEBUG, "Telling CMAN to "
- "kill the node\n");
- cman_kill_node(ctx->qc_cman_admin,
- 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;
- logt_print(LOG_DEBUG, "Node %d is UP\n",
- ni[x].ni_status.ps_nodeid);
- ni[x].ni_incarnation =
- ni[x].ni_status.ps_incarnation;
- ni[x].ni_evil_incarnation = 0;
-
- if (mask)
- set_bit(mask, (ni[x].ni_status.ps_nodeid-1),
- sizeof(memb_mask_t));
-
- continue;
- }
-
- /*
- Case 5: Check for a node becoming master. Not really a
- transition.
- */
- if (ni[x].ni_state == S_RUN &&
- ni[x].ni_status.ps_state == S_MASTER) {
- logt_print(LOG_INFO, "Node %d is the master\n",
- ni[x].ni_status.ps_nodeid);
- ni[x].ni_state = S_MASTER;
- if (mask)
- set_bit(mask, (ni[x].ni_status.ps_nodeid-1),
- sizeof(memb_mask_t));
- continue;
- }
-
- /*
- Case 6: Check for a node which has changed its
- incarnation # quickly (e.g. killall -9 qdiskd;
- qdiskd). Not a transition.
- */
- if (state_run(ni[x].ni_state) &&
- ni[x].ni_incarnation != ni[x].ni_status.ps_incarnation) {
-
- logt_print(LOG_DEBUG, "Node %d incarnation # changed\n",
- ni[x].ni_status.ps_nodeid);
- ni[x].ni_incarnation =
- ni[x].ni_status.ps_incarnation;
- ni[x].ni_evil_incarnation = 0;
-
- continue;
- }
-
- /*
- All other cases: Believe the node's reported state
- */
- if (state_run(ni[x].ni_state)) {
- ni[x].ni_state = ni[x].ni_status.ps_state;
- if (mask)
- set_bit(mask, (ni[x].ni_status.ps_nodeid-1),
- sizeof(memb_mask_t));
- }
- }
-}
-
-
-/**
- Checks for presence of an online master. If there is no
- Returns
- */
-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) {
- logt_print(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;
- struct timeval tv;
-
- logt_print(LOG_INFO, "Quorum Daemon Initializing\n");
-
- if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0) {
- logt_print(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) {
- logt_print(LOG_CRIT, "Failed to open %s: %s\n", ctx->qc_device,
- strerror(errno));
- return -1;
- }
-
- logt_print(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 {
- logt_print(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) {
- logt_print(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) {
- logt_print(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);
-
- tv.tv_sec = ctx->qc_interval;
- tv.tv_usec = 0;
- if (cman_wait(ctx->qc_cman_user, &tv) < 0)
- logt_print(LOG_ERR, "cman_dispatch: %s\n",
- strerror(errno));
- }
-
- if (!_running) {
- return 1;
- }
-
- get_my_score(&score, &maxscore);
- logt_print(LOG_INFO, "Initial score %d/%d\n", score, maxscore);
- if ((ctx->qc_flags & RF_STOP_CMAN) && (score < score_req))
- return -1;
- logt_print(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;
- static unsigned int check_cycle = 0;
-
- if (cman_get_nodes(ctx->qc_cman_admin, MAX_NODES_DISK,
- &retnodes, nodes) <0 )
- return;
-
- memset(master_mask, 0, sizeof(memb_mask_t));
- for (x = 0; x < retnodes; x++) {
- /* See if the other node is running cman and not qdiskd.
- Just to this every 4 times (seconds) so we don't spam syslog
- too much. cman_is_listening() can return EBUSY which means
- "I don't know". We don't worry about this, and just report
- at the next check by which time it will.
- */
- check_cycle = (check_cycle + 1) % 4;
- if ((check_cycle == 1) &&
- (cman_is_listening(ctx->qc_cman_admin, nodes[x].cn_nodeid,
- CLUSTER_PORT_QDISKD) == 0)) {
- logt_print(LOG_NOTICE, "node %s is up but not running qdiskd", nodes[x].cn_name);
- }
- if (is_bit_set(mask, nodes[x].cn_nodeid-1, sizeof(memb_mask_t)) &&
- nodes[x].cn_member) {
- set_bit(master_mask, nodes[x].cn_nodeid-1,
- sizeof(memb_mask_t));
- } 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 int
-register_device(qd_ctx *ctx)
-{
- return cman_register_quorum_device(
- ctx->qc_cman_admin,
- (ctx->qc_flags&RF_CMAN_LABEL) ?
- ctx->qc_cman_label : ctx->qc_device,
- (!(ctx->qc_flags & RF_MASTER_WINS) ||
- ctx->qc_status == S_MASTER) ?
- ctx->qc_votes : 0);
-}
-
-static int
-update_device(qd_ctx *ctx)
-{
- return cman_update_quorum_device(
- ctx->qc_cman_admin,
- (ctx->qc_flags&RF_CMAN_LABEL) ?
- ctx->qc_cman_label : ctx->qc_device,
- (!(ctx->qc_flags & RF_MASTER_WINS) ||
- ctx->qc_status == S_MASTER) ?
- ctx->qc_votes : 0);
-}
-
-static int
-adjust_votes(qd_ctx *ctx)
-{
- if (!(ctx->qc_flags & RF_MASTER_WINS))
- return 0;
-
- return register_device(ctx);
-}
-
-
-static void
-print_node_info(FILE *fp, node_info_t *ni)
-{
- uint64_t incarnation;
-
- fprintf(fp, "node_info_t [node %d] {\n", ni->ni_status.ps_nodeid);
-
- incarnation = be_swap64(ni->ni_incarnation);
- fprintf(fp, " ni_incarnation = 0x%08x%08x\n",
- ((int)(incarnation>>32))&0xffffffff,
- ((int)(incarnation)&0xffffffff));
-
- incarnation = be_swap64(ni->ni_evil_incarnation);
- fprintf(fp, " ni_evil_incarnation = 0x%08x%08x\n",
- ((int)(incarnation>>32))&0xffffffff,
- ((int)(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;
- long flags;
- int fd;
-
- 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;
- }
-
- /* Don't block while writing to this file
- * XXX Not set O_NONBLOCK twice on stdout?
- */
- fd = fileno(fp);
- flags = fcntl(fd, F_GETFD, 0);
- if (fcntl(fd, F_SETFD, flags | O_NONBLOCK) != 0) {
- if (need_close)
- fclose(fp);
- return;
- }
-
- now = time(NULL);
- fprintf(fp, "Time Stamp: %s", ctime(&now));
- fprintf(fp, "Node ID: %d\n", ctx->qc_my_id);
-
- fprintf(fp, "Score: %d/%d (Minimum required = %d)\n",
- score, score_max, score_req);
- fprintf(fp, "Current state: %s\n", state_str(ctx->qc_status));
-
- /*
- fprintf(fp, "Current disk state: %s\n",
- state_str(ctx->qc_disk_status));
- */
- fprintf(fp, "Initializing Set: {");
- for (x=0; x<max; x++) {
- if (ni[x].ni_status.ps_state == S_INIT && ni[x].ni_seen)
- fprintf(fp," %d", ni[x].ni_status.ps_nodeid);
- }
- fprintf(fp, " }\n");
-
- fprintf(fp, "Visible Set: {");
- for (x=0; x<max; x++) {
- if (ni[x].ni_state >= S_RUN || ni[x].ni_status.ps_nodeid ==
- ctx->qc_my_id)
- fprintf(fp," %d", ni[x].ni_status.ps_nodeid);
- }
- fprintf(fp, " }\n");
-
- if (ctx->qc_status == S_INIT)
- goto out;
-
- if (ctx->qc_master)
- fprintf(fp, "Master Node ID: %d\n", ctx->qc_master);
- else
- fprintf(fp, "Master Node ID: (none)\n");
-
- if (!ctx->qc_master)
- goto out;
-
- fprintf(fp, "Quorate Set: {");
- for (x=0; x<max; x++) {
- if (is_bit_set(ni[ctx->qc_master-1].ni_status.ps_master_mask,
- ni[x].ni_status.ps_nodeid-1,
- sizeof(memb_mask_t))) {
- fprintf(fp," %d", ni[x].ni_status.ps_nodeid);
- }
- }
-
- fprintf(fp, " }\n");
-
-out:
- if (ctx->qc_flags & RF_DEBUG) {
- for (x = 0; x < max; x++)
- print_node_info(fp, &ni[x]);
- }
-
- fprintf(fp, "\n");
- if (need_close)
- fclose(fp);
-}
-
-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;
- const 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) {
- logt_print(LOG_WARNING, "set_priority [%s] failed: %s\n", func,
- strerror(errno));
- }
-}
-
-
-static int
-cman_wait(cman_handle_t ch, struct timeval *_tv)
-{
- fd_set rfds;
- int fd = cman_get_fd(ch);
- struct timeval tv_local = {0, 0};
- struct timeval *tv = _tv;
-
- if (!_tv)
- tv = &tv_local;
-
- 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;
-}
-
-
-/*
- Listen for cman events
- */
-static void
-process_cman_event(cman_handle_t handle, void *private, int reason, int arg)
-{
- qd_priv_t *qp = (qd_priv_t *)private;
- qd_ctx *ctx = qp->ctx;
-
- switch(reason) {
- case CMAN_REASON_PORTOPENED:
- break;
- case CMAN_REASON_TRY_SHUTDOWN:
- _running = 0;
- _cman_shutdown = 1;
- break;
- case CMAN_REASON_CONFIG_UPDATE:
- get_config_data(ctx, NULL, 0, &fake_cfh);
- break;
- case CMAN_REASON_PORTCLOSED:
- break;
- case CMAN_REASON_STATECHANGE:
- /* Not used */
- break;
- }
-}
-
-
-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, rd_lastok, wr_lastok;
-
- ctx->qc_status = S_NONE;
-
- maxtime.tv_usec = 0;
- maxtime.tv_sec = ctx->qc_interval * ctx->qc_tko;
-
- interval.tv_usec = 0;
- interval.tv_sec = ctx->qc_interval;
-
- rd_lastok.tv_usec = 0;
- rd_lastok.tv_sec = 0;
-
- wr_lastok.tv_usec = 0;
- wr_lastok.tv_sec = 0;
-
- get_my_score(&score, &score_max);
- if (score_max < ctx->qc_scoremin) {
- logt_print(LOG_WARNING, "Minimum score (%d) is impossible to "
- "achieve (heuristic total = %d)\n",
- ctx->qc_scoremin, score_max);
- }
-
- _running = 1;
- while (_running) {
- if (_reconfig) {
- get_config_data(ctx, NULL, 0, &fake_cfh);
- _reconfig = 0;
- }
-
- /* XXX this was getuptime() in clumanager */
- get_time(&oldtime, (ctx->qc_flags&RF_UPTIME));
-
- /* Read everyone else's status */
- if ((errors = read_node_blocks(ctx, ni, max)) == 0 )
- get_time(&rd_lastok, ctx->qc_flags&RF_UPTIME);
-
- /* Check for node transitions */
- check_transitions(ctx, ni, max, mask);
-
- /* Check heuristics and remove ourself if necessary */
- get_my_score(&score, &score_max);
-
- /* If we recently upgraded, decrement our wait time */
- if (upgrade > 0)
- --upgrade;
-
- score_req = ctx->qc_scoremin;
- if (score_req <= 0)
- score_req = (score_max/2 + 1);
-
- if (score < score_req) {
- clear_bit(mask, (ctx->qc_my_id-1), sizeof(mask));
- if (ctx->qc_status > S_NONE) {
- logt_print(LOG_NOTICE,
- "Score insufficient for master "
- "operation (%d/%d; required=%d); "
- "downgrading\n",
- score, score_max, score_req);
- ctx->qc_status = S_NONE;
- adjust_votes(ctx);
- msg.m_msg = M_NONE;
- ++msg.m_seq;
- bid_pending = 0;
- if (cman_wait(ctx->qc_cman_user, NULL) < 0) {
- logt_print(LOG_ERR, "cman: %s\n",
- strerror(errno));
- } else {
- cman_poll_quorum_device(ctx->qc_cman_admin, 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) {
- logt_print(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) {
- logt_print(LOG_WARNING, "Master conflict: abdicating\n");
-
- /* Handle just like a recent upgrade */
- ctx->qc_status = S_RUN;
- adjust_votes(ctx);
- 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.
- */
-
- logt_print(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;
-
- logt_print(LOG_INFO,
- "Assuming master role\n");
- ctx->qc_status = S_MASTER;
- adjust_votes(ctx);
- 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. */
-
- logt_print(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_wait(ctx->qc_cman_user, NULL) < 0) {
- logt_print(LOG_ERR, "cman_dispatch: %s\n",
- strerror(errno));
- logt_print(LOG_ERR,
- "Halting qdisk operations\n");
- return -1;
- }
- check_cman(ctx, mask, master_mask);
- if (!errors)
- cman_poll_quorum_device(ctx->qc_cman_admin, 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_wait(ctx->qc_cman_user, NULL) < 0) {
- logt_print(LOG_ERR, "cman_dispatch: %s\n",
- strerror(errno));
- logt_print(LOG_ERR,
- "Halting qdisk operations\n");
- return -1;
- }
- if (!errors) {
- cman_poll_quorum_device(
- ctx->qc_cman_admin,
- 1);
- }
- }
- }
-
- /* Write out our status */
- if (qd_write_status(ctx, ctx->qc_my_id, ctx->qc_status,
- &msg, mask, master_mask) != 0) {
- logt_print(LOG_ERR, "Error writing to quorum disk\n");
- errors++; /* this value isn't really used
- at this point */
- } else {
- get_time(&wr_lastok, ctx->qc_flags&RF_UPTIME);
- }
-
- /* write out our local status */
- update_local_status(ctx, ni, max, score, score_req, score_max);
-
- /* Cycle. We could time the loop and sleep
- (interval-looptime), but this is fine for now.*/
- get_time(&newtime, ctx->qc_flags&RF_UPTIME);
-
- /*
- * Reboot if the last successful hearbeat was longer ago than interval*TKO_COUNT
- */
- _diff_tv(&diff, &wr_lastok, &newtime);
- if (_cmp_tv(&maxtime, &diff) == 1 &&
- ctx->qc_flags & RF_IOTIMEOUT) {
- logt_print(LOG_EMERG, "Failed to send a heartbeat "
- "within %d second%s (%d.%06d) - REBOOTING\n",
- (int)maxtime.tv_sec,
- maxtime.tv_sec==1?"":"s",
- (int)diff.tv_sec,
- (int)diff.tv_usec);
- if (!(ctx->qc_flags & RF_DEBUG))
- reboot(RB_AUTOBOOT);
- }
-
- /*
- * Reboot if the last successful hearbeat was longer ago than interval*TKO_COUNT
- */
- _diff_tv(&diff, &rd_lastok, &newtime);
- if (_cmp_tv(&maxtime, &diff) == 1 &&
- ctx->qc_flags & RF_IOTIMEOUT) {
- logt_print(LOG_EMERG,
- "Failed to read from qdisk within "
- "%d second%s (%d.%06d) - REBOOTING\n",
- (int)maxtime.tv_sec,
- maxtime.tv_sec==1?"":"s",
- (int)diff.tv_sec,
- (int)diff.tv_usec);
- if (!(ctx->qc_flags & RF_DEBUG))
- reboot(RB_AUTOBOOT);
- }
-
- /*
- * Reboot if we didn't send a heartbeat in interval*TKO_COUNT
- */
- _diff_tv(&diff, &oldtime, &newtime);
- if (_cmp_tv(&maxtime, &diff) == 1 &&
- ctx->qc_flags & RF_PARANOID) {
- logt_print(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 {
- logt_print(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) {
- logt_print(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) {
- if (cman_wait(ctx->qc_cman_user, &sleeptime) < 0)
- logt_print(LOG_ERR, "cman_dispatch: %s\n",
- strerror(errno));
- }
- }
-
- return !!errors;
-}
-
-
-/**
- Tell the other nodes to elect a new master != me.
- */
-static int
-quorum_reelect_master(qd_ctx *ctx, node_info_t *ni, int max)
-{
- if (qd_write_status(ctx, ctx->qc_my_id, S_EXIT,
- NULL, NULL, NULL) != 0) {
- logt_print(LOG_WARNING,
- "Error writing to quorum disk during reelect_master\n");
- }
-
- while (1) {
- int master, x;
- int found = 0;
- int low_id, count;
-
- read_node_blocks(ctx, ni, max);
-
- for (x = 0; x < max; x++) {
- if (ni[x].ni_state >= S_RUN) {
- found = 1;
- }
- }
-
- if (!found) {
- logt_print(LOG_DEBUG, "No other nodes are active. Exiting\n");
- break;
- }
-
- master = master_exists(ctx, ni, max, &low_id, &count);
- if (master) {
- logt_print(LOG_DEBUG, "New master elected: %d\n", master);
- break;
- }
- /*
- * give time for message to be read
- */
- sleep(1);
- }
-
- return 0;
-}
-
-/**
- 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) {
- logt_print(LOG_WARNING,
- "Error writing to quorum disk during logout\n");
- }
- return 0;
-}
-
-
-static void
-conf_logging(int debug, int logmode, int facility, int loglevel,
- int filelevel, char *fname)
-{
- static int _log_config = 0;
-
- if (debug)
- _debug |= DEBUG_CONF;
- else
- _debug &= ~DEBUG_CONF;
- if (_debug)
- loglevel = LOG_DEBUG;
- if (_foreground)
- logmode |= LOG_MODE_OUTPUT_STDERR;
-
- if (!_log_config) {
- logt_init(LOG_DAEMON_NAME, logmode, facility, loglevel,
- filelevel, fname);
- _log_config = 1;
- return;
-
- }
-
- logt_conf(LOG_DAEMON_NAME, logmode, facility, loglevel,
- filelevel, fname);
-}
-
-
-static int
-ccs_read_old_logging(int ccsfd, int *facility, int *priority)
-{
- char query[256];
- char *val;
- int x, ret = 0;
-
- /* Get log log_facility */
- snprintf(query, sizeof(query), "/cluster/quorumd/@log_facility");
- if (ccs_get(ccsfd, query, &val) == 0) {
- logt_print(LOG_WARNING,
- "Use of quorumd/@log_facility is deprecated!\n");
- for (x = 0; facilitynames[x].c_name; x++) {
- if (strcasecmp(val, facilitynames[x].c_name))
- continue;
- *facility = facilitynames[x].c_val;
- ret = 1;
- break;
- }
- free(val);
- }
-
- /* Get log level */
- snprintf(query, sizeof(query), "/cluster/quorumd/@log_level");
- if (ccs_get(ccsfd, query, &val) == 0) {
- logt_print(LOG_WARNING,
- "Use of quorumd/@log_level is deprecated!\n");
- *priority = atoi(val);
- free(val);
- if (*priority < 0)
- *priority = SYSLOGLEVEL;
- else
- ret = 1;
- }
-
- return ret;
-}
-
-
-/**
- Grab logsys configuration data from libccs
- */
-static int
-get_log_config_data(int ccsfd)
-{
- char fname[PATH_MAX];
- int debug = 0, logmode = LOG_MODE_OUTPUT_FILE | LOG_MODE_OUTPUT_SYSLOG;
- int facility = SYSLOGFACILITY;
- int loglevel = SYSLOGLEVEL, filelevel = SYSLOGLEVEL;
- int need_close = 0;
-
- logt_print(LOG_DEBUG, "Loading logging configuration\n");
-
- if (ccsfd < 0) {
- ccsfd = ccs_connect();
- if (ccsfd < 0) {
- logt_print(LOG_ERR, "Logging configuration "
- "unavailable; using defaults\n");
- return -1;
- }
- need_close = 1;
- }
-
- snprintf(fname, sizeof(fname)-1, LOGDIR "/qdiskd.log");
- if (ccs_read_old_logging(ccsfd, &facility, &loglevel))
- filelevel = loglevel;
-
- ccs_read_logging(ccsfd, (char *)"QDISKD", &debug, &logmode,
- &facility, &loglevel, &filelevel, (char *)fname);
- conf_logging(debug, logmode, facility, loglevel, filelevel, fname);
-
- if (need_close)
- ccs_disconnect(ccsfd);
-
- return 0;
-}
-
-
-/*
- * return number of nodes - 1 on success
- * -1 on generic error
- * -2 if one of the node votes is != 1
- */
-static int
-auto_qdisk_votes(int desc)
-{
- int ret = 1;
- char buf[PATH_MAX];
- char *v = NULL, *name = NULL;
-
- while (1) {
- int votes=0;
-
- name = NULL;
- snprintf(buf, sizeof(buf)-1,
- "/cluster/clusternodes/clusternode[%d]/@name", ret);
- if (ccs_get(desc, buf, &name) != 0)
- break;
-
- snprintf(buf, sizeof(buf)-1,
- "/cluster/clusternodes/clusternode[%d]/@votes", ret);
-
- if (ccs_get(desc, buf, &v) == 0) {
- votes = atoi(v);
- free(v);
- v = NULL;
- } else {
- votes = 1;
- }
-
- if (votes != 1) {
-
- logt_print(LOG_ERR, "%s's vote count is %d\n",
- name, votes);
- free(name);
-
- logt_print(LOG_ERR, "Set all node vote counts to 1 "
- "or specify qdiskd's votes\n");
- return -2;
- }
-
- free(name);
- ret++;
- }
-
- // adjust count (one from init and one from the node count)
- ret = ret - 2;
-
- if (ret <= 0)
- logt_print(LOG_ERR, "Unable to determine qdiskd votes "
- "automatically\n");
- else
- logt_print(LOG_DEBUG, "Setting autocalculated votes to %d\n", ret);
-
- return (ret);
-}
-
-
-static int
-get_dynamic_config_data(qd_ctx *ctx, int ccsfd)
-{
- char *val = NULL;
- char query[256];
- int old_votes = 0, found = 0;
-
- if (ccsfd < 0)
- return -1;
-
- logt_print(LOG_DEBUG, "Loading dynamic configuration\n");
-
- /* Check label / device presence. If it disappeared, we need to exit */
- if (ctx->qc_config) {
- val = NULL;
- snprintf(query, sizeof(query), "/cluster/quorumd/@device");
- found = ccs_get(ccsfd, query, &val);
- if (found != 0) {
- val = NULL;
- snprintf(query, sizeof(query), "/cluster/quorumd/@label");
- found = ccs_get(ccsfd, query, &val);
- free(val);
- }
-
- if (found != 0) {
- logt_print(LOG_NOTICE,
- "Quorum device removed from the configuration."
- " Shutting down.\n");
- ctx->qc_votes = 0;
- register_device(ctx);
- _running = 0;
- return -1;
- }
- }
-
- /* Get status file */
- snprintf(query, sizeof(query), "/cluster/quorumd/@status_file");
- if (ccs_get(ccsfd, query, &val) == 0) {
- ctx->qc_status_file = val;
- }
-
- /* 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:
- logt_print(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);
- }
- set_priority(ctx->qc_sched, ctx->qc_sched_prio);
-
- /* 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 flag to see if we're supposed to kill cman if qdisk is not
- * available.
- */
- /* default = off, so, 1 to turn on */
- snprintf(query, sizeof(query), "/cluster/quorumd/@stop_cman");
- if (ccs_get(ccsfd, query, &val) == 0) {
- if (!atoi(val))
- ctx->qc_flags &= ~RF_STOP_CMAN;
- else
- ctx->qc_flags |= RF_STOP_CMAN;
- free(val);
- }
-
- /* default = off, so, 1 to turn on */
- snprintf(query, sizeof(query), "/cluster/quorumd/@io_timeout");
- if (ccs_get(ccsfd, query, &val) == 0) {
- if (!atoi(val))
- ctx->qc_flags &= ~RF_IOTIMEOUT;
- else
- ctx->qc_flags |= RF_IOTIMEOUT;
- free(val);
- }
-
- /*
- * Get flag to see if we're supposed to reboot if we can't complete
- * a pass in failure time
- */
- /* default = off, so, 1 to turn on */
- snprintf(query, sizeof(query), "/cluster/quorumd/@paranoid");
- if (ccs_get(ccsfd, query, &val) == 0) {
- if (!atoi(val))
- ctx->qc_flags &= ~RF_PARANOID;
- else
- ctx->qc_flags |= RF_PARANOID;
- free(val);
- }
-
- /*
- * Get flag to see if we're supposed to reboot if we can't complete
- * a pass in failure time
- */
- /* default = off, so, 1 to turn on */
- snprintf(query, sizeof(query), "/cluster/quorumd/@allow_kill");
- if (ccs_get(ccsfd, query, &val) == 0) {
- if (!atoi(val))
- ctx->qc_flags &= ~RF_ALLOW_KILL;
- else
- ctx->qc_flags |= RF_ALLOW_KILL;
- free(val);
- }
-
- /*
- * How many consecutive error cycles do we allow before
- * giving up?
- *
- * Notice that max_error_cycles is disabled if io_timeout is
- * active.
- */
- /* 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_flags & RF_IOTIMEOUT))
- ctx->qc_max_error_cycles = 0;
- free(val);
- }
-
- /* Get votes */
- if (ctx->qc_config) {
- old_votes = ctx->qc_votes;
- ctx->qc_flags &= ~RF_AUTO_VOTES;
- }
-
- ctx->qc_auto_votes = auto_qdisk_votes(ccsfd);
-
- snprintf(query, sizeof(query), "/cluster/quorumd/@votes");
- if (ccs_get(ccsfd, query, &val) == 0) {
- ctx->qc_votes = atoi(val);
- free(val);
- if (ctx->qc_votes < 0)
- ctx->qc_votes = 0;
- } else {
- ctx->qc_votes = ctx->qc_auto_votes;
- if (ctx->qc_votes < 0) {
- if (ctx->qc_config) {
- logt_print(LOG_WARNING, "Unable to determine "
- "new vote value; retaining old "
- "value of %d\n", old_votes);
- ctx->qc_votes = old_votes;
- } else {
- /* During startup, this is fatal */
- return -1;
- }
- } else {
- ctx->qc_flags |= RF_AUTO_VOTES;
- }
- }
-
- if (ctx->qc_config && old_votes != ctx->qc_votes) {
- logt_print(LOG_DEBUG, "Changing vote count from %d to %d\n",
- old_votes, ctx->qc_votes);
-
- if (ctx->qc_flags & RF_AUTO_MASTER_WINS) {
- logt_print(LOG_DEBUG, "Vote count changed! "
- "Disabling master-wins\n");
- ctx->qc_flags &= ~(RF_MASTER_WINS|RF_AUTO_MASTER_WINS);
- }
-
- /*
- * Here, we are reconfiguring _only_ the votes. The
- * label / cman runflags do not change during reconfiguration
- *
- * This only works after we have already gotten static
- * configuration data during initial startup.
- */
- register_device(ctx);
- }
-
- return 0;
-}
-
-
-static int
-get_static_config_data(qd_ctx *ctx, int ccsfd)
-{
- char *val = NULL;
- char query[256];
- int qdisk_fo;
-
- if (ccsfd < 0)
- return -1;
-
- logt_print(LOG_DEBUG, "Loading static configuration\n");
-
- /* 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;
- }
-
- snprintf(query, sizeof(query), "/cluster/totem/@token");
- if (ccs_get(ccsfd, query, &val) == 0) {
- ctx->qc_token_timeout = atoi(val);
- free(val);
- if (ctx->qc_token_timeout < 10000) {
- logt_print(LOG_ERR, "Token timeout %d is too fast "
- "to use with qdiskd!\n",
- ctx->qc_token_timeout);
- return -1;
- }
- } else {
- ctx->qc_token_timeout = DEFAULT_TOKEN_TIMEOUT;
- }
-
- /* Get tko */
- snprintf(query, sizeof(query), "/cluster/quorumd/@tko");
- if (ccs_get(ccsfd, query, &val) == 0) {
- ctx->qc_tko = atoi(val);
- free(val);
- } else {
- ctx->qc_tko = ((ctx->qc_token_timeout / 1000) -
- ctx->qc_interval) / 2;
- logt_print(LOG_DEBUG, "Auto-configured TKO as %d based on "
- "token=%d interval=%d\n", ctx->qc_tko,
- ctx->qc_token_timeout, ctx->qc_interval);
- }
-
- if (ctx->qc_tko < 4) {
- logt_print(LOG_WARNING, "Quorum disk TKO (%d) is too low!\n",
- ctx->qc_tko);
- }
-
- /* 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;
-
- logt_print(LOG_DEBUG, "Timings: %d tko, %d interval\n",
- ctx->qc_tko, ctx->qc_interval);
- logt_print(LOG_DEBUG, "Timings: %d tko_up, %d master_wait, "
- "%d upgrade_wait\n",
- ctx->qc_tko_up, ctx->qc_master_wait, ctx->qc_upgrade_wait);
-
- qdisk_fo = ctx->qc_interval * (ctx->qc_master_wait +
- ctx->qc_upgrade_wait +
- ctx->qc_tko) * 1000;
- if (qdisk_fo >= ctx->qc_token_timeout) {
- logt_print(LOG_ERR, "Quorum disk timings are too slow for "
- "configured token timeout\n");
- logt_print(LOG_ERR, " * Totem Token timeout: %dms\n",
- ctx->qc_token_timeout);
- logt_print(LOG_ERR, " * Min. Master recovery time: %dms\n",
- qdisk_fo);
- logt_print(LOG_ERR,
- "Please set token timeout to at least %dms\n",
- qdisk_fo + (ctx->qc_interval * 1000));
- return -1;
- }
-
- /* 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;
- /* courtesy info message */
- if (ctx->qc_device)
- logt_print(LOG_INFO, "Quorum Label (%s) will be used to "
- "locate quorum partition, overriding Quorum Device\n",
- ctx->qc_label);
- }
-
- if (!ctx->qc_device && !ctx->qc_label) {
- logt_print(LOG_ERR, "No device or label specified; cannot "
- "run QDisk services.\n");
- return -1;
- }
-
- /* 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 master-wins flag for when we transition -> offline */
- /* default = off, so, 1 to turn on */
- snprintf(query, sizeof(query), "/cluster/quorumd/@master_wins");
- if (ccs_get(ccsfd, query, &val) == 0) {
- if (atoi(val))
- ctx->qc_flags |= RF_MASTER_WINS;
- 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 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);
- }
-
- return 0;
-}
-
-
-/**
- Grab all our configuration data from libccs
- */
-static int
-get_config_data(qd_ctx *ctx, struct h_data *h, int maxh, int *cfh)
-{
- int ccsfd = -1, ret = -1;
-
- ccsfd = ccs_connect();
- if (ccsfd < 0) {
- logt_print(LOG_CRIT, "Configuration unavailable; "
- "cannot start\n");
- return -1;
- }
-
- get_log_config_data(ccsfd);
-
- /* Initialize defaults if we are not reconfiguring */
- if (ctx->qc_config == 0) {
- ctx->qc_interval = 1;
- ctx->qc_tko = 10;
- ctx->qc_scoremin = 0;
- ctx->qc_flags = RF_REBOOT | RF_ALLOW_KILL | RF_UPTIME;
- /* | RF_STOP_CMAN;*/
-
- ctx->qc_sched = SCHED_RR;
- ctx->qc_sched_prio = 1;
- ctx->qc_max_error_cycles = 0;
- }
-
- if (get_dynamic_config_data(ctx, ccsfd) < 0) {
- goto out;
- }
-
- if (ctx->qc_config) {
- ret = 0;
- goto out;
- }
-
- ctx->qc_config = 1;
-
- if (get_static_config_data(ctx, ccsfd) < 0) {
- goto out;
- }
-
- /* Heuristics need to report in 1 cycle before we need to
- * report in so we can get their score.
- */
- *cfh = configure_heuristics(ccsfd, h, maxh,
- ctx->qc_interval * (ctx->qc_tko - 1));
-
- if (ctx->qc_flags & RF_MASTER_WINS) {
- if (*cfh) {
- logt_print(LOG_WARNING, "Master-wins mode disabled "
- "(not compatible with heuristics)\n");
- ctx->qc_flags &= ~RF_MASTER_WINS;
- }
- if (ctx->qc_auto_votes != 1) {
- logt_print(LOG_WARNING, "Master-wins mode disabled "
- "(not compatible with more than 2 nodes)\n");
- ctx->qc_flags &= ~RF_MASTER_WINS;
- }
- } else {
- if (ctx->qc_flags & RF_AUTO_VOTES &&
- !*cfh &&
- ctx->qc_auto_votes == 1) {
- /* Two node cluster, no heuristics, 1 vote for
- * quorum disk daemon. Safe to enable master-wins.
- * In fact, qdiskd without master-wins in this config
- * is a waste of resources.
- */
- ctx->qc_flags |= RF_MASTER_WINS | RF_AUTO_MASTER_WINS;
- logt_print(LOG_INFO, "Enabling master-wins mode for "
- "simple two-node cluster\n");
- }
- }
-
- ret = 0;
-
- logt_print(LOG_DEBUG, "Quorum Daemon: %d heuristics, "
- "%d interval, %d tko, %d votes\n",
- *cfh, ctx->qc_interval, ctx->qc_tko, ctx->qc_votes);
- logt_print(LOG_DEBUG, "Run Flags: %08x\n", ctx->qc_flags);
-out:
- ccs_disconnect(ccsfd);
-
- return ret;
-}
-
-
-static void
-check_stop_cman(qd_ctx *ctx)
-{
- if (!(ctx->qc_flags & RF_STOP_CMAN))
- return;
-
- logt_print(LOG_WARNING, "Telling CMAN to leave the cluster; "
- "qdisk is not available\n");
- if (cman_shutdown(ctx->qc_cman_admin, 0) < 0) {
- logt_print(LOG_CRIT,
- "Could not leave the cluster - rebooting\n");
- sleep(5);
- if (ctx->qc_flags & RF_DEBUG) {
- logt_print(LOG_CRIT, "Debug mode specified! "
- "Reboot averted.\n");
- return;
- }
- reboot(RB_AUTOBOOT);
- }
-}
-
-
-#define logt_print_once(level, fmt, args...) \
-do { static int _logged=0; if (!_logged) { _logged=1; logt_print(level, fmt, ##args); } } while(0)
-
-
-static void
-qdisk_whine(cman_handle_t h, void *privdata, char *buf, int len,
- uint8_t port, int nodeid)
-{
- int32_t dstate;
- qd_priv_t *qp = (qd_priv_t *)privdata;
- node_info_t *ni = qp->ni;
-
- if (len != sizeof(dstate)) {
- return;
- }
-
- dstate = *((int32_t*)buf);
-
- if (nodeid == (qp->ctx->qc_my_id))
- return;
-
- swab32(dstate);
-
- if (dstate) {
- logt_print(LOG_NOTICE, "qdiskd on node %d reports hung %s()\n", nodeid,
- state_to_string(dstate));
- ni[nodeid-1].ni_misses = 0;
- }
-}
-
-
-int
-main(int argc, char **argv)
-{
- cman_node_t me;
- int cfh = 0, rv, nfd = -1, ret = -1, active;
- qd_ctx ctx;
- cman_handle_t ch_admin = NULL;
- cman_handle_t ch_user = NULL;
- node_info_t ni[MAX_NODES_DISK];
- struct h_data h[10];
- char device[128];
- pid_t pid;
- quorum_header_t qh;
- qd_priv_t qp;
-
-
- rv = check_process_running(argv[0], &pid);
- if (rv < 0) {
- fprintf(stderr, "Unable to determin if %s is already running: %s\n",
- argv[0], strerror(errno));
- return -1;
- }
- if (rv && pid !=getpid()) {
- printf("QDisk services already running\n");
- return 0;
- }
-
- while ((rv = getopt(argc, argv, "fdQs")) != EOF) {
- switch (rv) {
- case 'd':
- _debug = DEBUG_CMDLINE;
- break;
- case 'f':
- _foreground = 1;
- break;
- case 'Q':
- /* Make qdisk very quiet */
- nfd = open("/dev/null", O_RDWR);
- if (nfd < 0) {
- fprintf(stderr, "Could not open /dev/null!\n");
- ret = -1;
- goto out;
- }
- close(0);
- close(1);
- close(2);
- dup2(nfd, 0);
- dup2(nfd, 1);
- dup2(nfd, 2);
- close(nfd);
- break;
- default:
- break;
- }
- }
-
- if(getenv("QDISK_DEBUG"))
- _debug = 1;
-
- if (!_foreground && daemon_init(argv[0]) < 0) {
- fprintf(stderr, "Could not fork: %s\n", strerror(errno));
- goto out;
- }
-
- conf_logging(0, LOG_MODE_OUTPUT_SYSLOG, SYSLOGFACILITY,
- SYSLOGLEVEL, 0, NULL);
-
- while (_running && (ch_admin = cman_admin_init(NULL)) == NULL) {
- logt_print_once(LOG_INFO, "Waiting for CMAN to start\n");
- sleep(1);
- }
-
- while (_running && (active = cman_is_active(ch_admin)) <= 0) {
- logt_print_once(LOG_INFO,
- "Waiting for CMAN to become active\n");
- if (active < 0) {
- logt_print(LOG_CRIT, "cman_is_active: %s\n",
- strerror(errno));
- goto out;
- }
- sleep(1);
- }
-
- if (!_running)
- goto out;
-
- /* For cman notifications we need two sockets - one for events,
- one for config change callbacks */
- qp.ctx = &ctx;
- qp.ni = &ni[0];
- qp.ni_len = MAX_NODES_DISK;
-
- ch_user = cman_init(&qp);
- if (cman_start_notification(ch_user, process_cman_event) != 0) {
- logt_print(LOG_CRIT, "Could not register with CMAN: %s\n",
- strerror(errno));
- goto out;
- }
-
- if (cman_start_recv_data(ch_user, qdisk_whine, CLUSTER_PORT_QDISKD) != 0) {
- logt_print(LOG_CRIT, "Could not register with CMAN: %s\n",
- strerror(errno));
- goto out;
- }
-
- memset(&me, 0, sizeof(me));
- if (cman_get_node(ch_admin, CMAN_NODEID_US, &me) < 0) {
- logt_print(LOG_CRIT, "Could not determine local node ID: %s\n",
- strerror(errno));
- goto out;
- }
-
- qd_init(&ctx, ch_admin, ch_user, me.cn_nodeid);
-
- signal(SIGINT, int_handler);
- signal(SIGTERM, int_handler);
- signal(SIGHUP, hup_handler);
- signal(SIGUSR1, usr1_handler);
-
- /* RF_DEBUG can only be set from the command line */
- if (_debug)
- ctx.qc_flags |= RF_DEBUG;
-
- if (get_config_data(&ctx, h, 10, &cfh) < 0) {
- logt_print(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) {
- logt_print(LOG_CRIT, "Unable to match label"
- " '%s' to any device\n",
- ctx.qc_label);
- check_stop_cman(&ctx);
- goto out;
- } else if (ret > 0) {
- logt_print(LOG_WARNING, "%d matches found for "
- "label '%s'; please use 'device=' "
- "instead!\n", ret, ctx.qc_label);
- }
-
- if (ctx.qc_device)
- free(ctx.qc_device);
- ctx.qc_device = strdup(device);
-
- logt_print(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) {
- logt_print(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) {
- logt_print(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;
- }
- }
-
- ret = quorum_init(&ctx, ni, MAX_NODES_DISK, h, cfh);
- if (ret < 0) {
- logt_print(LOG_CRIT, "Initialization failed\n");
- check_stop_cman(&ctx);
- goto out;
- } else if (ret > 0) {
- /* ret > 0 means we received a shutdown during initialization */
- /* Write our 'clean down' state to disk and get out of here */
- logt_print(LOG_INFO, "Shutdown request received during initialization\n");
- quorum_logout(&ctx);
- goto out;
- }
-
- ret = 0;
-
- if (!_running)
- goto out;
-
- /* This registers the quorum device */
- ret = register_device(&ctx);
- if (ret) {
- if (errno == EBUSY) {
- logt_print(LOG_NOTICE, "quorum device is already registered, updating\n");
- ret = update_device(&ctx);
- if (ret) {
- logt_print(LOG_ERR, "Unable to update quorum device info!\n");
- goto out;
- }
- } else {
- logt_print(LOG_ERR, "Unable to register quorum device!\n");
- goto out;
- }
- }
-
- io_nanny_start(ch_user, ctx.qc_tko * ctx.qc_interval);
-
- if (quorum_loop(&ctx, ni, MAX_NODES_DISK) == 0) {
- /*
- * if we are master and we are in master-win mode,
- * request other qdiskd to elect a new one
- */
- if ((ctx.qc_status == S_MASTER) &&
- ((ctx.qc_flags & RF_MASTER_WINS) ||
- (ctx.qc_flags & RF_AUTO_MASTER_WINS))) {
- quorum_reelect_master(&ctx, ni, MAX_NODES_DISK);
- }
- /* Only clean up if we're exiting w/o error) */
- logt_print(LOG_NOTICE, "Unregistering quorum device.\n");
- cman_unregister_quorum_device(ctx.qc_cman_admin);
- quorum_logout(&ctx);
- }
-
- io_nanny_stop();
-
-out:
- /* free cman handle to avoid leak in cman */
- cman_finish(ch_admin);
- if (_cman_shutdown) {
- cman_replyto_shutdown(ch_user, 1);
- cman_finish(ch_user);
- }
- qd_destroy(&ctx);
- logt_exit();
- daemon_cleanup();
- return ret;
-}
-
diff --git a/cman/qdisk/mkqdisk.c b/cman/qdisk/mkqdisk.c
deleted file mode 100644
index 6d64ee5..0000000
--- a/cman/qdisk/mkqdisk.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- @file Quorum disk utility
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <disk.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <platform.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <liblogthread.h>
-
-#define PROGRAM_NAME "mkqdisk"
-
-int
-main(int argc, char **argv)
-{
- char device[128];
- char *newdev = NULL, *newlabel = NULL;
- int rv, flg = 0, verbose_level = 1;
-
- printf(PROGRAM_NAME " 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;
- if (verbose_level > LOG_DEBUG)
- verbose_level = LOG_DEBUG;
- break;
- }
- }
-
- logt_init(PROGRAM_NAME, LOG_MODE_OUTPUT_STDERR,
- verbose_level, verbose_level, verbose_level, NULL);
-
- /* 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 */
- flg = rv;
- break;
- case 'f':
- flg = rv;
- newlabel = optarg;
- break;
- case 'c':
- newdev = optarg;
- break;
- case 'l':
- newlabel = optarg;
- break;
- case 'h':
- printf("usage: mkqdisk -L | -f <label> | -c "
- "<device> -l <label> [-d]\n");
- return 0;
- default:
- break;
- }
- }
-
- /* list */
- if (flg == 'L') {
- return find_partitions(NULL, NULL, 0, verbose_level);
- } else if (flg == 'f') {
- return find_partitions( newlabel, device,
- sizeof(device), verbose_level);
- }
-
- if (!newdev && !newlabel) {
- printf("usage: mkqdisk -L | -f <label> | -c "
- "<device> -l <label>\n");
- return 1;
- }
-
- if (!newdev || !newlabel) {
- printf("Both a device and a label are required\n");
- return 1;
- }
-
- printf("Writing new quorum disk label '%s' to %s.\n",
- newlabel, newdev);
- printf("WARNING: About to destroy all data on %s; proceed [N/y] ? ",
- newdev);
- if (getc(stdin) != 'y') {
- printf("Good thinking.\n");
- return 0;
- }
-
- return qdisk_init(newdev, newlabel);
-}
diff --git a/cman/qdisk/platform.h b/cman/qdisk/platform.h
deleted file mode 100644
index b1dfc64..0000000
--- a/cman/qdisk/platform.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/** @file
- * Defines for byte-swapping
- */
-#ifndef __PLATFORM_H
-#define __PLATFORM_H
-
-#include <endian.h>
-#include <sys/param.h>
-#include <byteswap.h>
-#include <bits/wordsize.h>
-
-/* No swapping on little-endian machines */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define le_swap16(x) (x)
-#define le_swap32(x) (x)
-#define le_swap64(x) (x)
-#else
-#define le_swap16(x) bswap_16(x)
-#define le_swap32(x) bswap_32(x)
-#define le_swap64(x) bswap_64(x)
-#endif
-
-/* No swapping on big-endian machines */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define be_swap16(x) bswap_16(x)
-#define be_swap32(x) bswap_32(x)
-#define be_swap64(x) bswap_64(x)
-#else
-#define be_swap16(x) (x)
-#define be_swap32(x) (x)
-#define be_swap64(x) (x)
-#endif
-
-
-#define swab16(x) x=be_swap16(x)
-#define swab32(x) x=be_swap32(x)
-#define swab64(x) x=be_swap64(x)
-
-
-#endif /* __PLATFORM_H */
diff --git a/cman/qdisk/proc.c b/cman/qdisk/proc.c
deleted file mode 100644
index 688a4d1..0000000
--- a/cman/qdisk/proc.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/**
- @file Quorum disk /proc/partition scanning functions
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <disk.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <platform.h>
-#include <stdlib.h>
-#include <string.h>
-#include <liblogthread.h>
-#include "scandisk.h"
-
-const char *state_str(disk_node_state_t s);
-
-struct device_args {
- char *label;
- struct devnode *devnode;
- int sector_size;
- int flags;
- int count;
- int pad;
-};
-
-int
-check_device(char *device, char *label, quorum_header_t *qh,
- int flags)
-{
- int ret = -1;
- quorum_header_t qh_local;
- target_info_t disk;
-
- if (!qh)
- qh = &qh_local;
-
- ret = qdisk_validate(device);
- if (ret < 0) {
- logt_print(LOG_DEBUG, "qdisk_validate: %s\n", strerror(errno));
- return -1;
- }
-
- ret = qdisk_open(device, &disk);
- if (ret < 0) {
- logt_print(LOG_ERR, "qdisk_open: %s\n", strerror(errno));
- return -1;
- }
-
- ret = -1;
- if (qdisk_read(&disk, OFFSET_HEADER, qh, sizeof(*qh)) == sizeof(*qh)) {
- swab_quorum_header_t(qh);
- if (qh->qh_magic == HEADER_MAGIC_NUMBER) {
- if (!label || !strcmp(qh->qh_cluster, label)) {
- ret = 0;
- }
- }
- }
-
- qh->qh_kernsz = disk.d_blksz;
-
- /* only flag now is 'strict device check'; i.e.,
- "block size recorded must match kernel's reported size" */
- if (flags && qh->qh_version == VERSION_MAGIC_V2 &&
- disk.d_blksz != qh->qh_blksz) {
- ret = -1;
- }
-
- qdisk_close(&disk);
-
- return ret;
-}
-
-
-static void
-filter_devs(struct devnode *node, void *v_args)
-{
- struct device_args *args = (struct device_args *)v_args;
- quorum_header_t qh;
- quorum_header_t *ret_qh = NULL;
- int ret;
-
- if (!node->sysfsattrs.sysfs)
- return;
- if (!node->devpath)
- return;
- if (node->sysfsattrs.holders)
- return;
- /* Qdiskd doesn't work on soft-raid */
- if (node->md > 0)
- return;
-
- ret = check_device(node->devpath->path, args->label, &qh, args->flags);
- if (ret == 0) {
- ret_qh = malloc(sizeof(qh));
- if (!ret_qh)
- return;
- memcpy(ret_qh, &qh, sizeof(qh));
-
- node->filter = (void *)ret_qh;
- if (!args->count) {
- args->devnode = node;
- }
- ++args->count;
- }
-}
-
-
-const char *
-state_str(disk_node_state_t s)
-{
- switch (s) {
- case S_NONE:
- return "None";
- case S_EVICT:
- return "Evicted";
- case S_INIT:
- return "Initializing";
- case S_RUN:
- return "Running";
- case S_MASTER:
- return "Master";
- default:
- return "ILLEGAL";
- }
-}
-
-
-static void
-print_status_block(status_block_t *sb)
-{
- time_t timestamp = (time_t)sb->ps_timestamp;
- uint64_t incarnation = be_swap64(sb->ps_incarnation);
-
- if (sb->ps_state == S_NONE)
- return;
- logt_print(LOG_INFO, "Status block for node %d\n", sb->ps_nodeid);
- logt_print(LOG_INFO, "\tLast updated by node %d\n", sb->ps_updatenode);
- logt_print(LOG_INFO, "\tLast updated on %s", ctime((time_t *)×tamp));
- logt_print(LOG_INFO, "\tState: %s\n", state_str(sb->ps_state));
- logt_print(LOG_INFO, "\tFlags: %04x\n", (be_swap16(sb->ps_flags)));
- logt_print(LOG_INFO, "\tScore: %d/%d\n", sb->ps_score, sb->ps_scoremax);
- logt_print(LOG_INFO, "\tAverage Cycle speed: %d.%06d seconds\n",
- sb->ps_ca_sec, sb->ps_ca_usec);
- logt_print(LOG_INFO, "\tLast Cycle speed: %d.%06d seconds\n",
- sb->ps_lc_sec, sb->ps_lc_usec);
- logt_print(LOG_INFO, "\tIncarnation: %08x%08x\n",
- (int)(incarnation>>32&0xffffffff),
- (int)(incarnation&0xffffffff));
-
-}
-
-
-static void
-read_info(char *dev)
-{
- target_info_t ti;
- int x;
- status_block_t sb;
-
- if (qdisk_open(dev, &ti) < 0) {
- logt_print(LOG_ERR, "Could not read from %s: %s\n",
- dev, strerror(errno));
- return;
- }
-
- for (x = 0; x < MAX_NODES_DISK; x++) {
-
- if (qdisk_read(&ti,
- qdisk_nodeid_offset(x+1, ti.d_blksz),
- &sb, sizeof(sb)) < 0) {
- logt_print(LOG_ERR, "Error reading node ID block %d\n",
- x+1);
- continue;
- }
- swab_status_block_t(&sb);
- print_status_block(&sb);
- }
-
- qdisk_close(&ti);
-}
-
-
-static void
-print_qdisk_info(struct devnode *dn)
-{
- quorum_header_t *qh = (quorum_header_t *)dn->filter;
- struct devpath *dp;
- time_t timestamp = (time_t)qh->qh_timestamp;
-
- for (dp = dn->devpath; dp; dp = dp->next)
- printf("%s:\n", dp->path);
- printf("\tMagic: %08x\n", qh->qh_magic);
- printf("\tLabel: %s\n", qh->qh_cluster);
- printf("\tCreated: %s", ctime(×tamp));
- printf("\tHost: %s\n", qh->qh_updatehost);
- printf("\tKernel Sector Size: %d\n", qh->qh_kernsz);
- if (qh->qh_version == VERSION_MAGIC_V2) {
- printf("\tRecorded Sector Size: %d\n\n", (int)qh->qh_blksz);
- }
-}
-
-int
-find_partitions(const char *label, char *devname, size_t devlen, int print)
-{
- struct devlisthead *dh = NULL;
- struct devnode *dn = NULL;
- struct device_args dargs;
-
- memset(&dargs, 0, sizeof(dargs));
- dargs.label = (char *)label;
- dargs.flags = 1; /* strict device check */
- dargs.devnode = NULL; /* First matching device */
-
- dh = scan_for_dev(NULL, 5, filter_devs, (void *)(&dargs));
- if (!dh)
- goto not_found;
- if (!dargs.devnode)
- goto not_found;
-
- if (dargs.count > 0 && print) {
- for (dn = dh->devnode; dn; dn = dn->next) {
- if (dn->filter == NULL) {
- continue;
- }
-
- print_qdisk_info(dn);
- if (print >= 2) {
- /* Print node stuff */
- read_info(dn->devpath->path);
- }
- }
- }
-
- if (dargs.count >= 1 && label) {
- snprintf(devname, devlen, "%s", dargs.devnode->devpath->path);
- }
-
- for (dn = dh->devnode; dn; dn = dn->next)
- if (dn->filter)
- free(dn->filter);
- free_dev_list(dh);
-
- if (print)
- /* No errors if we're just printing stuff */
- return 0;
-
- if (dargs.count == 1 || !label)
- return 0;
-
- /* more than one match */
- return dargs.count;
-
- not_found:
- if (dh) {
- for (dn = dh->devnode; dn; dn = dn->next)
- if (dn->filter)
- free(dn->filter);
- free_dev_list(dh);
- }
- errno = ENOENT;
- return -1;
-}
diff --git a/cman/qdisk/scandisk.c b/cman/qdisk/scandisk.c
deleted file mode 100644
index f37b420..0000000
--- a/cman/qdisk/scandisk.c
+++ /dev/null
@@ -1,782 +0,0 @@
-#include <stdio.h>
-#include <time.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/param.h>
-#include <dirent.h>
-#include <sys/sysmacros.h>
-#include <sys/stat.h>
-
-#include "scandisk.h"
-
-/** search in cache helpers **/
-
-/*
- * match is 0 for exact match
- * 1 to see if the string is contained and return the first match
- */
-
-static struct devnode *find_dev_by_path(struct devnode *startnode, char *path,
- int match)
-{
- struct devnode *nextnode;
- struct devpath *nextpath;
-
- while (startnode) {
- nextnode = startnode->next;
- nextpath = startnode->devpath;
- while (nextpath) {
- if (match) {
- if (strstr(nextpath->path, path))
- return startnode;
- } else {
- if (!strcmp(nextpath->path, path))
- return startnode;
- }
- nextpath = nextpath->next;
- }
- startnode = nextnode;
- }
-
- return 0;
-}
-
-static struct devnode *find_dev_by_majmin(struct devnode *startnode, int maj,
- int min)
-{
- struct devnode *nextnode;
-
- while (startnode) {
- nextnode = startnode->next;
- if ((startnode->maj == maj) && (startnode->min == min))
- return startnode;
- startnode = nextnode;
- }
-
- return 0;
-}
-
-/** free the cache.. this one is easy ;) **/
-
-/* free all the path associated to one node */
-static void flush_dev_list(struct devpath *startpath)
-{
- struct devpath *nextpath;
-
- while (startpath) {
- nextpath = startpath->next;
- free(startpath);
- startpath = nextpath;
- }
-
- return;
-}
-
-/* free all nodes associated with one devlist */
-static void flush_dev_cache(struct devlisthead *devlisthead)
-{
- struct devnode *nextnode, *startnode = devlisthead->devnode;
-
- while (startnode) {
- nextnode = startnode->next;
- flush_dev_list(startnode->devpath);
- free(startnode);
- startnode = nextnode;
- }
-
- return;
-}
-
-/** list object allocation helpers **/
-
-/* our only certain keys in the list are maj and min
- * this function append a devnode obj to devlisthead
- * and set maj and min
- */
-
-static struct devnode *alloc_list_obj(struct devlisthead *devlisthead, int maj,
- int min)
-{
- struct devnode *nextnode;
-
- nextnode = malloc(sizeof(struct devnode));
- if (!nextnode)
- return 0;
-
- memset(nextnode, 0, sizeof(struct devnode));
-
- if (!devlisthead->devnode)
- devlisthead->devnode = nextnode;
- else
- devlisthead->tail->next = nextnode;
-
- devlisthead->tail = nextnode;
-
- nextnode->maj = maj;
- nextnode->min = min;
-
- return nextnode;
-}
-
-/* really annoying but we have no way to know upfront how
- * many paths are linked to a certain maj/min combo.
- * Once we find a device, we know maj/min and this new path.
- * add_path_obj will add the given path to the devnode
- */
-static int add_path_obj(struct devnode *startnode, const char *path)
-{
- struct devpath *nextpath, *startpath;
-
- nextpath = malloc(sizeof(struct devpath));
- if (!nextpath)
- return 0;
-
- memset(nextpath, 0, sizeof(struct devpath));
-
- if (!startnode->devpath) {
- startnode->devpath = startpath = nextpath;
- } else {
- startpath = startnode->devpath;
- while (startpath->next)
- startpath = startpath->next;
-
- /* always append what we find */
- startpath->next = nextpath;
- startpath = nextpath;
- }
-
- strncpy(startpath->path, path, MAXPATHLEN - 1);
-
- return 1;
-}
-
-/* lsdev needs to add blocks in 2 conditions: if we have a real block device
- * or if have a symlink to a block device.
- * this function simply avoid duplicate code around.
- */
-static int add_lsdev_block(struct devlisthead *devlisthead, struct stat *sb,
- const char *path)
-{
- int maj, min;
- struct devnode *startnode;
-
- maj = major(sb->st_rdev);
- min = minor(sb->st_rdev);
-
- startnode = find_dev_by_majmin(devlisthead->devnode, maj, min);
- if (!startnode) {
- startnode = alloc_list_obj(devlisthead, maj, min);
- if (!startnode)
- return 0;
- }
-
- if (!add_path_obj(startnode, path))
- return 0;
-
- return 1;
-}
-
-/* check if it is a device or a symlink to a device */
-static int dev_is_block(struct stat *sb, char *path)
-{
- if (S_ISBLK(sb->st_mode))
- return 1;
-
- if (S_ISLNK(sb->st_mode))
- if (!stat(path, sb))
- if (S_ISBLK(sb->st_mode))
- return 1;
-
- return 0;
-}
-
-/* lsdev does nothing more than ls -lR /dev
- * dives into dirs (skips hidden directories)
- * add block devices
- * parse symlinks
- *
- * ret:
- * 1 on success
- * -1 for generic errors
- * -2 -ENOMEM
- */
-static int lsdev(struct devlisthead *devlisthead, const char *path)
-{
- int i, n, err = 0;
- struct dirent **namelist;
- struct stat sb;
- char newpath[MAXPATHLEN];
-
- i = scandir(path, &namelist, 0, alphasort);
- if (i < 0)
- return -1;
-
- for (n = 0; n < i; n++) {
- if (namelist[n]->d_name[0] != '.') {
- snprintf(newpath, sizeof(newpath), "%s/%s", path,
- namelist[n]->d_name);
-
- if (!lstat(newpath, &sb)) {
- if (S_ISDIR(sb.st_mode))
- err = lsdev(devlisthead, newpath);
- if (err < 0)
- return err;
-
- if (dev_is_block(&sb, newpath))
- if (!add_lsdev_block
- (devlisthead, &sb, newpath))
- return -2;
- }
- }
- free(namelist[n]);
- }
- free(namelist);
- return 1;
-}
-
-/*
- * scan /proc/partitions and adds info into the list.
- * It's able to add nodes if those are not found in sysfs.
- *
- * ret:
- * 0 if we can't scan
- * -2 -ENOMEM
- * 1 if everything is ok
- */
-
-static int scanprocpart(struct devlisthead *devlisthead)
-{
- char line[4096];
- FILE *fp;
- int minor, major;
- unsigned long long blkcnt;
- char device[128];
- struct devnode *startnode;
-
- fp = fopen("/proc/partitions", "r");
- if (!fp)
- return 0;
-
- while (fgets(line, sizeof(line), fp) != NULL) {
-
- if (strlen(line) > 128 + (22))
- continue;
-
- if (sscanf(line, "%4d %4d %10llu %s",
- &major, &minor, &blkcnt, device) < 4)
- continue;
-
- /* careful here.. if there is no device, we are scanning the
- * first two lines that are not useful to us
- */
- if (!strlen(device))
- continue;
-
- startnode =
- find_dev_by_majmin(devlisthead->devnode, major, minor);
- if (!startnode) {
- startnode = alloc_list_obj(devlisthead, major, minor);
- if (!startnode) {
- fclose(fp);
- return -2;
- }
- }
-
- startnode->procpart = 1;
- strncpy(startnode->procname, device, sizeof(startnode->procname) - 1);
- }
-
- fclose(fp);
- return 1;
-}
-
-/* scan /proc/mdstat and adds info to the list. At this point
- * all the devices _must_ be already in the list. We don't add anymore
- * since raids can only be assembled out of existing devices
- *
- * ret:
- * 1 if we could scan
- * 0 otherwise
- */
-static int scanmdstat(struct devlisthead *devlisthead)
-{
- char line[4096];
- FILE *fp;
- char device[16];
- char separator[4];
- char status[16];
- char personality[16];
- char firstdevice[16];
- char devices[4096];
- char *tmp, *next;
- struct devnode *startnode = NULL;
-
- fp = fopen("/proc/mdstat", "r");
- if (!fp)
- return 0;
-
- while (fgets(line, sizeof(line), fp) != NULL) {
-
- /* i like things to be absolutely clean */
- memset(device, 0, sizeof(device));
- memset(separator, 0, sizeof(separator));
- memset(status, 0, sizeof(status));
- memset(personality, 0, sizeof(personality));
- memset(firstdevice, 0, sizeof(firstdevice));
- memset(devices, 0, sizeof(devices));
-
- if (strlen(line) >= sizeof(line))
- continue;
-
- /* we only parse stuff that starts with ^md
- * that's supposed to point to raid */
- if (!(line[0] == 'm' && line[1] == 'd'))
- continue;
-
- if (sscanf(line, "%s %s %s %s %s",
- device, separator, status, personality, firstdevice) < 5)
- continue;
-
- /* scan only raids that are active */
- if (strcmp(status, "active"))
- continue;
-
- /* try to find *mdX and set the device as real raid.
- * if we don't find the device we don't try to set the slaves */
- startnode = find_dev_by_path(devlisthead->devnode, device, 1);
- if (!startnode)
- continue;
-
- startnode->md = 1;
-
- /* trunkate the string from sdaX[Y] to sdaX and
- * copy the whole device string over */
- tmp = strstr(firstdevice, "[");
- if (!tmp)
- continue;
- memset(tmp, 0, 1);
-
- tmp = strstr(line, firstdevice);
- if (!tmp)
- continue;
- strncpy(devices, tmp, sizeof(devices) - 1);
-
- /* if we don't find any slave (for whatever reason)
- * keep going */
- if (!strlen(devices))
- continue;
-
- tmp = devices;
- while ((tmp) && ((next = strstr(tmp, " ")) || strlen(tmp))) {
- char *tmp2;
-
- tmp2 = strstr(tmp, "[");
- if (tmp2)
- memset(tmp2, 0, 1);
-
- startnode =
- find_dev_by_path(devlisthead->devnode, tmp, 1);
- if (startnode)
- startnode->md = 2;
-
- tmp = next;
-
- if (tmp)
- tmp++;
-
- }
- }
-
- fclose(fp);
- return 1;
-}
-
-/* scanmapper parses /proc/devices to identify what maj are associated
- * with device-mapper
- *
- * ret:
- * can't fail for now
- */
-static int scanmapper(struct devlisthead *devlisthead)
-{
- struct devnode *startnode;
- FILE *fp;
- char line[4096];
- char major[4];
- char device[64];
- int maj, start = 0;
-
- fp = fopen("/proc/devices", "r");
- if (!fp)
- return 0;
-
- while (fgets(line, sizeof(line), fp) != NULL) {
- memset(major, 0, sizeof(major));
- memset(device, 0, sizeof(device));
-
- if (strlen(line) > sizeof(line))
- continue;
-
- if (!strncmp(line, "Block devices:", 13)) {
- start = 1;
- continue;
- }
-
- if (!start)
- continue;
-
- if (sscanf(line, "%s %s", major, device) < 2)
- continue;
-
- if (!strncmp(device, "device-mapper", 13)) {
- maj = atoi(major);
- startnode = devlisthead->devnode;
-
- while (startnode) {
- if (startnode->maj == maj)
- startnode->mapper = 1;
-
- startnode = startnode->next;
- }
-
- }
-
- }
-
- fclose(fp);
- return 1;
-}
-
-/* scan through the list and execute the custom filter for each entry */
-static void run_filter(struct devlisthead *devlisthead,
- devfilter filter, void *filter_args)
-{
- struct devnode *startnode = devlisthead->devnode;
-
- while (startnode) {
- filter(startnode, filter_args);
- startnode = startnode->next;
- }
- return;
-}
-
-/** sysfs helper functions **/
-
-/* /sys/block/sda/dev or /sys/block/sda1/dev exists
- * the device is real and dev contains maj/min info.
- *
- * ret:
- * 1 on success and set maj/min
- * 0 if no file is found
- * -1 if we could not open the file
- */
-static int sysfs_is_dev(char *path, int *maj, int *min)
-{
- char newpath[MAXPATHLEN];
- struct stat sb;
- FILE *f;
- snprintf(newpath, sizeof(newpath), "%s/dev", path);
- if (!lstat(newpath, &sb)) {
- f = fopen(newpath, "r");
- if (f) {
- int err;
-
- err = fscanf(f, "%d:%d", maj, min);
- fclose(f);
- if ((err == EOF) || (err != 2))
- return -1;
-
- return 1;
- } else
- return -1;
- }
- return 0;
-}
-
-/* /sys/block/sda/removable tells us if a device can be ejected
- * from the system or not. This is useful for USB pendrive that are
- * both removable and disks.
- *
- * ret:
- * 1 if is removable
- * 0 if not
- * -1 if we couldn't find the file.
- */
-static int sysfs_is_removable(char *path)
-{
- char newpath[MAXPATHLEN];
- struct stat sb;
- int i = -1;
- FILE *f;
- snprintf(newpath, sizeof(newpath), "%s/removable", path);
- if (!lstat(newpath, &sb)) {
- f = fopen(newpath, "r");
- if (f) {
- int err;
-
- err = fscanf(f, "%d\n", &i);
- fclose(f);
- if ((err == EOF) || (err != 1))
- i = -1;
- }
- }
- return i;
-}
-
-/* we use this function to scan /sys/block/sda{,1}/{holders,slaves}
- * to know in what position of the foodchain this device is.
- * NOTE: a device can have both holders and slaves at the same time!
- * (for example an lvm volume on top of a raid device made of N real disks
- *
- * ret:
- * always return the amount of entries in the dir if successful
- * or any return value from scandir.
- */
-static int sysfs_has_subdirs_entries(char *path, const char *subdir)
-{
- char newpath[MAXPATHLEN];
- struct dirent **namelist;
- struct stat sb;
- int n, i, count = 0;
-
- snprintf(newpath, sizeof(newpath), "%s/%s", path, subdir);
- if (!lstat(newpath, &sb)) {
- if (S_ISDIR(sb.st_mode)) {
- i = scandir(newpath, &namelist, 0, alphasort);
- if (i < 0)
- return i;
- for (n = 0; n < i; n++) {
- if (namelist[n]->d_name[0] != '.')
- count++;
- free(namelist[n]);
- }
- free(namelist);
- }
- }
- return count;
-}
-
-/* this is the best approach so far to make sure a block device
- * is a disk and distinguish it from a cdrom or tape or etc.
- * What we know for sure is that a type 0 is a disk.
- * From an old piece code 0xe is an IDE disk and comes from media.
- * NOTE: we scan also for ../ that while it seems stupid, it will
- * allow to easily mark partitions as real disks.
- * (see for example /sys/block/sda/device/type and
- * /sys/block/sda1/../device/type)
- * TODO: there might be more cases to evaluate.
- *
- * ret:
- * -2 we were not able to open the file
- * -1 no path found
- * 0 we found the path but we have 0 clue on what it is
- * 1 is a disk
- */
-static int sysfs_is_disk(char *path)
-{
- char newpath[MAXPATHLEN];
- struct stat sb;
- int i = -1;
- FILE *f;
-
- snprintf(newpath, sizeof(newpath), "%s/device/type", path);
- if (!lstat(newpath, &sb))
- goto found;
-
- snprintf(newpath, sizeof(newpath), "%s/../device/type", path);
- if (!lstat(newpath, &sb))
- goto found;
-
- snprintf(newpath, sizeof(newpath), "%s/device/media", path);
- if (!lstat(newpath, &sb))
- goto found;
-
- snprintf(newpath, sizeof(newpath), "%s/../device/media", path);
- if (!lstat(newpath, &sb))
- goto found;
-
- snprintf(newpath, sizeof(newpath), "%s/device/devtype", path);
- if (!lstat(newpath, &sb))
- return 1;
-
- snprintf(newpath, sizeof(newpath), "%s/../device/devtype", path);
- if (!lstat(newpath, &sb))
- return 1;
-
- return -1;
-
- found:
- f = fopen(newpath, "r");
- if (f) {
- int err;
-
- err = fscanf(f, "%d\n", &i);
- fclose(f);
-
- if ((err == EOF) || (err != 1))
- return 0;
-
- switch (i) {
- case 0x0: /* scsi type_disk */
- case 0xe: /* found on ide disks from old kernels.. */
- i = 1;
- break;
- default:
- i = 0; /* by default we have no clue */
- break;
- }
- } else
- i = -2;
-
- return i;
-}
-
-/* recursive function that will scan and dive into /sys/block
- * looking for devices and scanning for attributes.
- *
- * ret:
- * 1 on success
- * -1 on generic error
- * -2 -ENOMEM
- */
-static int scansysfs(struct devlisthead *devlisthead, const char *path, int level, int parent_holder)
-{
- struct devnode *startnode;
- int i, n, maj = -1, min = -1, has_holder;
- struct dirent **namelist;
- struct stat sb;
- char newpath[MAXPATHLEN];
-
- i = scandir(path, &namelist, 0, alphasort);
- if (i < 0)
- return -1;
-
- for (n = 0; n < i; n++) {
- if (namelist[n]->d_name[0] != '.') {
- snprintf(newpath, sizeof(newpath),
- "%s/%s", path, namelist[n]->d_name);
-
- if (!lstat(newpath, &sb) && level)
- if (S_ISLNK(sb.st_mode))
- continue;
-
- has_holder = parent_holder;
-
- if (sysfs_is_dev(newpath, &maj, &min) > 0) {
- startnode =
- alloc_list_obj(devlisthead, maj,
- min);
- if (!startnode)
- return -2;
-
- startnode->sysfsattrs.sysfs = 1;
- startnode->sysfsattrs.removable =
- sysfs_is_removable(newpath);
-
- if (!parent_holder)
- has_holder =
- sysfs_has_subdirs_entries(newpath,
- "holders");
-
- startnode->sysfsattrs.holders = has_holder;
-
- startnode->sysfsattrs.slaves =
- sysfs_has_subdirs_entries(newpath,
- "slaves");
- startnode->sysfsattrs.disk =
- sysfs_is_disk(newpath);
- }
-
- if (!stat(newpath, &sb) && !level)
- if (S_ISDIR(sb.st_mode))
- if (scansysfs(devlisthead, newpath, 1, has_holder) < 0)
- return -1;
-
- if (!lstat(newpath, &sb))
- if (S_ISDIR(sb.st_mode))
- if (scansysfs(devlisthead, newpath, 1, has_holder) < 0)
- return -1;
-
- }
- free(namelist[n]);
- }
-
- free(namelist);
- return 1;
-}
-
-/*
- * devlisthead can be null if you are at init time. pass the old one if you are
- * updating or scanning..
- *
- * timeout is used only at init time to set the cache timeout value if default
- * value is not good enough. We might extend its meaning at somepoint.
- * Anything <= 0 means that the cache does not expire.
- */
-
-struct devlisthead *scan_for_dev(struct devlisthead *devlisthead,
- time_t timeout,
- devfilter filter, void *filter_args)
-{
- int res;
- time_t current;
-
- time(¤t);
-
- if (devlisthead) {
- if ((current - devlisthead->cache_timestamp) <
- devlisthead->cache_timeout) {
- return devlisthead;
- }
- } else {
- devlisthead = malloc(sizeof(struct devlisthead));
- if (!devlisthead)
- return NULL;
- memset(devlisthead, 0, sizeof(struct devlisthead));
- if (timeout)
- devlisthead->cache_timeout = timeout;
- else
- devlisthead->cache_timeout = DEVCACHETIMEOUT;
- }
-
- flush_dev_cache(devlisthead);
- devlisthead->cache_timestamp = current;
-
- /* it's important we check those 3 errors and abort in case
- * as it means that we are running out of mem,
- */
- devlisthead->sysfs = res = scansysfs(devlisthead, SYSBLOCKPATH, 0, 0);
- if (res < -1)
- goto emergencyout;
-
- devlisthead->procpart = res = scanprocpart(devlisthead);
- if (res < -1)
- goto emergencyout;
-
- devlisthead->lsdev = res = lsdev(devlisthead, DEVPATH);
- if (res < -1)
- goto emergencyout;
-
- /* from now on we don't alloc mem ourselves but only add info */
- devlisthead->mdstat = scanmdstat(devlisthead);
- devlisthead->mapper = scanmapper(devlisthead);
- if (filter)
- run_filter(devlisthead, filter, filter_args);
-
- return devlisthead;
-
- emergencyout:
- free_dev_list(devlisthead);
- return 0;
-}
-
-/* free everything we used so far */
-
-void free_dev_list(struct devlisthead *devlisthead)
-{
- if (devlisthead) {
- flush_dev_cache(devlisthead);
- free(devlisthead);
- }
- return;
-}
diff --git a/cman/qdisk/scandisk.h b/cman/qdisk/scandisk.h
deleted file mode 100644
index 031de26..0000000
--- a/cman/qdisk/scandisk.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef __SCANDISK_H__
-#define __SCANDISK_H__
-
-#ifndef DEVPATH
-#define DEVPATH "/dev"
-#endif
-
-#ifndef SYSFSPATH
-#define SYSFSPATH "/sys"
-#endif
-
-#ifndef SYSBLOCKPATH
-#define SYSBLOCKPATH SYSFSPATH "/block"
-#endif
-
-#ifndef DEVCACHETIMEOUT
-#define DEVCACHETIMEOUT 30 /* expressed in seconds */
-#endif
-
-/* each entry can be (generally):
- * > 0 on success or good hit
- * 0 on success with no hit
- * < 0 on error
- */
-
-struct sysfsattrs { /* usual 0 | 1 game */
- int sysfs; /* did we find an entry in sysfs at all? */
- int slaves; /* device has slaves */
- int holders; /* device has holders */
- int removable; /* device is removable */
- int disk; /* device is a disk */
-};
-
-/* this structure is required because we don't know upfront how many
- * entries for a certain maj/min will be found in /dev, and so we need
- * to alloc them dynamically.
- */
-struct devpath {
- struct devpath *next;
- char path[MAXPATHLEN];
-};
-
-/* this structure holds all the data for each maj/min found in the system
- * that is a block device
- */
-struct devnode {
- struct devnode *next;
- struct devpath *devpath; /* point to the first path entry */
- int maj; /* device major */
- int min; /* device minor */
- struct sysfsattrs sysfsattrs; /* like the others.. scanning /sys */
- int procpart; /* 0 if the device is not in proc/part or 1 on success. <0 on error */
- char procname[MAXPATHLEN]; /* non-NULL if we find a maj/min match */
- int md; /* 0 nothing to do with raid, 1 is raid,
- * 2 is raid slave - data from /proc/mdstat */
- int mapper; /* 0 nothing, 1 we believe it's a devmap dev */
- void *filter; /* your filter output.. whatever it is */
-};
-
-/* this is what you get after a scan... if you are lucky */
-/* each entry can be 0 if we can't scan or < 0 if there are errors */
-
-struct devlisthead {
- struct devnode *devnode; /* points to the first entry */
- struct devnode *tail; /* last entry (for fast append) */
- time_t cache_timestamp; /* this cache timestamp */
- int cache_timeout; /* for how long this cache is valid */
- int sysfs; /* set to 1 if we were able to scan
- * /sys */
- int procpart; /* set to 1 if we were able to scan
- * /proc/partitions */
- int lsdev; /* set to 1 if we were able to ls /dev */
- int mdstat; /* set to 1 if we were able to scan
- * /proc/mdstat */
- int mapper; /* set to 1 if we were able to run
- * something against mapper */
-};
-
-typedef void (*devfilter) (struct devnode * cur, void *arg);
-
-struct devlisthead *scan_for_dev(struct devlisthead *devlisthead,
- time_t timeout,
- devfilter filter, void *filter_args);
-void free_dev_list(struct devlisthead *devlisthead);
-
-#endif /* __SCANDISK_H__ */
diff --git a/cman/qdisk/score.c b/cman/qdisk/score.c
deleted file mode 100644
index 653fdf3..0000000
--- a/cman/qdisk/score.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/**
- @file Quorum daemon scoring functions + thread.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <string.h>
-#include <ccs.h>
-#include <liblogthread.h>
-#include <sched.h>
-#include <sys/mman.h>
-#include "disk.h"
-#include "score.h"
-
-static pthread_mutex_t sc_lock = PTHREAD_MUTEX_INITIALIZER;
-static int _score = 0, _maxscore = 0, _score_thread_running = 0;
-static pthread_t score_thread = (pthread_t)0;
-extern void set_priority(int, int);
-
-struct h_arg {
- struct h_data *h;
- int sched_queue;
- int sched_prio;
- int count;
-};
-
-/*
- XXX Messy, but works for now...
- */
-static void
-nullify(void)
-{
- int fd[3];
-
- close(0);
- close(1);
- close(2);
-
- fd[0] = open("/dev/null", O_RDONLY);
- if (fd[0] != 0)
- dup2(fd[0], 0);
- fd[1] = open("/dev/null", O_WRONLY);
- if (fd[1] != 1)
- dup2(fd[1], 1);
- fd[2] = open("/dev/null", O_WRONLY);
- if (fd[2] != 2)
- dup2(fd[2], 2);
-}
-
-
-/**
- Set all signal handlers to default for exec of a script.
- ONLY do this after a fork().
- */
-static void
-restore_signals(void)
-{
- sigset_t set;
- int x;
-
- for (x = 1; x < _NSIG; x++)
- signal(x, SIG_DFL);
-
- sigfillset(&set);
- sigprocmask(SIG_UNBLOCK, &set, NULL);
-}
-
-
-/**
- Spin off a user-defined heuristic
- */
-static int
-fork_heuristic(struct h_data *h, struct timespec *now)
-{
- int pid;
- char *argv[4];
-
- if (h->childpid) {
- errno = EINPROGRESS;
- return -1;
- }
-
- if (now->tv_sec < h->nextrun.tv_sec ||
- ((now->tv_sec == h->nextrun.tv_sec) &&
- (now->tv_nsec < h->nextrun.tv_nsec)))
- return 0;
-
- h->nextrun.tv_sec = now->tv_sec + h->interval;
- h->nextrun.tv_nsec = now->tv_nsec;
-
- h->failtime.tv_sec = now->tv_sec + h->maxtime;
- h->failtime.tv_nsec = now->tv_nsec;
-
- pid = fork();
- if (pid < 0)
- return -1;
-
- if (pid) {
- h->childpid = pid;
- return 0;
- }
-
- /*
- * always use SCHED_OTHER for the child processes
- * nice -1 is fine; but we don't know what the child process
- * might do, so leaving it (potentially) in SCHED_RR or SCHED_FIFO
- * is out of the question
- *
- * XXX if you set SCHED_OTHER in the conf file and nice 20, the below
- * will make the heuristics a higher prio than qdiskd. This should be
- * fine in practice, because running qdiskd at nice 20 will cause all
- * sorts of problems on a busy system.
- */
- set_priority(SCHED_OTHER, -1);
- munlockall();
- restore_signals();
-
- argv[0] = strdup("/bin/sh");
- argv[1] = strdup("-c");
- argv[2] = h->program;
- argv[3] = NULL;
-
- nullify();
-
- execv("/bin/sh", argv);
-
- free(argv[0]);
- free(argv[1]);
-
- logt_print(LOG_ERR, "Execv failed\n");
- return 0;
-}
-
-
-/**
- Total our current score
- */
-static void
-total_score(struct h_data *h, int max, int *score, int *maxscore)
-{
- int x;
-
- *score = 0;
- *maxscore = 0;
-
- /* Allow operation w/o any heuristics */
- if (!max) {
- *score = *maxscore = 1;
- return;
- }
-
- for (x = 0; x < max; x++) {
- *maxscore += h[x].score;
- if (h[x].available)
- *score += h[x].score;
- }
-}
-
-
-/**
- Check for response from a user-defined heuristic / script
- */
-static int
-check_heuristic(struct h_data *h, int block, struct timespec *now)
-{
- int ret;
- int status;
-
- if (h->childpid == 0)
- /* No child to check */
- return 0;
-
- ret = waitpid(h->childpid, &status, block?0:WNOHANG);
- if (!block && ret == 0) {
- /* No children exited */
-
- /* no timeout */
- if (!h->maxtime)
- return 0;
-
- /* If we overran our timeout, the heuristic is dead */
- if (now->tv_sec > h->failtime.tv_sec ||
- (now->tv_sec == h->failtime.tv_sec &&
- now->tv_nsec > h->failtime.tv_nsec)) {
- h->misses = h->tko;
- h->failed = ETIMEDOUT;
- if (h->available) {
- logt_print(LOG_INFO, "Heuristic: '%s' DOWN - "
- "Exceeded timeout of %d seconds\n",
- h->program, h->maxtime);
- h->available = 0;
- }
- }
-
- return 0;
- }
-
- h->childpid = 0;
- if (ret < 0 && errno == ECHILD)
- /* wrong child? */
- goto miss;
-
- /* Timed out previously; this run must be ignored. */
- if (h->failed) {
- h->failed = 0;
- goto miss;
- }
- if (!WIFEXITED(status)) {
- ret = 0;
- goto miss;
- }
- if (WEXITSTATUS(status) != 0) {
- logt_print(LOG_DEBUG, "Heuristic: sh returned %d for '%s'\n",
- WEXITSTATUS(status), h->program);
- ret = 0;
- goto miss;
- }
-
- /* Returned 0 and was not killed */
- if (!h->available) {
- h->available = 1;
- logt_print(LOG_INFO, "Heuristic: '%s' UP\n", h->program);
- }
- h->misses = 0;
- return 0;
-
-miss:
- if (h->available) {
- h->misses++;
- if (h->misses >= h->tko) {
- logt_print(LOG_INFO,
- "Heuristic: '%s' DOWN (%d/%d)\n",
- h->program, h->misses, h->tko);
- h->available = 0;
- } else {
- logt_print(LOG_DEBUG,
- "Heuristic: '%s' missed (%d/%d)\n",
- h->program, h->misses, h->tko);
- }
- }
-
- return ret;
-}
-
-
-/**
- Kick off all available heuristics
- */
-static int
-fork_heuristics(struct h_data *h, int max)
-{
- struct timespec now;
- int x;
-
- clock_gettime(CLOCK_MONOTONIC, &now);
- for (x = 0; x < max; x++)
- fork_heuristic(&h[x], &now);
- return 0;
-}
-
-
-/**
- Check all available heuristics
- */
-static int
-check_heuristics(struct h_data *h, int max, int block)
-{
- struct timespec now;
- int x;
-
- clock_gettime(CLOCK_MONOTONIC, &now);
- for (x = 0; x < max; x++)
- check_heuristic(&h[x], block, &now);
- return 0;
-}
-
-
-/*
- * absmax should be qdiskd (interval * (tko-1))
- */
-static void
-auto_heuristic_timing(int *interval, int *tko, int absmax)
-{
- if (!interval || ! tko)
- return;
-
- if (absmax < 3)
- return;
-
- if (absmax <= 4) {
- *interval = 1;
- } else if (absmax <= 22) {
- *interval = 2;
- } else if (absmax <= 39) {
- *interval = 3;
- } else if (absmax <= 50) {
- *interval = 4;
- } else {
- *interval = 5;
- }
-
- *tko = absmax / (*interval);
-}
-
-
-/**
- Read configuration data from CCS into the array provided
- */
-int
-configure_heuristics(int ccsfd, struct h_data *h, int max, int maxtime)
-{
- int x = 0;
- char *val;
- char query[128];
-
- if (!h || !max)
- return -1;
-
- do {
- h[x].program = NULL;
- h[x].available = 0;
- h[x].misses = 0;
- auto_heuristic_timing(&h[x].interval, &h[x].tko, maxtime);
- h[x].maxtime = maxtime;
- h[x].score = 1;
- h[x].childpid = 0;
- h[x].nextrun.tv_sec = 0;
- h[x].nextrun.tv_nsec = 0;
- h[x].failtime.tv_sec = 0;
- h[x].failtime.tv_nsec = 0;
-
- /* Get program */
- snprintf(query, sizeof(query),
- "/cluster/quorumd/heuristic[%d]/@program", x+1);
- if (ccs_get(ccsfd, query, &val) != 0)
- /* No more */
- break;
- h[x].program = val;
-
- /* Get score */
- snprintf(query, sizeof(query),
- "/cluster/quorumd/heuristic[%d]/@score", x+1);
- if (ccs_get(ccsfd, query, &val) == 0) {
- h[x].score = atoi(val);
- free(val);
- if (h[x].score <= 0)
- h[x].score = 1;
- }
-
- /* Get query interval */
- snprintf(query, sizeof(query),
- "/cluster/quorumd/heuristic[%d]/@interval", x+1);
- if (ccs_get(ccsfd, query, &val) == 0) {
- h[x].interval = atoi(val);
- free(val);
- if (h[x].interval <= 0)
- h[x].interval = 2;
- }
-
- /* Get tko for this heuristic */
- snprintf(query, sizeof(query),
- "/cluster/quorumd/heuristic[%d]/@tko", x+1);
- if (ccs_get(ccsfd, query, &val) == 0) {
- h[x].tko= atoi(val);
- free(val);
- if (h[x].tko <= 0)
- h[x].tko = 1;
- }
-
- logt_print(LOG_DEBUG,
- "Heuristic: '%s' score=%d interval=%d tko=%d\n",
- h[x].program, h[x].score, h[x].interval, h[x].tko);
-
- } while (++x < max);
-
- logt_print(LOG_DEBUG, "%d heuristics loaded\n", x);
-
- return x;
-}
-
-
-/**
- Return the current score + maxscore to the caller
- */
-int
-get_my_score(int *score, int *maxscore)
-{
- pthread_mutex_lock(&sc_lock);
- *score = _score;
- *maxscore = _maxscore;
- pthread_mutex_unlock(&sc_lock);
-
- return 0;
-}
-
-
-/**
- Call this if no heuristics are set to run in master-wins mode
- */
-int
-fudge_scoring(void)
-{
- pthread_mutex_lock(&sc_lock);
- _score = _maxscore = 1;
- pthread_mutex_unlock(&sc_lock);
-
- return 0;
-}
-
-
-/**
- Loop for the scoring thread.
- */
-static void *
-score_thread_main(void *arg)
-{
- struct h_arg *args = (struct h_arg *)arg;
- int score, maxscore;
-
- set_priority(args->sched_queue, args->sched_prio);
-
- while (_score_thread_running) {
- fork_heuristics(args->h, args->count);
- check_heuristics(args->h, args->count, 0);
- total_score(args->h, args->count, &score, &maxscore);
-
- pthread_mutex_lock(&sc_lock);
- _score = score;
- _maxscore = maxscore;
- pthread_mutex_unlock(&sc_lock);
-
- if (_score_thread_running)
- sleep(1);
- }
-
- free(args->h);
- free(args);
- logt_print(LOG_INFO, "Score thread going away\n");
- return (NULL);
-}
-
-
-/**
- Start the score thread. h is copied into an argument which is
- passed in as the arg parameter in the score thread, so it is safe
- to pass in h if it was allocated on the stack.
- */
-int
-start_score_thread(qd_ctx *ctx, struct h_data *h, int count)
-{
- pthread_attr_t attrs;
- struct h_arg *args;
-
- if (!h || !count)
- return -1;
-
- args = malloc(sizeof(struct h_arg));
- if (!args)
- return -1;
-
- args->h = malloc(sizeof(struct h_data) * count);
- if (!args->h) {
- free(args);
- return -1;
- }
-
- memcpy(args->h, h, (sizeof(struct h_data) * count));
- args->count = count;
- args->sched_queue = ctx->qc_sched;
- args->sched_prio = ctx->qc_sched_prio;
-
- _score_thread_running = 1;
-
- pthread_attr_init(&attrs);
- pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED);
- pthread_create(&score_thread, &attrs, score_thread_main, args);
- pthread_attr_destroy(&attrs);
-
- if (score_thread)
- return 0;
- _score_thread_running = 0;
- return -1;
-}
diff --git a/cman/qdisk/score.h b/cman/qdisk/score.h
deleted file mode 100644
index beff31b..0000000
--- a/cman/qdisk/score.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- @file Quorum daemon scoring functions + thread header file
- */
-#ifndef _SCORE_H
-#define _SCORE_H
-
-#include <time.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-struct h_data {
- char * program;
- struct timespec nextrun;
- struct timespec failtime;
- int score;
- int available;
- int tko;
- int interval;
- int maxtime;
- int misses;
- int failed;
- pid_t childpid;
-};
-
-/*
- Grab score data from CCSD
- */
-int configure_heuristics(int ccsfd, struct h_data *hp, int max, int maxtime);
-
-/*
- Start the thread which runs the scoring applets
- */
-int start_score_thread(qd_ctx *ctx, struct h_data *h, int count);
-
-/*
- Get our score + maxscore
- */
-int get_my_score(int *score, int *maxscore);
-
-/*
- Set score + maxscore to 1. Call if no heuristics are present
- to enable master-wins mode
- */
-int fudge_scoring(void);
-
-
-#endif
diff --git a/cman/scripts/Makefile b/cman/scripts/Makefile
deleted file mode 100644
index f80f7e4..0000000
--- a/cman/scripts/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-SHAREDIRTEX=checkquorum
-SHAREDIRT=checkquorum.wdmd
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-all:
-
-clean: generalclean
diff --git a/cman/scripts/checkquorum b/cman/scripts/checkquorum
deleted file mode 100755
index 61934cd..0000000
--- a/cman/scripts/checkquorum
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/perl -w
-# Quorum detection watchdog script
-#
-# This script will return -2 if the node had quorum at one point
-# and then subsequently lost it
-#
-# Copyright 2011 Red Hat, Inc.
-
-# Amount of time in seconds to wait after quorum is lost to fail script
-$wait_time = 60;
-
-# Hard Reboot the system (doesn't cleanly shut down the system)
-$hardreboot = 0;
-
-# Location of temporary file to capture timeouts
-$timerfile = "/var/run/cluster/checkquorum-timer";
-
-# Enable debug messages (0 to disable, 1 to enable)
-$debugval = 0;
-
-# If command is called attempting to 'repair' we automatically fail
-if (($#ARGV != -1) && ($ARGV[0] eq "repair")) {
- debug ("Failing on repair\n");
- exit 1;
-}
-
-if (!quorum()) {
- if (has_quorum_already_been_formed()) {
- debug("Quorum has already existed, node can be rebooted!\n");
- if (-e $timerfile) {
- $tf = open (FILE, "$timerfile");
- $time = <FILE>;
- close (FILE);
- $timediff = time() - $time;
- if ($timediff >= $wait_time) {
- reboot()
- } else {
- $remaining = $wait_time - $timediff;
- debug("Time has not exceeded wait time ($remaining seconds remaining).\n");
- }
- } else {
- debug("Creating timer file...\n");
- $tf = open (FILE, ">$timerfile");
- print FILE time();
- close (FILE);
- }
- } else {
- debug("This is a new startup no reboot will occur.\n");
- `rm -f $timerfile`;
- }
-} else {
- debug("Quorum exists, no reboot should occur.\n");
- `rm -f $timerfile`;
-}
-
-sub has_quorum_already_been_formed {
- $oe = `corosync-objctl 2>&1 | grep -E "runtime.totem.pg.mrp.srp.operational_entered|Could not initialize objdb library|Cannot connect to quorum service" `;
- if ($oe =~ /^Could not/ || $oe =~ /^Cannot/) {
- debug("corosync is not running\n");
- exit 0;
- }
- $oe =~ s/.*=//;
- if ($oe > 1) {
- return 1;
- } else {
- return 0;
- }
-}
-
-sub quorum {
- $cq = `corosync-quorumtool -s 2>&1 | grep -E "Quorate:|Cannot connect to quorum service"`;
- if ($cq =~ /Cannot connect to quorum service/) {
- debug("corosync is not running\n");
- exit 0;
- }
- $cq =~ s/Quorate: *//;
- chomp ($cq);
- return 1 if ($cq eq "Yes");
- return 0;
-}
-
-sub reboot {
- debug("Reboot commencing...\n");
- `rm -f $timerfile`;
- if ($hardreboot == 1) {
- `echo 1 > /proc/sys/kernel/sysrq`;
- `echo b > /proc/sysrq-trigger`;
- }
- exit -2;
-}
-
-sub debug {
- $out = pop(@_);
- if ($debugval) {
- print $out;
- }
-}
diff --git a/cman/scripts/checkquorum.wdmd b/cman/scripts/checkquorum.wdmd
deleted file mode 100644
index 1d81ff6..0000000
--- a/cman/scripts/checkquorum.wdmd
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/bin/bash
-# Quorum detection watchdog script
-#
-# This script will return -2 if the node had quorum at one point
-# and then subsequently lost it
-#
-# Copyright 2012 Red Hat, Inc.
-
-# defaults
-
-# Amount of time in seconds to wait after quorum is lost to fail script
-waittime=60
-
-# action to take if quorum is missing for over > waittime
-# autodetect|hardreboot|crashdump|watchdog
-action=autodetect
-
-# Location of temporary file to capture timeouts
-timerfile="/var/run/cluster/checkquorum-timer"
-
-# rpm based distros
-[ -d /etc/sysconfig ] && \
- [ -f /etc/sysconfig/checkquorum ] && \
- . /etc/sysconfig/checkquorum
-
-# deb based distros
-[ ! -d /etc/sysconfig ] && \
- [ -f /etc/default/checkquorum ] && \
- . /etc/default/checkquorum
-
-has_quorum() {
- corosync-quorumtool -s 2>/dev/null | \
- grep ^Quorate: | \
- grep -q Yes$
-}
-
-had_quorum() {
- output="$(corosync-objctl 2>/dev/null | \
- grep runtime.totem.pg.mrp.srp.operational_entered | cut -d "=" -f 2)"
- [ -n "$output" ] && {
- [ "$output" -ge 1 ] && return 0
- return 1
- }
-}
-
-take_action() {
- case "$action" in
- watchdog)
- [ -n "$wdmd_action" ] && return 1
- ;;
- hardreboot)
- echo 1 > /proc/sys/kernel/sysrq
- echo b > /proc/sysrq-trigger
- ;;
- crashdump)
- echo 1 > /proc/sys/kernel/sysrq
- echo c > /proc/sysrq-trigger
- ;;
- autodetect)
- service kdump status > /dev/null 2>&1
- usekexec="$?"
- [ -n "$wdmd_action" ] && [ "$usekexec" != "0" ] && return 1
- echo 1 > /proc/sys/kernel/sysrq
- [ "$usekexec" = "0" ] && echo c > /proc/sysrq-trigger
- echo b > /proc/sysrq-trigger
- esac
-}
-
-# watchdog uses $1 = test or = repair
-# with no arguments we are called by wdmd
-[ -z "$1" ] && wdmd_action=yes
-
-# we don't support watchdog repair action
-[ "$1" = "repair" ] && exit 1
-
-service corosync status > /dev/null 2>&1
-ret=$?
-
-case "$ret" in
- 3) # corosync is not running (clean)
- rm -f "$timerfile"
- exit 0
- ;;
- 1) # corosync crashed or did exit abonormally (dirty - take action)
- logger -t checkquorum.wdmd "corosync crashed or exited abonarmally. Node will soon reboot"
- take_action
- ;;
- 0) # corosync is running (clean)
- # check quorum here
- has_quorum && {
- echo -e "oldtime=$(date +%s)" > "$timerfile"
- exit 0
- }
- . "$timerfile"
- newtime="$(date +%s)"
- delta=$((newtime - oldtime))
- logger -t checkquorum.wdmd "Node has lost quorum. Node will soon reboot"
- had_quorum && [ "$delta" -gt "$waittime" ] && {
- take_action
- }
- ;;
-esac
-
-exit $?
diff --git a/cman/tests/Makefile b/cman/tests/Makefile
deleted file mode 100644
index eb800c1..0000000
--- a/cman/tests/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-TARGETS= client libtest sysman sysmand
-
-all: depends ${TARGETS}
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-
-CFLAGS += -I${cmanincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${cmanlibdir} -lcman
-LDFLAGS += -L${libdir}
-
-depends:
- $(MAKE) -C ../lib all
-
-%: %.o
- $(CC) -o $@ $^ $(LDFLAGS)
-
-install:
-
-clean: generalclean
diff --git a/cman/tests/client.c b/cman/tests/client.c
deleted file mode 100644
index ff74816..0000000
--- a/cman/tests/client.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* test client */
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <sys/utsname.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "libcman.h"
-
-static cman_handle_t handle;
-static void get_members(void);
-
-static void event_callback(cman_handle_t handle, void *private, int reason, int arg)
-{
- get_members();
-}
-
-
-static void data_callback(cman_handle_t handle, void *private,
- char *buf, int len, uint8_t port, int nodeid)
-{
- printf("Received from node %d port %d: '%s'\n", nodeid, port, buf);
-}
-
-
-int main(int argc, char *argv[])
-{
-
- unsigned char port = 100;
- char message[256];
- struct utsname ubuf;
-
- if (argc >= 2)
- port = atoi(argv[1]);
-
- if (argc >= 3)
- strcpy(message, argv[2]);
-
- printf("Cluster port number is %d\n", port);
- uname(&ubuf);
- sprintf(message, "Hello from %s", ubuf.nodename);
-
- handle = cman_init(NULL);
- if (!handle)
- {
- perror("Can't connect to cman");
- return -1;
- }
-
-
- if (cman_start_recv_data(handle, data_callback, port))
- {
- perror("Can't bind cluster socket");
- return -1;
- }
- cman_start_notification(handle, event_callback);
-
- while (1)
- {
-
- if (cman_send_data(handle, message, strlen(message)+1,0, port, 0) < 0)
- {
- perror("write");
- cman_finish(handle);
- exit(-1);
- }
-
- while (1)
- {
- if (cman_dispatch(handle, CMAN_DISPATCH_ALL|CMAN_DISPATCH_BLOCKING) == -1)
- break;
- }
- }
- fprintf(stderr, "EOF: finished\n");
-}
-
-
-void get_members(void)
-{
- cman_node_t *nodes;
- int i;
- int num_nodes = cman_get_node_count(handle);
-
- if (num_nodes == -1)
- {
- perror("get nodes");
- }
- else
- {
- printf("There are %d nodes: \n", num_nodes);
-
- nodes = malloc(num_nodes * sizeof(cman_node_t));
- if ( (cman_get_nodes(handle, num_nodes, &num_nodes, nodes)))
- {
- for (i=0; i<num_nodes; i++)
- {
- printf("%s %d\n", nodes[i].cn_name, nodes[i].cn_nodeid);
- }
- }
- else
- {
- perror("get node details");
- }
- }
-}
diff --git a/cman/tests/libtest.c b/cman/tests/libtest.c
deleted file mode 100644
index 85c1ea8..0000000
--- a/cman/tests/libtest.c
+++ /dev/null
@@ -1,132 +0,0 @@
-#include <netinet/in.h>
-#include <inttypes.h>
-#include "libcman.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-
-static void cman_callback(cman_handle_t handle, void *private, int reason, int arg)
-{
- printf("callback called reason = %d, arg=%d\n", reason, arg);
-}
-
-static void confchg_callback(cman_handle_t handle, void *private,
- unsigned int *member_list, int member_list_entries,
- unsigned int *left_list, int left_list_entries,
- unsigned int *joined_list, int joined_list_entries)
-{
- int i;
- printf("Confchg callback\n");
- printf("member_list: %d entries:\n", member_list_entries);
- for (i=0; i<member_list_entries; i++)
- printf(" %d\n", member_list[i]);
- printf("left_list: %d entries:\n", left_list_entries);
- for (i=0; i<left_list_entries; i++)
- printf(" %d\n", left_list[i]);
- printf("joined_list: %d entries:\n", joined_list_entries);
- for (i=0; i<joined_list_entries; i++)
- printf(" %d\n", joined_list[i]);
-}
-
-static void print_node(cman_node_t *node)
-{
- printf(" node id %d\n", node->cn_nodeid);
- printf(" node member %d\n", node->cn_member);
- printf(" node name %s\n", node->cn_name);
- printf(" node incarn %d\n", node->cn_incarnation);
- printf("\n");
-}
-
-int main()
-{
- cman_handle_t h;
- int num;
- int retnodes;
- cman_node_t *nodes;
- cman_version_t ver;
- cman_cluster_t clinfo;
-
- h = cman_init(0);
- if (!h)
- {
- perror("cman_init failed");
- exit(1);
- }
-
- num = cman_get_node_count(h);
- if (num > 0)
- printf("cluster has %d nodes\n", num);
- else
- perror("node count");
-
- printf("cman is active: %d\n", cman_is_active(h));
- printf("cman is quorate: %d\n", cman_is_quorate(h));
- printf("cman is listening: %d\n", cman_is_listening(h, CMAN_NODEID_US, 1)); /* membership! */
- cman_get_version(h, &ver);
- printf("cman version %d.%d.%d (config %d)\n",
- ver.cv_minor,
- ver.cv_major,
- ver.cv_patch,
- ver.cv_config);
-
- if (!cman_get_cluster(h, &clinfo))
- {
- printf("Cluster '%s', number %d\n", clinfo.ci_name, clinfo.ci_number);
- }
- else
- perror("cluster info failed");
-
- nodes = malloc(num * sizeof(cman_node_t));
- if (!nodes)
- {
- perror("malloc");
- exit(1);
- }
-
- if (!cman_get_nodes(h, num, &retnodes, nodes))
- {
- int i;
- printf("Getting all nodes:\n");
- for (i=0; i<retnodes; i++)
- print_node(&nodes[i]);
- }
- else
- {
- perror("get_nodes failed");
- }
-
- // Need to clear this.
- // Who wrote this rubbish? oh, I did.
- nodes[0].cn_name[0] = '\0';
- if (!cman_get_node(h, CMAN_NODEID_US, &nodes[0]))
- {
- printf("Getting our info:\n");
- print_node(&nodes[0]);
- }
- else
- {
- perror("get_node failed");
- }
-
- if (cman_start_notification(h, cman_callback))
- {
- perror("start_notification");
- }
-
- if (cman_start_confchg(h, confchg_callback))
- {
- perror("start_confchg");
- }
-
-
- while (1) {
- int ret = cman_dispatch(h, CMAN_DISPATCH_BLOCKING | CMAN_DISPATCH_ALL);
- if (ret == -1) {
- perror("cman_dispatch");
- break;
- }
- }
- cman_finish(h);
-
- return 0;
-}
diff --git a/cman/tests/qwait.c b/cman/tests/qwait.c
deleted file mode 100644
index 5d6a3f7..0000000
--- a/cman/tests/qwait.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <sys/utsname.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "cnxman-socket.h"
-
-static int cluster_sock;
-
-static void signal_handler(int sig)
-{
-
- return;
-}
-
-
-int main(int argc, char *argv[])
-{
- struct sigaction sa;
- sigset_t ss;
-
- cluster_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT);
- if (cluster_sock == -1)
- {
- perror("Can't open cluster socket");
- return -1;
- }
- sa.sa_handler = signal_handler;
- sa.sa_mask = ss;
- sa.sa_flags = 0;
- sigaction(SIGUSR1, &sa, NULL);
-
- if (ioctl(cluster_sock, SIOCCLUSTER_NOTIFY, SIGUSR1) == -1)
- {
- perror("Can't set up cluster notification");
- close(cluster_sock);
- return -1;
- }
-
- while (!ioctl(cluster_sock, SIOCCLUSTER_ISQUORATE, 0))
- {
- pause();
- }
-
- close(cluster_sock);
-
- return 0;
-}
diff --git a/cman/tests/sysman.c b/cman/tests/sysman.c
deleted file mode 100644
index 99ba562..0000000
--- a/cman/tests/sysman.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* "sysman" client */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <sys/utsname.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#define LOCAL_SOCKNAME "/var/run/sysman"
-static int open_local_sock(void);
-
-int main(int argc, char *argv[])
-{
- char message[PIPE_BUF];
- int local_sock;
- int len;
-
- if (argc < 2)
- {
- printf("usage: sysman \"command\"\n");
- return 0;
- }
-
- local_sock = open_local_sock();
- if (local_sock < 0)
- exit(2);
-
- /* Send the command */
- write(local_sock, argv[1], strlen(argv[1])+1);
-
- /* Print the replies */
- while ( (len = read(local_sock, message, sizeof(message))) )
- {
- write(STDOUT_FILENO, message, len);
- }
- printf("\n");
- return 0;
-}
-
-
-static int open_local_sock(void)
-{
- int local_socket;
- struct sockaddr_un sockaddr;
-
- // Open local socket
- local_socket = socket(PF_UNIX, SOCK_STREAM, 0);
- if (local_socket < 0)
- {
- perror("Can't create local socket");
- return -1;
- }
-
- strcpy(sockaddr.sun_path, LOCAL_SOCKNAME);
- sockaddr.sun_family = AF_UNIX;
- if (connect(local_socket, (struct sockaddr *)&sockaddr, sizeof(sockaddr)))
- {
- fprintf(stderr, "sysmand is not running\n");
- close(local_socket);
- return -1;
- }
- return local_socket;
-}
-
diff --git a/cman/tests/sysmand.c b/cman/tests/sysmand.c
deleted file mode 100644
index 8391c06..0000000
--- a/cman/tests/sysmand.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/* "sysman" server
-
- Listens on a cluster port and executes commands.
-
- This is just a demonstration piece of code, not for production use
-
- *************************************
- *** IT IS A MASSIVE SECURITY HOLE ***
- *************************************
-
- Any command passed to it will be run as root!
-
-*/
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <sys/utsname.h>
-#include <sys/errno.h>
-#include <syslog.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <time.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "libcman.h"
-#define LOCAL_SOCKNAME "/var/run/sysman"
-#define CLUSTER_PORT_SYSMAN 12
-
-static cman_node_t *nodes = NULL;
-static int num_nodes;
-static cman_handle_t ch;
-static int expected_responses;
-
-/* Header for all commands sent to other sysmand servers */
-struct sysman_header
-{
- int fd; /* local FD to return output to. in network byte order */
- int ret; /* Return code of command */
- char cmd;
-#define SYSMAN_CMD_REQUEST 1
-#define SYSMAN_CMD_REPLY 2
-};
-
-/* One of these for each fd we are listening on
- some fields are specific to particular types.
-*/
-struct read_fd
-{
- int fd;
- enum {CLUSTER_SOCK, LOCAL_RENDEZVOUS, LOCAL_SOCK} type;
- int nodes_done;
- time_t start_time;
- struct read_fd *next;
-};
-/* Head of the fd list. Also contains
- the cluster_socket details */
-static struct read_fd read_fd_head;
-
-
-static void get_members(void);
-static int open_local_sock(void);
-static int exec_command(char *cmd, char *reply, int *len);
-static int name_from_nodeid(int nodeid, char *name);
-static void remove_sock(struct read_fd *deadfd);
-static struct read_fd *find_by_fd(int fd);
-static int nodes_listening(int);
-
-static void event_callback(cman_handle_t handle, void *private, int reason, int arg)
-{
- get_members();
-}
-
-static void data_callback(cman_handle_t handle, void *private,
- char *buf, int len, uint8_t port, int nodeid)
-{
- struct read_fd *replyfd = NULL;
- char reply[PIPE_BUF];
- char title[PIPE_BUF];
- char nodename[CMAN_MAX_NODENAME_LEN];
- struct sysman_header *header;
- int status;
- int title_len;
- struct sysman_header *inheader = (struct sysman_header *)buf;
-
- switch (inheader->cmd)
- {
- case SYSMAN_CMD_REQUEST:
-
- /* Execute command and capture stdout/stderr into 'reply'*/
- status = exec_command(buf+sizeof(struct sysman_header), reply+sizeof(struct sysman_header), &len);
-
- header = (struct sysman_header *)reply;
-
- /* Send reply */
- header->fd = inheader->fd; /* Already in the right format */
- header->cmd = SYSMAN_CMD_REPLY;
- header->ret = htonl(status);
-
- cman_send_data(ch, reply, len, 0, port, nodeid);
- break;
-
- case SYSMAN_CMD_REPLY:
- name_from_nodeid(nodeid, nodename);
- title_len = sprintf(title, "\nReply from %s:", nodename);
- if (inheader->ret != 0)
- title_len += sprintf(title+title_len, " (ret=%d)", ntohl(inheader->ret));
- strcat(title, "\n"); title_len++;
- write(ntohl(inheader->fd), title, title_len);
- write(ntohl(inheader->fd), buf+sizeof(struct sysman_header),
- len - sizeof(struct sysman_header));
-
- replyfd = find_by_fd(ntohl(inheader->fd));
- if (replyfd)
- {
- /* If we've done all nodes then close the client down */
- if (++replyfd->nodes_done == expected_responses)
- {
- close(replyfd->fd);
- remove_sock(replyfd);
- }
- }
- break;
-
- default:
- name_from_nodeid(nodeid, nodename);
- syslog(LOG_ERR, "Unknown sysman command received from %s: %d\n",
- nodename, inheader->cmd);
- break;
- }
-}
-
-int main(int argc, char *argv[])
-{
- unsigned char port = CLUSTER_PORT_SYSMAN;
- int local_sock;
- struct read_fd *newfd;
- struct utsname nodeinfo;
-
- ch = cman_init(NULL);
- if (!ch)
- {
- perror("Can't connect to cman");
- return -1;
- }
-
- uname(&nodeinfo);
-
- if (cman_start_recv_data(ch, data_callback, port))
- {
- perror("Can't bind cluster socket");
- return -1;
- }
-
- cman_start_notification(ch, event_callback);
-
- read_fd_head.fd = cman_get_fd(ch);
- read_fd_head.type = CLUSTER_SOCK;
-
- /* Preload cluster members list */
- get_members();
-
- /* Just a sensible default, we work out just how many
- responses we expect properly later */
- expected_responses = num_nodes;
-
- /* Open the Unix socket we listen for commands on */
- local_sock = open_local_sock();
- if (local_sock < 0)
- exit(2);
-
- newfd = malloc(sizeof(struct read_fd));
- if (!newfd)
- exit(2);
-
- newfd->fd = local_sock;
- newfd->type = LOCAL_RENDEZVOUS;
- newfd->next = NULL;
- read_fd_head.next = newfd;
-
- while (1)
- {
- fd_set in;
- struct read_fd *thisfd;
- struct timeval tv = {10,0};
-
- read_fd_head.fd = cman_get_fd(ch);
- FD_ZERO(&in);
- for (thisfd = &read_fd_head; thisfd != NULL; thisfd = thisfd->next)
- {
- FD_SET(thisfd->fd, &in);
- }
-
- if (select(FD_SETSIZE, &in, NULL, NULL, &tv) > 0)
- {
- struct read_fd *lastfd = NULL;
-
- for (thisfd = &read_fd_head; thisfd != NULL; thisfd = thisfd->next)
- {
- if (FD_ISSET(thisfd->fd, &in))
- {
- switch(thisfd->type)
- {
- /* Request or response from another cluster node */
- case CLUSTER_SOCK:
- if (cman_dispatch(ch, CMAN_DISPATCH_ONE) == -1)
- goto closedown;
- break;
-
- /* Someone connected to our local socket */
- case LOCAL_RENDEZVOUS:
- {
- struct sockaddr_un socka;
- struct read_fd *newfd;
- socklen_t sl = sizeof(socka);
- int client_fd = accept(local_sock, (struct sockaddr *)&socka, &sl);
-
- if (client_fd >= 0)
- {
- newfd = malloc(sizeof(struct read_fd));
- if (!newfd)
- {
- close(client_fd);
- break;
- }
- newfd->fd = client_fd;
- newfd->type = LOCAL_SOCK;
- newfd->next = thisfd->next;
- newfd->nodes_done = 0;
- newfd->start_time = time(NULL);
- thisfd->next = newfd;
- }
- }
- break;
-
- /* Data on a connected socket */
- case LOCAL_SOCK:
- {
- int len;
- char buffer[PIPE_BUF];
- len = read(thisfd->fd, buffer, sizeof(buffer));
-
- /* EOF on socket */
- if (len <= 0)
- {
- struct read_fd *free_fd;
-
- close(thisfd->fd);
- /* Remove it from the list safely */
- lastfd->next = thisfd->next;
- free_fd = thisfd;
- thisfd = lastfd;
- free(free_fd);
- }
- else
- {
- char cman_buffer[PIPE_BUF];
- struct sysman_header *header = (struct sysman_header *)cman_buffer;
-
- expected_responses = nodes_listening(thisfd->fd);
-
- header->fd = htonl(thisfd->fd);
- header->cmd = SYSMAN_CMD_REQUEST;
- memcpy(cman_buffer+sizeof(*header), buffer, len);
-
- if (!cman_send_data(ch, cman_buffer, sizeof(*header)+len, 0, port, 0))
- {
- perror("write");
- goto closedown;
- }
- }
- }
- break;
-
- } /* switch */
-
- }
- lastfd = thisfd;
- }
- }
- /* Check for timed-out connections */
- for (thisfd = &read_fd_head; thisfd != NULL; thisfd = thisfd->next)
- {
- if (thisfd->type == LOCAL_SOCK && (thisfd->start_time <= time(NULL)-10))
- {
- write(thisfd->fd,"Timed-out\n", 10);
- close(thisfd->fd);
- remove_sock(thisfd);
-
- /* Refresh members list in case a node has gone down
- or a remote sysmand has crashed */
- get_members();
- }
- }
- }
- closedown:
- cman_finish(ch);
- close(local_sock);
-
- return 0;
-}
-
-/* Get a list of members */
-static void get_members()
-{
- num_nodes = cman_get_node_count(ch);
- if (num_nodes == -1)
- {
- perror("get nodes");
- }
- else
- {
- if (nodes) free(nodes);
-
- nodes = malloc(num_nodes * sizeof(cman_node_t));
-
- if (cman_get_nodes(ch, num_nodes, &num_nodes, nodes))
- perror("Error getting node list");
- }
-}
-
-/* Convert a nodeid to a node name */
-static int name_from_nodeid(int nodeid, char *name)
-{
- int i;
-
- for (i=0; i<num_nodes; i++)
- {
- if (nodeid == nodes[i].cn_nodeid)
- {
- strcpy(name, nodes[i].cn_name);
- return 0;
- }
- }
- /* Who?? */
- strcpy(name, "Unknown");
- return -1;
-}
-
-/* Check which nodes are listening on the SYSMAN port */
-static int nodes_listening(int errfd)
-{
- int i;
- int num_listening = 0;
-
- for (i=0; i<num_nodes; i++)
- {
- int listening;
-
- listening = cman_is_listening(ch, nodes[i].cn_nodeid, CLUSTER_PORT_SYSMAN);
-
- if (listening > 0)
- {
- num_listening++;
- }
- else
- {
- if (listening == 0)
- {
- char errstring[1024];
- int len;
- len = snprintf(errstring, sizeof(errstring),
- "WARNING: node %s is not listening for SYSMAN requests\n",
- nodes[i].cn_name);
- write(errfd, errstring, len);
- }
- }
- }
- return num_listening;
-}
-
-static int open_local_sock()
-{
- int local_socket;
- struct sockaddr_un sockaddr;
-
- // Open local socket
- unlink(LOCAL_SOCKNAME);
- local_socket = socket(PF_UNIX, SOCK_STREAM, 0);
- if (local_socket < 0)
- {
- syslog(LOG_ERR, "Can't create local socket: %m");
- return -1;
- }
-
- strcpy(sockaddr.sun_path, LOCAL_SOCKNAME);
- sockaddr.sun_family = AF_UNIX;
- if (bind(local_socket, (struct sockaddr *)&sockaddr, sizeof(sockaddr)))
- {
- syslog(LOG_ERR, "can't bind local socket: %m");
- close(local_socket);
- return -1;
- }
- if (listen(local_socket, 1) != 0)
- {
- syslog(LOG_ERR, "listen local: %m");
- close(local_socket);
- return -1;
- }
- // Make sure only root can talk to us via the local socket.
- // Considering the rest of the security implications of
- // this code, this is simply pathetic!
- chmod(LOCAL_SOCKNAME, 0600);
-
- return local_socket;
-}
-
-static struct read_fd *find_by_fd(int fd)
-{
- struct read_fd *thisfd;
-
- for (thisfd = &read_fd_head; thisfd != NULL; thisfd = thisfd->next)
- if (fd == thisfd->fd) return thisfd;
-
- return NULL;
-}
-
-static void remove_sock(struct read_fd *deadfd)
-{
- struct read_fd *thisfd;
- struct read_fd *lastfd=NULL;
-
- for (thisfd = &read_fd_head; thisfd != NULL; thisfd = thisfd->next)
- {
- if (thisfd == deadfd)
- {
- lastfd->next = deadfd->next;
- free(deadfd);
- }
- lastfd = thisfd;
- }
-}
-
-static int exec_command(char *cmd, char *reply, int *len)
-{
- FILE *pipe;
- int readlen;
- int avail = PIPE_BUF-sizeof(struct sysman_header)-1;
- char realcmd[strlen(cmd)+25];
-
- /* Send stderr back to the caller, and make stdin /dev/null */
- snprintf(realcmd, sizeof(realcmd), "%s </dev/null 2>&1", cmd);
-
- *len = 0;
- pipe = popen(realcmd, "r");
-
- /* Fill the buffer as full as possible */
- do
- {
- readlen = fread(reply + *len, 1, avail, pipe);
- if (readlen > 0)
- {
- *len += readlen;
- avail -= readlen;
- }
- }
- while (avail>0 && readlen > 0);
-
- reply[*len] ='\0';
-
- /* Return completion status of command */
- return pclose(pipe);
-}
diff --git a/cman/tests/user_service.c b/cman/tests/user_service.c
deleted file mode 100644
index f47987b..0000000
--- a/cman/tests/user_service.c
+++ /dev/null
@@ -1,285 +0,0 @@
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <signal.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include "cnxman-socket.h"
-
-static pthread_t recv_thread;
-static int cl_sock;
-static int quit = 0;
-static int leave_finished = 0;
-static pid_t our_pid;
-
-
-/* SIGUSR1 will cause this program to look for a new service event from SM
- using the GETEVENT ioctl.
-
- SIGTERM will cause this program to leave the service group cleanly; it will
- do a LEAVE ioctl, get a stop event and then exit.
-
- SIGKILL will cause the program to exit without first leaving the service
- group. In that case the kernel will clean up and leave the service group
- (as a part of cl_release on the cluster socket). */
-
-
-static void sigusr1_handler(int sig)
-{
-}
-
-static void sigterm_handler(int sig)
-{
- quit = 1;
-}
-
-/* This thread receives messages on the cluster socket and prints them. */
-
-static void *recv_thread_fn(void *arg)
-{
- struct iovec iov[2];
- struct msghdr msg;
- struct sockaddr_cl saddr;
- char buf[256];
- int len;
- int nodeid;
-
- for (;;) {
- memset(buf, 0, 256);
-
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_iovlen = 1;
- msg.msg_iov = iov;
- msg.msg_name = &saddr;
- msg.msg_flags = 0;
- msg.msg_namelen = sizeof(saddr);
- iov[0].iov_len = sizeof(buf);
- iov[0].iov_base = buf;
-
- len = recvmsg(cl_sock, &msg, MSG_OOB);
-
- if (len < 0 && errno == EAGAIN)
- continue;
-
- if (!len || len < 0)
- continue;
-
- nodeid = saddr.scl_nodeid;
-
- if (buf[0] == CLUSTER_OOB_MSG_PORTCLOSED)
- printf("message: oob port-closed from nodeid %d\n",
- nodeid);
-
- else if (buf[0] == CLUSTER_OOB_MSG_SERVICEEVENT)
- printf("message: oob service-event\n");
-
- else if (!strcmp(buf, "hello"))
- printf("message: \"%s\" from nodeid %d\n", buf, nodeid);
-
- else
- printf("message: unknown len %d byte0 %x nodeid %d\n",
- len, buf[0], nodeid);
- }
-}
-
-static void send_group_message(void)
-{
- struct iovec iov[2];
- struct msghdr msg;
- char buf[256];
- int len;
-
- strcpy(buf, "hello");
-
- iov[0].iov_len = strlen(buf);
- iov[0].iov_base = buf;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_iovlen = 1;
- msg.msg_iov = iov;
- msg.msg_name = NULL;
- msg.msg_flags = O_NONBLOCK;
- msg.msg_namelen = 0;
-
- len = sendmsg(cl_sock, &msg, 0);
-}
-
-static void print_ev(struct cl_service_event *ev)
-{
- switch (ev->type) {
- case SERVICE_EVENT_STOP:
- printf("stop:\n");
- break;
- case SERVICE_EVENT_START:
- printf("start:\n");
- break;
- case SERVICE_EVENT_FINISH:
- printf("finish:\n");
- break;
- case SERVICE_EVENT_LEAVEDONE:
- printf("leavedone:\n");
- break;
- }
- printf(" event_id = %u\n", ev->event_id);
- printf(" last_stop = %u\n", ev->last_stop);
- printf(" last_start = %u\n", ev->last_start);
- printf(" last_finish = %u\n", ev->last_finish);
- printf(" node_count = %u\n", ev->node_count);
-}
-
-static void print_members(int count, struct cl_cluster_node *nodes)
-{
- int i;
-
- printf("members:\n");
- for (i = 0; i < count; i++) {
- printf(" nodeid = %u \"%s\"\n", nodes->node_id, nodes->name);
- nodes++;
- }
-}
-
-static int process_event(struct cl_service_event *ev)
-{
- struct cl_cluster_node *nodes;
- int error = 0;
-
- print_ev(ev);
-
- if (ev->type == SERVICE_EVENT_START) {
-
- nodes = malloc(ev->node_count * sizeof(struct cl_cluster_node));
- if (!nodes) {
- perror("process_event: malloc failed");
- return -ENOMEM;
- }
-
- memset(nodes, 0, ev->node_count*sizeof(struct cl_cluster_node));
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_GETMEMBERS, nodes);
- if (error < 0)
- perror("process_event: service get members failed");
-
- print_members(ev->node_count, nodes);
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_STARTDONE,
- ev->event_id);
- if (error < 0)
- perror("process_event: start done error");
-
- /* send_group_message(); */
-
- free(nodes);
- }
-
- if (ev->type == SERVICE_EVENT_LEAVEDONE)
- leave_finished = 1;
-
- return error;
-}
-
-int main(int argc, char **argv)
-{
- struct cl_service_event event;
- struct sockaddr_cl saddr;
- char *name;
- int error;
-
- our_pid = getpid();
-
- if (argc > 1)
- name = argv[1];
- else
- name = "example";
-
-
- cl_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT);
- if (cl_sock < 0) {
- perror("main: can't create cluster socket");
- return -1;
- }
-
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_REGISTER, name);
- if (error < 0) {
- perror("main: service register failed");
- return -1;
- }
-
-
- /* binding to an address is only needed if we want to send/recv
- messages to other nodes on the cluster socket. */
-
-#if 0
- saddr.scl_family = AF_CLUSTER;
- saddr.scl_port = 13; /* CLUSTER_PORT_USER_SERVICE */
-
- error = bind(cl_sock, (struct sockaddr *) &saddr,
- sizeof(struct sockaddr_cl));
- if (error < 0) {
- perror("main: can't bind to cluster socket");
- return -1;
- }
- pthread_create(&recv_thread, NULL, recv_thread_fn, 0);
-#endif
-
- signal(SIGUSR1, sigusr1_handler);
- signal(SIGTERM, sigterm_handler);
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_SETSIGNAL, SIGUSR1);
- if (error < 0) {
- perror("main: service set signal failed");
- return -1;
- }
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_JOIN, NULL);
- if (error < 0) {
- perror("main: service join failed");
- return -1;
- }
-
-
- for (;;) {
- memset(&event, 0, sizeof(struct cl_service_event));
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_GETEVENT, &event);
- if (error < 0) {
- perror("main: service get event failed");
- return -1;
- }
-
- if (!error)
- pause();
- else
- process_event(&event);
-
-
- if (quit) {
- quit = 0;
- leave_finished = 0;
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_LEAVE, NULL);
- if (error < 0) {
- perror("main: service leave failed");
- return -1;
- }
- }
-
- if (leave_finished)
- break;
- }
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_UNREGISTER, NULL);
- if (error < 0)
- perror("main: unregister failed");
-
- return 0;
-}
diff --git a/common/Makefile b/common/Makefile
deleted file mode 100644
index 31fdfdb..0000000
--- a/common/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS=liblogthread
diff --git a/common/liblogthread/Makefile b/common/liblogthread/Makefile
deleted file mode 100644
index be072bf..0000000
--- a/common/liblogthread/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET= liblogthread
-
-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${incdir}
-
-LDFLAGS += -lpthread
diff --git a/common/liblogthread/liblogthread.c b/common/liblogthread/liblogthread.c
deleted file mode 100644
index b44f01a..0000000
--- a/common/liblogthread/liblogthread.c
+++ /dev/null
@@ -1,378 +0,0 @@
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <time.h>
-#include <syslog.h>
-#include <pthread.h>
-#include <sys/param.h>
-
-#include "liblogthread.h"
-
-#define DEFAULT_ENTRIES 4096
-#define ENTRY_STR_LEN 128
-
-struct entry {
- int level;
- char str[ENTRY_STR_LEN];
- time_t time;
-};
-
-static struct entry *ents;
-static unsigned int num_ents = DEFAULT_ENTRIES;
-static unsigned int head_ent, tail_ent; /* add at head, remove from tail */
-static unsigned int dropped;
-static unsigned int pending_ents;
-static unsigned int init;
-static unsigned int done;
-static pthread_t thread_handle;
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-
-static int logt_mode; /* LOG_MODE_ */
-static int logt_syslog_facility;
-static int logt_syslog_priority;
-static int logt_logfile_priority;
-static char logt_name[PATH_MAX];
-static char logt_logfile[PATH_MAX];
-static FILE *logt_logfile_fp;
-static FILE *new_logt_logfile_fp;
-
-static char *_time(time_t *t)
-{
- static char buf[64];
- struct tm *tm;
-
- tm = localtime(t);
- if (!tm) {
- strncpy(buf, "unknown time", sizeof(buf) - 1);
- } else {
- strftime(buf, sizeof(buf), "%b %d %T", tm);
- }
-
- return buf;
-}
-
-static void write_entry(int level, time_t *t, char *str)
-{
- if ((logt_mode & LOG_MODE_OUTPUT_FILE) &&
- (level <= logt_logfile_priority) && logt_logfile_fp) {
- fprintf(logt_logfile_fp, "%s %s %s", _time(t), logt_name, str);
- fflush(logt_logfile_fp);
- }
- if ((logt_mode & LOG_MODE_OUTPUT_SYSLOG) &&
- (level <= logt_syslog_priority))
- syslog(level, "%s", str);
-}
-
-static void write_dropped(int level, time_t *t, int num)
-{
- char str[ENTRY_STR_LEN];
- snprintf(str, sizeof(str) - 1, "dropped %d entries", num);
- write_entry(level, t, str);
-}
-
-static void *thread_fn(void *arg)
-{
- char str[ENTRY_STR_LEN];
- struct entry *e;
- time_t logtime;
- int level, prev_dropped = 0;
-
- while (1) {
- pthread_mutex_lock(&mutex);
- while (head_ent == tail_ent) {
- if (done) {
- pthread_mutex_unlock(&mutex);
- goto out;
- }
- pthread_cond_wait(&cond, &mutex);
- }
-
- e = &ents[tail_ent++];
- tail_ent = tail_ent % num_ents;
- pending_ents--;
-
- memcpy(str, e->str, ENTRY_STR_LEN);
- level = e->level;
- logtime = e->time;
-
- prev_dropped = dropped;
- dropped = 0;
-
- if (new_logt_logfile_fp) {
- fclose(logt_logfile_fp);
- logt_logfile_fp = new_logt_logfile_fp;
- new_logt_logfile_fp = NULL;
- }
-
- pthread_mutex_unlock(&mutex);
-
- if (prev_dropped) {
- write_dropped(level, &logtime, prev_dropped);
- prev_dropped = 0;
- }
-
- write_entry(level, &logtime, str);
- }
- out:
- pthread_exit(NULL);
-}
-
-static void _logt_print(int level, char *buf)
-{
- struct entry *e;
-
- pthread_mutex_lock(&mutex);
-
- if (pending_ents == num_ents) {
- dropped++;
- goto out;
- }
-
- e = &ents[head_ent++];
- head_ent = head_ent % num_ents;
- pending_ents++;
-
- strncpy(e->str, buf, ENTRY_STR_LEN - 1);
- e->level = level;
- e->time = time(NULL);
- out:
- pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
-}
-
-void logt_print(int level, const char *fmt, ...)
-{
- va_list ap;
- char buf[ENTRY_STR_LEN];
-
- if (!init)
- return;
-
- buf[sizeof(buf) - 1] = 0;
-
- va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
- va_end(ap);
-
- if (level > logt_syslog_priority && level > logt_logfile_priority)
- return;
-
- /* this stderr crap really doesn't belong in this lib, please
- feel free to not use it */
- if (logt_mode & LOG_MODE_OUTPUT_STDERR)
- fputs(buf, stderr);
-
- _logt_print(level, buf);
-}
-
-static void _conf(const char *name, int mode, int syslog_facility,
- int syslog_priority, int logfile_priority, const char *logfile)
-{
- int fd;
-
- logt_mode = mode;
- logt_syslog_facility = syslog_facility;
- logt_syslog_priority = syslog_priority;
- logt_logfile_priority = logfile_priority;
- if (name)
- strncpy(logt_name, name, PATH_MAX - 1);
- if (logfile)
- strncpy(logt_logfile, logfile, PATH_MAX - 1);
-
- if (logt_mode & LOG_MODE_OUTPUT_FILE && logt_logfile[0]) {
- /* Don't close the existing fp in this thread, let the main logthread do it later */
- if (!logt_logfile_fp) {
- logt_logfile_fp = fopen(logt_logfile, "a+");
- if (logt_logfile_fp != NULL) {
- fd = fileno(logt_logfile_fp);
- fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
- }
- }
- else {
- new_logt_logfile_fp = fopen(logt_logfile, "a+");
- if (new_logt_logfile_fp != NULL) {
- fd = fileno(new_logt_logfile_fp);
- fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
- }
- }
- } else {
- if (logt_logfile_fp) {
- fclose(logt_logfile_fp);
- logt_logfile_fp = NULL;
- }
- if (new_logt_logfile_fp) {
- fclose(new_logt_logfile_fp);
- new_logt_logfile_fp = NULL;
- }
- }
-
- if (logt_mode & LOG_MODE_OUTPUT_SYSLOG) {
- closelog();
- openlog(logt_name, LOG_CONS | LOG_PID, logt_syslog_facility);
- }
-}
-
-void logt_conf(const char *name, int mode, int syslog_facility, int syslog_priority,
- int logfile_priority, const char *logfile)
-{
- pthread_mutex_lock(&mutex);
- if (init)
- _conf(name, mode, syslog_facility, syslog_priority, logfile_priority,
- logfile);
-
- pthread_mutex_unlock(&mutex);
-}
-
-static int _init(const char *name, int mode, int syslog_facility, int syslog_priority,
- int logfile_priority, const char *logfile)
-{
- if (init)
- return -1;
-
- _conf(name, mode, syslog_facility, syslog_priority, logfile_priority,
- logfile);
-
- ents = malloc(num_ents * sizeof(struct entry));
- if (!ents)
- return -1;
-
- memset(ents, 0, num_ents * sizeof(struct entry));
-
- if (pthread_create(&thread_handle, NULL, thread_fn, NULL)) {
- free(ents);
- return -1;
- }
- done = 0;
- init = 1;
-
- return 0;
-}
-
-int logt_init(const char *name, int mode, int syslog_facility, int syslog_priority,
- int logfile_priority, const char *logfile)
-{
- int rv = 0;
-
- pthread_mutex_lock(&mutex);
- rv = _init(name, mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
- pthread_mutex_unlock(&mutex);
- return rv;
-}
-
-/*
- * Reinitialize logt w/ previous values (e.g. use after
- * a call to fork())
- *
- * Only works after you call logt_init and logt_exit
- */
-int logt_reinit(void)
-{
- char name_tmp[PATH_MAX];
- char file_tmp[PATH_MAX];
- int rv = 0;
-
- pthread_mutex_lock(&mutex);
- if (!done || init) {
- rv = -1;
- goto out;
- }
-
- /* Use copies on the stack for these */
- memset(name_tmp, 0, sizeof(name_tmp));
- memset(file_tmp, 0, sizeof(file_tmp));
-
- strncpy(name_tmp, logt_name, sizeof(name_tmp) - 1);
- if (!strlen(name_tmp)) {
- rv = -1;
- goto out;
- }
- if (strlen(logt_logfile))
- strncpy(file_tmp, logt_logfile, sizeof(file_tmp) - 1);
-
- rv = _init(name_tmp, logt_mode, logt_syslog_facility,
- logt_syslog_priority, logt_logfile_priority,
- file_tmp);
-
-out:
- pthread_mutex_unlock(&mutex);
- return rv;
-}
-
-
-void logt_exit(void)
-{
- pthread_mutex_lock(&mutex);
- done = 1;
- init = 0;
- pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
- pthread_join(thread_handle, NULL);
-
- pthread_mutex_lock(&mutex);
- /* close syslog + log file */
- closelog();
- if (logt_logfile_fp) {
- fclose(logt_logfile_fp);
- logt_logfile_fp = NULL;
- }
-
- /* clean up any pending log messages */
- dropped = 0;
- pending_ents = 0;
- head_ent = tail_ent = 0;
- free(ents);
- ents = NULL;
-
- pthread_mutex_unlock(&mutex);
-}
-
-#ifdef TEST
-int main(int argc, char **argv)
-{
- int pid;
-
- logt_init("test", LOG_MODE_OUTPUT_FILE|LOG_MODE_OUTPUT_SYSLOG,
- LOG_DAEMON, LOG_DEBUG, LOG_DEBUG, "/tmp/logthread");
- logt_print(LOG_DEBUG, "debugging message %d\n", argc);
- logt_print(LOG_ERR, "error message %d\n", argc);
- sleep(1);
- logt_print(LOG_DEBUG, "second debug message\n");
- logt_exit();
-
- logt_print(LOG_ERR, "If you see this, it's a bug\n");
-
- logt_init("test2", LOG_MODE_OUTPUT_FILE|LOG_MODE_OUTPUT_SYSLOG,
- LOG_DAEMON, LOG_DEBUG, LOG_DEBUG, "/tmp/logthread");
- logt_print(LOG_DEBUG, "after 2nd init %d\n", argc);
- logt_print(LOG_ERR, "error message %d\n", argc);
- logt_print(LOG_DEBUG, "third debug message\n");
- logt_exit();
-
- logt_print(LOG_ERR, "If you see this, it's a bug\n");
-
- logt_reinit();
- logt_print(LOG_DEBUG, "after reinit\n");
- logt_print(LOG_DEBUG, "<-- should say test2\n");
-
- logt_exit();
-
- if ((pid = fork()) < 0)
- return -1;
-
- if (pid)
- exit(0);
-
- /* child process */
- logt_reinit();
- logt_print(LOG_DEBUG, "HELLO from child process\n");
- logt_exit();
-
- return 0;
-}
-#endif
-
diff --git a/common/liblogthread/liblogthread.h b/common/liblogthread/liblogthread.h
deleted file mode 100644
index 3c17395..0000000
--- a/common/liblogthread/liblogthread.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef LOGTHREAD_DOT_H
-#define LOGTHREAD_DOT_H
-
-#include <syslog.h>
-
-#define LOG_MODE_OUTPUT_FILE 1
-#define LOG_MODE_OUTPUT_SYSLOG 2
-#define LOG_MODE_OUTPUT_STDERR 4
-
-int logt_init(const char *name, int mode, int syslog_facility, int syslog_priority,
- int logfile_priority, const char *logfile);
-void logt_conf(const char *name, int mode, int syslog_facility, int syslog_priority,
- int logfile_priority, const char *logfile);
-void logt_exit(void);
-int logt_reinit(void);
-void logt_print(int level, const char *fmt, ...)
- __attribute__((format(printf, 2, 3)));;
-
-#endif
diff --git a/common/liblogthread/liblogthread.pc.in b/common/liblogthread/liblogthread.pc.in
deleted file mode 100644
index 8ba8268..0000000
--- a/common/liblogthread/liblogthread.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: liblogthread
-Version: @VERSION@
-Description: Cluster threaded logging library
-Requires:
-Libs: -L${libdir} -llogthread
-Cflags: -I${includedir}
diff --git a/config/Makefile b/config/Makefile
deleted file mode 100644
index 50468ed..0000000
--- a/config/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS=libs plugins tools man
diff --git a/config/libs/Makefile b/config/libs/Makefile
deleted file mode 100644
index 8fd2879..0000000
--- a/config/libs/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS = libccsconfdb
diff --git a/config/libs/libccsconfdb/Makefile b/config/libs/libccsconfdb/Makefile
deleted file mode 100644
index 2b233f3..0000000
--- a/config/libs/libccsconfdb/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-TARGET= libccs
-
-INCDIRT=ccs.h
-
-OBJS= $(TARGET).o \
- xpathlite.o \
- fullxpath.o \
- extras.o
-
-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 += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64
-CFLAGS += -I${corosyncincdir} -I${logtincdir} `xml2-config --cflags`
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${corosynclibdir} -lconfdb
-LDFLAGS += `xml2-config --libs`
-LDFLAGS += -L${libdir}
diff --git a/config/libs/libccsconfdb/ccs.h b/config/libs/libccsconfdb/ccs.h
deleted file mode 100644
index 5c67735..0000000
--- a/config/libs/libccsconfdb/ccs.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __CCS_DOT_H__
-#define __CCS_DOT_H__
-
-int ccs_connect(void);
-int ccs_force_connect(const char *cluster_name, int blocking);
-int ccs_disconnect(int desc);
-int ccs_get(int desc, const char *query, char **rtn);
-int ccs_get_list(int desc, const char *query, char **rtn);
-int ccs_set(int desc, const char *path, char *val);
-int ccs_lookup_nodename(int desc, const char *nodename, char **rtn);
-void ccs_read_logging(int fd, const char *name, int *debug, int *mode,
- int *syslog_facility, int *syslog_priority,
- int *logfile_priority, char *logfile);
-extern int fullxpath;
-
-#endif /* __CCS_DOT_H__ */
diff --git a/config/libs/libccsconfdb/ccs_internal.h b/config/libs/libccsconfdb/ccs_internal.h
deleted file mode 100644
index 617f9e7..0000000
--- a/config/libs/libccsconfdb/ccs_internal.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __CCS_INTERNAL_DOT_H__
-#define __CCS_INTERNAL_DOT_H__
-
-/* NOTE: use __attribute__ to hide the internal API */
-
-/* from libccs.c */
-void reset_iterator(confdb_handle_t handle, hdb_handle_t connection_handle)
- __attribute__ ((visibility("hidden")));
-int get_previous_query(confdb_handle_t handle, hdb_handle_t connection_handle,
- char *previous_query, hdb_handle_t *query_handle)
- __attribute__ ((visibility("hidden")));
-int set_previous_query(confdb_handle_t handle, hdb_handle_t connection_handle,
- const char *previous_query, hdb_handle_t query_handle)
- __attribute__ ((visibility("hidden")));
-
-/* from xpathlite.c */
-char *_ccs_get_xpathlite(confdb_handle_t handle, hdb_handle_t connection_handle,
- const char *query, int list)
- __attribute__ ((visibility("hidden")));
-
-/* from fullxpath.c */
-char *_ccs_get_fullxpath(confdb_handle_t handle, hdb_handle_t connection_handle,
- const char *query, int list)
- __attribute__ ((visibility("hidden")));
-int xpathfull_init(confdb_handle_t handle)
- __attribute__ ((visibility("hidden")));
-void xpathfull_finish(void) __attribute__ ((visibility("hidden")));
-
-#endif /* __CCS_INTERNAL_DOT_H__ */
diff --git a/config/libs/libccsconfdb/extras.c b/config/libs/libccsconfdb/extras.c
deleted file mode 100644
index 34cbbae..0000000
--- a/config/libs/libccsconfdb/extras.c
+++ /dev/null
@@ -1,454 +0,0 @@
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <limits.h>
-
-#define SYSLOG_NAMES
-#include <syslog.h>
-#include <liblogthread.h>
-
-#include "ccs.h"
-
-/**
- * ccs_lookup_nodename
- * @cd: ccs descriptor
- * @nodename: node name string
- * @retval: pointer to location to assign the result, if found
- *
- * This function takes any valid representation (FQDN, non-qualified
- * hostname, IP address, IPv6 address) of a node's name and finds its
- * canonical name (per cluster.conf). This function will find the primary
- * node name if passed a node's "altname" or any valid representation
- * of it.
- *
- * Returns: 0 on success, < 0 on failure
- */
-int ccs_lookup_nodename(int cd, const char *nodename, char **retval)
-{
- char path[256];
- char host_only[128];
- char *str;
- char *p;
- int error;
- int ret;
- unsigned int i;
- size_t nodename_len;
- struct addrinfo hints;
-
- if (nodename == NULL) {
- errno = EINVAL;
- return -1;
- }
-
- nodename_len = strlen(nodename);
- ret = snprintf(path, sizeof(path),
- "/cluster/clusternodes/clusternode[@name=\"%s\"]/@name",
- nodename);
- if (ret < 0 || (size_t) ret >= sizeof(path)) {
- errno = E2BIG;
- return -1;
- }
-
- str = NULL;
- error = ccs_get(cd, path, &str);
- if (!error) {
- *retval = str;
- return 0;
- }
-
- if (nodename_len >= sizeof(host_only)) {
- errno = E2BIG;
- return -1;
- }
-
- /* Try just the hostname */
- strncpy(host_only, nodename, sizeof(host_only) - 1);
- p = strchr(host_only, '.');
- if (p != NULL) {
- *p = '\0';
-
- ret = snprintf(path, sizeof(path),
- "/cluster/clusternodes/clusternode[@name=\"%s\"]/@name",
- host_only);
- if (ret < 0 || (size_t) ret >= sizeof(path)) {
- errno = E2BIG;
- return -1;
- }
-
- str = NULL;
- error = ccs_get(cd, path, &str);
- if (!error) {
- *retval = str;
- return 0;
- }
- }
-
- memset(&hints, 0, sizeof(hints));
- if (strchr(nodename, ':') != NULL)
- hints.ai_family = AF_INET6;
- else if (isdigit(nodename[nodename_len - 1]))
- hints.ai_family = AF_INET;
- else
- hints.ai_family = AF_UNSPEC;
-
- /*
- ** Try to match against each clusternode in cluster.conf.
- */
- for (i = 1;; i++) {
- char canonical_name[128];
- unsigned int altcnt;
-
- ret = snprintf(path, sizeof(path),
- "/cluster/clusternodes/clusternode[%u]/@name",
- i);
- if (ret < 0 || (size_t) ret >= sizeof(path))
- continue;
-
- for (altcnt = 0;; altcnt++) {
- size_t len;
- struct addrinfo *ai = NULL;
- char cur_node[128];
-
- if (altcnt != 0) {
- ret = snprintf(path, sizeof(path),
- "/cluster/clusternodes/clusternode[%u]/altname[%u]/@name",
- i, altcnt);
- if (ret < 0 || (size_t) ret >= sizeof(path))
- continue;
- }
-
- str = NULL;
- error = ccs_get(cd, path, &str);
- if (error || !str) {
- if (altcnt == 0)
- goto out_fail;
- break;
- }
-
- if (altcnt == 0) {
- if (strlen(str) >= sizeof(canonical_name)) {
- free(str);
- errno = E2BIG;
- return -1;
- }
- strncpy(canonical_name, str, sizeof(canonical_name) - 1);
- }
-
- if (strlen(str) >= sizeof(cur_node)) {
- free(str);
- errno = E2BIG;
- return -1;
- }
-
- strncpy(cur_node, str, sizeof(cur_node) - 1);
-
- p = strchr(cur_node, '.');
- if (p != NULL)
- len = p - cur_node;
- else
- len = strlen(cur_node);
-
- if (strlen(host_only) == len &&
- !strncasecmp(host_only, cur_node, len)) {
- free(str);
- *retval = strdup(canonical_name);
- if (*retval == NULL) {
- errno = ENOMEM;
- return -1;
- }
- return 0;
- }
-
- if (getaddrinfo(str, NULL, &hints, &ai) == 0) {
- struct addrinfo *cur;
-
- for (cur = ai; cur != NULL; cur = cur->ai_next) {
- char hostbuf[512];
- if (getnameinfo
- (cur->ai_addr, cur->ai_addrlen,
- hostbuf, sizeof(hostbuf), NULL, 0,
- hints.ai_family !=
- AF_UNSPEC ? NI_NUMERICHOST : 0)) {
- continue;
- }
-
- if (!strcasecmp(hostbuf, nodename)) {
- freeaddrinfo(ai);
- free(str);
- *retval =
- strdup(canonical_name);
- if (*retval == NULL) {
- errno = ENOMEM;
- return -1;
- }
- return 0;
- }
- }
- freeaddrinfo(ai);
- }
-
- free(str);
-
- /* Now try any altnames */
- }
- }
-
-out_fail:
- errno = EINVAL;
- *retval = NULL;
- return -1;
-}
-
-static int facility_id_get(char *name)
-{
- unsigned int i;
-
- for (i = 0; facilitynames[i].c_name != NULL; i++) {
- if (strcasecmp(name, facilitynames[i].c_name) == 0) {
- return (facilitynames[i].c_val);
- }
- }
- return (-1);
-}
-
-static int priority_id_get(char *name)
-{
- unsigned int i;
-
- for (i = 0; prioritynames[i].c_name != NULL; i++) {
- if (strcasecmp(name, prioritynames[i].c_name) == 0) {
- return (prioritynames[i].c_val);
- }
- }
- return (-1);
-}
-
-/* requires string buffer to be PATH_MAX */
-static void read_string(int fd, const char *path, char *string, size_t string_s)
-{
- char *str;
- int error;
-
- memset(string, 0, PATH_MAX);
-
- error = ccs_get(fd, path, &str);
- if (error || !str)
- return;
-
- strncpy(string, str, string_s - 1);
-
- free(str);
-}
-
-static void read_yesno(int fd, const char *path, int *yes, int *no)
-{
- char *str;
- int error;
-
- *yes = 0;
- *no = 0;
-
- error = ccs_get(fd, path, &str);
- if (error || !str)
- return;
-
- if (!strcmp(str, "yes"))
- *yes = 1;
- else if (!strcmp(str, "no"))
- *no = 1;
-
- free(str);
-}
-
-static void read_onoff(int fd, const char *path, int *on, int *off)
-{
- char *str;
- int error;
-
- *on = 0;
- *off = 0;
-
- error = ccs_get(fd, path, &str);
- if (error || !str)
- return;
-
- if (!strcmp(str, "on"))
- *on = 1;
- else if (!strcmp(str, "off"))
- *off = 1;
-
- free(str);
-}
-
-/* requires path buffer to be PATH_MAX */
-static void create_daemon_path(const char *name, const char *field, char *path)
-{
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX,
- "/cluster/logging/logging_daemon[@name=\"%s\"]/@%s",
- name, field);
-}
-
-/* Values should be initialized to default values before calling
- this function; they are not changed if cluster.conf has nothing
- to say about them. If *debug is already set , then *logfile_priority
- is set to LOG_DEBUG; all debug and logfile_priority values from
- cluster.conf are ignored. */
-
-void ccs_read_logging(int fd, const char *name, int *debug, int *mode,
- int *syslog_facility, int *syslog_priority,
- int *logfile_priority, char *logfile)
-{
- char string[PATH_MAX];
- char path[PATH_MAX];
- int val, y, n, on, off;
-
- /*
- * to_syslog
- */
- create_daemon_path(name, "to_syslog", path);
-
- read_yesno(fd, "/cluster/logging/@to_syslog", &y, &n);
- if (y)
- *mode |= LOG_MODE_OUTPUT_SYSLOG;
- if (n)
- *mode &= ~LOG_MODE_OUTPUT_SYSLOG;
-
- read_yesno(fd, path, &y, &n);
- if (y)
- *mode |= LOG_MODE_OUTPUT_SYSLOG;
- if (n)
- *mode &= ~LOG_MODE_OUTPUT_SYSLOG;
-
- /*
- * to_logfile
- */
- create_daemon_path(name, "to_logfile", path);
-
- read_yesno(fd, "/cluster/logging/@to_logfile", &y, &n);
- if (y)
- *mode |= LOG_MODE_OUTPUT_FILE;
- if (n)
- *mode &= ~LOG_MODE_OUTPUT_FILE;
-
- read_yesno(fd, path, &y, &n);
- if (y)
- *mode |= LOG_MODE_OUTPUT_FILE;
- if (n)
- *mode &= ~LOG_MODE_OUTPUT_FILE;
-
- /*
- * syslog_facility
- */
- create_daemon_path(name, "syslog_facility", path);
-
- read_string(fd, "/cluster/logging/@syslog_facility",
- string, sizeof(string));
-
- if (string[0]) {
- val = facility_id_get(string);
- if (val >= 0)
- *syslog_facility = val;
- }
-
- read_string(fd, path, string, sizeof(string));
-
- if (string[0]) {
- val = facility_id_get(string);
- if (val >= 0)
- *syslog_facility = val;
- }
-
- /*
- * syslog_priority
- */
- create_daemon_path(name, "syslog_priority", path);
-
- read_string(fd, "/cluster/logging/@syslog_priority",
- string, sizeof(string));
-
- if (string[0]) {
- val = priority_id_get(string);
- if (val >= 0)
- *syslog_priority = val;
- }
-
- read_string(fd, path, string, sizeof(string));
-
- if (string[0]) {
- val = priority_id_get(string);
- if (val >= 0)
- *syslog_priority = val;
- }
-
- /*
- * logfile
- */
- create_daemon_path(name, "logfile", path);
-
- read_string(fd, "/cluster/logging/@logfile", string, sizeof(string));
-
- if (string[0])
- strcpy(logfile, string);
-
- read_string(fd, path, string, sizeof(string));
-
- if (string[0])
- strcpy(logfile, string);
-
- /*
- * debug is only ever turned on, not off, so if it's already on
- * (from the daemon), then just skip the debug lookups.
- */
- if (*debug) {
- *logfile_priority = LOG_DEBUG;
- return;
- }
-
- /*
- * debug
- * debug=on is a shortcut for logfile_priority=LOG_DEBUG
- */
- create_daemon_path(name, "debug", path);
-
- read_onoff(fd, "/cluster/logging/@debug", &on, &off);
- if (on)
- *debug = 1;
-
- read_onoff(fd, path, &on, &off);
- if (on)
- *debug = 1;
- else if (off)
- *debug = 0;
-
- if (*debug) {
- *logfile_priority = LOG_DEBUG;
- return;
- }
-
- /*
- * logfile_priority
- */
- create_daemon_path(name, "logfile_priority", path);
-
- read_string(fd, "/cluster/logging/@logfile_priority",
- string, sizeof(string));
-
- if (string[0]) {
- val = priority_id_get(string);
- if (val >= 0)
- *logfile_priority = val;
- }
-
- read_string(fd, path, string, sizeof(string));
-
- if (string[0]) {
- val = priority_id_get(string);
- if (val >= 0)
- *logfile_priority = val;
- }
-}
-
diff --git a/config/libs/libccsconfdb/fullxpath.c b/config/libs/libccsconfdb/fullxpath.c
deleted file mode 100644
index bffb9c3..0000000
--- a/config/libs/libccsconfdb/fullxpath.c
+++ /dev/null
@@ -1,361 +0,0 @@
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <corosync/corotypes.h>
-#include <corosync/confdb.h>
-#include <libxml/parser.h>
-#include <libxml/xpath.h>
-
-#include "ccs.h"
-#include "ccs_internal.h"
-
-#ifndef XMLBUFSIZE
-#define XMLBUFSIZE 64000
-#endif
-
-int fullxpath = 0;
-
-static xmlDocPtr doc = NULL;
-static xmlXPathContextPtr ctx = NULL;
-
-static int add_to_buffer(char *data, char **buffer, int *bufsize)
-{
- int datalen = 0, bufferlen = 0;
- char *newbuf = NULL;
-
- datalen = strlen(data);
- bufferlen = strlen(*buffer);
-
- if (datalen) {
- if ((bufferlen + datalen) >= *bufsize) {
- newbuf = malloc((*bufsize * 2));
- if (!newbuf) {
- errno = ENOMEM;
- return -1;
- }
- *bufsize = *bufsize * 2;
- memset(newbuf, 0, *bufsize);
- memcpy(newbuf, *buffer, bufferlen);
- free(*buffer);
- *buffer = newbuf;
- }
- strncpy(*buffer + bufferlen, data, datalen);
- }
- return 0;
-}
-
-static int dump_objdb_buff(confdb_handle_t dump_handle, hdb_handle_t cluster_handle,
- hdb_handle_t parent_object_handle, char **buffer,
- int *bufsize)
-{
- hdb_handle_t object_handle;
- char temp[PATH_MAX];
- char object_name[PATH_MAX];
- char key_name[PATH_MAX];
- char *key_value = NULL;
- size_t key_value_len = 0, object_name_len = 0;
- confdb_value_types_t type;
- int res;
-
- res = confdb_key_iter_start(dump_handle, parent_object_handle);
- if (res != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- if (!strlen(*buffer)) {
- snprintf(temp, PATH_MAX - 1,
- "<?xml version=\"1.0\"?>\n<cluster");
- if (add_to_buffer(temp, buffer, bufsize))
- return -1;
- }
-
- while ((res =
- confdb_key_iter_typed2(dump_handle, parent_object_handle, key_name,
- (void **)&key_value,
- &key_value_len, &type)) == CS_OK) {
- int char_pos = 0;
- key_value[key_value_len] = '\0';
-
- snprintf(temp, PATH_MAX - 1, " %s=\"", key_name);
- if (add_to_buffer(temp, buffer, bufsize)) {
- free(key_value);
- return -1;
- }
-
- for (char_pos = 0; char_pos < key_value_len-1; char_pos++) {
- switch (key_value[char_pos]) {
-
- case '&':
- snprintf(temp, PATH_MAX - 1, "&");
- break;
- case '<':
- snprintf(temp, PATH_MAX - 1, "<");
- break;
- case '>':
- snprintf(temp, PATH_MAX - 1, ">");
- break;
- case '"':
- snprintf(temp, PATH_MAX - 1, """);
- break;
- case '\'':
- snprintf(temp, PATH_MAX - 1, "'");
- break;
- default:
- temp[0] = key_value[char_pos];
- temp[1] = '\0';
- break;
- }
- if (add_to_buffer(temp, buffer, bufsize)) {
- free(key_value);
- return -1;
- }
- }
- free(key_value);
- key_value = NULL;
-
- snprintf(temp, PATH_MAX - 1, "\"");
- if (add_to_buffer(temp, buffer, bufsize))
- return -1;
- }
-
- if (parent_object_handle > 0) {
- snprintf(temp, PATH_MAX - 1, ">\n");
- if (add_to_buffer(temp, buffer, bufsize))
- return -1;
- }
-
- res = confdb_object_iter_start(dump_handle, parent_object_handle);
- if (res != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- while ((res =
- confdb_object_iter(dump_handle, parent_object_handle,
- &object_handle, object_name,
- &object_name_len)) == CS_OK) {
- hdb_handle_t parent;
-
- res =
- confdb_object_parent_get(dump_handle, object_handle,
- &parent);
- if (res != CS_OK) {
- errno = EINVAL;
- return -1;
- }
-
- object_name[object_name_len] = '\0';
-
- snprintf(temp, PATH_MAX - 1, "<%s", object_name);
- if (add_to_buffer(temp, buffer, bufsize))
- return -1;
-
- res =
- dump_objdb_buff(dump_handle, cluster_handle, object_handle, buffer,
- bufsize);
- if (res)
- return res;
-
- if (object_handle != parent_object_handle) {
- snprintf(temp, PATH_MAX - 1, "</%s>\n", object_name);
- if (add_to_buffer(temp, buffer, bufsize))
- return -1;
- } else {
- snprintf(temp, PATH_MAX - 1, ">\n");
- if (add_to_buffer(temp, buffer, bufsize))
- return -1;
- }
- }
-
- if (parent_object_handle == cluster_handle) {
- snprintf(temp, PATH_MAX - 1, "</cluster>\n");
- if (add_to_buffer(temp, buffer, bufsize))
- return -1;
- }
-
- return 0;
-}
-
-int xpathfull_init(confdb_handle_t handle)
-{
- int size = XMLBUFSIZE;
- char *buffer;
- hdb_handle_t cluster_handle;
-
- buffer = malloc(XMLBUFSIZE);
- if (!buffer) {
- errno = ENOMEM;
- goto fail;
- }
-
- memset(buffer, 0, XMLBUFSIZE);
-
- if (confdb_object_find_start(handle, OBJECT_PARENT_HANDLE) != CS_OK)
- goto fail;
-
- if (confdb_object_find(handle, OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"), &cluster_handle) != CS_OK)
- goto fail;
-
- if (dump_objdb_buff(handle, cluster_handle, cluster_handle, &buffer, &size))
- goto fail;
-
- doc = xmlParseMemory(buffer, strlen(buffer));
- if (!doc)
- goto fail;
-
- free(buffer);
-
- ctx = xmlXPathNewContext(doc);
- if (!ctx) {
- xmlFreeDoc(doc);
- goto fail;
- }
-
- return 0;
-
-fail:
- if (buffer)
- free(buffer);
-
- return -1;
-}
-
-void xpathfull_finish()
-{
- if (ctx) {
- xmlXPathFreeContext(ctx);
- ctx = NULL;
- }
- if (doc) {
- xmlFreeDoc(doc);
- doc = NULL;
- }
- return;
-}
-
-/**
- * _ccs_get_fullxpath
- * @desc:
- * @query:
- * @rtn: value returned
- * @list: 1 to operate in list fashion
- *
- * This function will allocate space for the value that is the result
- * of the given query. It is the user's responsibility to ensure that
- * the data returned is freed.
- *
- * Returns: char * to result or NULL in case of failure.
- */
-char *_ccs_get_fullxpath(confdb_handle_t handle, hdb_handle_t connection_handle,
- const char *query, int list)
-{
- xmlXPathObjectPtr obj = NULL;
- char previous_query[PATH_MAX];
- hdb_handle_t list_handle = 0;
- unsigned int xmllistindex = 0;
- int prev = 0;
- char *rtn = NULL;
- int myerrno;
-
- if (strncmp(query, "/", 1)) {
- errno = EINVAL;
- goto fail;
- }
-
- memset(previous_query, 0, PATH_MAX);
-
- prev =
- get_previous_query(handle, connection_handle, previous_query,
- &list_handle);
-
- if (list && !prev && !strcmp(query, previous_query)) {
- if (confdb_key_increment
- (handle, connection_handle, "iterator_tracker",
- strlen("iterator_tracker"), &xmllistindex) != CS_OK) {
- xmllistindex = 0;
- } else {
- xmllistindex--;
- }
- } else {
- reset_iterator(handle, connection_handle);
- xmllistindex = 0;
- }
-
- obj = xmlXPathEvalExpression((xmlChar *) query, ctx);
-
- if (!obj) {
- errno = EINVAL;
- goto fail;
- }
-
- if (obj->nodesetval && (obj->nodesetval->nodeNr > 0)) {
- xmlNodePtr node;
- int size = 0, nnv = 0;
-
- if (xmllistindex >= obj->nodesetval->nodeNr) {
- reset_iterator(handle, connection_handle);
- errno = ENODATA;
- goto fail;
- }
-
- node = obj->nodesetval->nodeTab[xmllistindex];
-
- if (!node) {
- errno = ENODATA;
- goto fail;
- }
-
- if (((node->type == XML_ATTRIBUTE_NODE) && strstr(query, "@*"))
- || ((node->type == XML_ELEMENT_NODE)
- && strstr(query, "child::*"))) {
- if (node->children && node->children->content)
- size = strlen((char *)node->children->content) +
- strlen((char *)node->name) + 2;
- else
- size = strlen((char *)node->name) + 2;
-
- nnv = 1;
- } else {
- if (node->children && node->children->content)
- size =
- strlen((char *)node->children->content) + 1;
-
- else {
- errno = ENODATA;
- goto fail;
- }
- }
-
- if (list)
- if (set_previous_query(handle, connection_handle,
- (char *)query, OBJECT_PARENT_HANDLE))
- goto fail;
-
- rtn = malloc(size);
-
- if (!rtn) {
- errno = ENOMEM;
- goto fail;
- }
-
- if (nnv)
- sprintf(rtn, "%s=%s", node->name,
- node->children ? (char *)node->children->
- content : "");
- else
- sprintf(rtn, "%s",
- node->children ? node->children->
- content : node->name);
-
- } else
- errno = EINVAL;
-
-fail:
- myerrno = errno;
- if (obj)
- xmlXPathFreeObject(obj);
-
- errno = myerrno;
- return rtn;
-}
diff --git a/config/libs/libccsconfdb/libccs.c b/config/libs/libccsconfdb/libccs.c
deleted file mode 100644
index bfc2d29..0000000
--- a/config/libs/libccsconfdb/libccs.c
+++ /dev/null
@@ -1,660 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <corosync/corotypes.h>
-#include <corosync/confdb.h>
-
-#include "ccs.h"
-#include "ccs_internal.h"
-
-/* Callbacks are not supported - we will use them to update fullxml doc/ctx */
-static confdb_callbacks_t callbacks = {
-};
-
-/* helper functions */
-
-static confdb_handle_t confdb_connect(void)
-{
- confdb_handle_t handle = 0;
-
- if (confdb_initialize(&handle, &callbacks) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- return handle;
-}
-
-static int confdb_disconnect(confdb_handle_t handle)
-{
- if (confdb_finalize(handle) != CS_OK) {
- errno = EINVAL;
- return -1;
- }
- return 0;
-}
-
-static hdb_handle_t find_libccs_handle(confdb_handle_t handle)
-{
- hdb_handle_t libccs_handle = 0;
-
- if (confdb_object_find_start(handle, OBJECT_PARENT_HANDLE) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- if (confdb_object_find
- (handle, OBJECT_PARENT_HANDLE, "libccs", strlen("libccs"),
- &libccs_handle) != CS_OK) {
- errno = ENOENT;
- return -1;
- }
-
- confdb_object_find_destroy(handle, OBJECT_PARENT_HANDLE);
-
- return libccs_handle;
-}
-
-static hdb_handle_t find_ccs_handle(confdb_handle_t handle, int ccs_handle)
-{
- int res, found = 0;
- hdb_handle_t libccs_handle = 0, connection_handle = 0;
- char data[128];
- size_t datalen = 0;
-
- libccs_handle = find_libccs_handle(handle);
- if (libccs_handle == -1)
- return -1;
-
- if (confdb_object_find_start(handle, libccs_handle) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- while (confdb_object_find
- (handle, libccs_handle, "connection", strlen("connection"),
- &connection_handle) == CS_OK) {
- memset(data, 0, sizeof(data));
- if (confdb_key_get
- (handle, connection_handle, "ccs_handle",
- strlen("ccs_handle"), data, &datalen) == CS_OK) {
- res = atoi(data);
- if (res == ccs_handle) {
- found = 1;
- break;
- }
- }
- }
-
- confdb_object_find_destroy(handle, libccs_handle);
-
- if (found) {
- return connection_handle;
- } else {
- errno = ENOENT;
- return -1;
- }
-}
-
-static int destroy_ccs_handle(confdb_handle_t handle,
- hdb_handle_t connection_handle)
-{
- if (confdb_object_destroy(handle, connection_handle) != CS_OK) {
- errno = EINVAL;
- return -1;
- }
-
- return 0;
-}
-
-static int get_running_config_version(confdb_handle_t handle, int *config_version)
-{
- hdb_handle_t cluster_handle;
- char data[128];
- size_t datalen = 0;
- int ret = -1;
-
- if (confdb_object_find_start(handle, OBJECT_PARENT_HANDLE) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- if (confdb_object_find
- (handle, OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"),
- &cluster_handle) == CS_OK) {
- memset(data, 0, sizeof(data));
- if (confdb_key_get
- (handle, cluster_handle, "config_version",
- strlen("config_version"), data, &datalen) == CS_OK) {
- *config_version = atoi(data);
- ret = 0;
- }
- }
-
- confdb_object_find_destroy(handle, OBJECT_PARENT_HANDLE);
-
- if (ret < 0)
- errno = ENODATA;
-
- return ret;
-}
-
-static int get_stored_config_version(confdb_handle_t handle,
- hdb_handle_t connection_handle, int *config_version)
-{
- char data[128];
- size_t datalen = 0;
- int ret = -1;
-
- if (confdb_key_get
- (handle, connection_handle, "config_version",
- strlen("config_version"), data, &datalen) == CS_OK) {
- *config_version = atoi(data);
- ret = 0;
- }
-
- if (ret < 0)
- errno = ENODATA;
-
- return ret;
-}
-
-static int set_stored_config_version(confdb_handle_t handle,
- hdb_handle_t connection_handle, int new_version)
-{
- char temp[PATH_MAX];
- size_t templen = 0;
- char data[128];
-
- memset(data, 0, sizeof(data));
- snprintf(data, sizeof(data), "%d", new_version);
-
- if (confdb_key_get
- (handle, connection_handle, "config_version",
- strlen("config_version"), temp, &templen) == CS_OK) {
- if (confdb_key_replace
- (handle, connection_handle, "config_version",
- strlen("config_version"), temp, templen, data,
- strlen(data) + 1) == CS_OK) {
- return 0;
- }
- }
-
- return -1;
-}
-
-static int config_reload(confdb_handle_t handle,
- hdb_handle_t connection_handle, int fullxpathint)
-{
- int running_version;
- int stored_version;
-
- if (get_running_config_version(handle, &running_version) < 0)
- return -1;
-
- if (get_stored_config_version(handle, connection_handle, &stored_version) < 0)
- return -1;
-
- if (running_version == stored_version)
- return 0;
-
- if (fullxpathint) {
- xpathfull_finish();
- if (xpathfull_init(handle))
- return -1;
- }
-
- reset_iterator(handle, connection_handle);
-
- if (set_previous_query(handle, connection_handle, "", 0))
- return -1;
-
- if (set_stored_config_version(handle, connection_handle, running_version))
- return -1;
-
- return 0;
-}
-
-static hdb_handle_t create_ccs_handle(confdb_handle_t handle, int ccs_handle,
- int xpath)
-{
- hdb_handle_t libccs_handle = 0, connection_handle = 0;
- char buf[128];
- int config_version = 0;
-
- libccs_handle = find_libccs_handle(handle);
- if (libccs_handle == -1)
- return -1;
-
- if (get_running_config_version(handle, &config_version) < 0)
- return -1;
-
- if (confdb_object_create
- (handle, libccs_handle, "connection", strlen("connection"),
- &connection_handle) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "%d", ccs_handle);
- if (confdb_key_create_typed
- (handle, connection_handle, "ccs_handle", buf,
- strlen(buf) + 1, CONFDB_VALUETYPE_STRING) != CS_OK) {
- destroy_ccs_handle(handle, connection_handle);
- errno = ENOMEM;
- return -1;
- }
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "%d", config_version);
- if (confdb_key_create_typed
- (handle, connection_handle, "config_version",
- buf, strlen(buf) + 1, CONFDB_VALUETYPE_STRING) != CS_OK) {
- destroy_ccs_handle(handle, connection_handle);
- errno = ENOMEM;
- return -1;
- }
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "%d", xpath);
- if (confdb_key_create_typed
- (handle, connection_handle, "fullxpath", buf,
- strlen(buf) + 1, CONFDB_VALUETYPE_STRING) != CS_OK) {
- destroy_ccs_handle(handle, connection_handle);
- errno = ENOMEM;
- return -1;
- }
-
- return connection_handle;
-}
-
-static hdb_handle_t get_ccs_handle(confdb_handle_t handle, int *ccs_handle,
- int xpath)
-{
- unsigned int next_handle;
- hdb_handle_t libccs_handle = 0;
- hdb_handle_t ret = 0;
-
- libccs_handle = find_libccs_handle(handle);
- if (libccs_handle == -1)
- return -1;
-
- if (confdb_key_increment
- (handle, libccs_handle, "next_handle", strlen("next_handle"),
- &next_handle) == CS_OK) {
- ret = create_ccs_handle(handle, (int)next_handle, xpath);
- if (ret == -1) {
- *ccs_handle = -1;
- return ret;
- }
-
- *ccs_handle = (int)next_handle;
- return ret;
- }
-
- *ccs_handle = -1;
- errno = ENOMEM;
- return -1;
-}
-
-int get_previous_query(confdb_handle_t handle, hdb_handle_t connection_handle,
- char *previous_query, hdb_handle_t *query_handle)
-{
- size_t datalen = 0;
-
- if (confdb_key_get
- (handle, connection_handle, "previous_query",
- strlen("previous_query"), previous_query, &datalen) == CS_OK) {
- if (confdb_key_get
- (handle, connection_handle, "query_handle",
- strlen("query_handle"), query_handle,
- &datalen) == CS_OK) {
- return 0;
- }
- }
- errno = ENOENT;
- return -1;
-}
-
-int set_previous_query(confdb_handle_t handle, hdb_handle_t connection_handle,
- const char *previous_query, hdb_handle_t query_handle)
-{
- char temp[PATH_MAX];
- size_t templen = 0;
- hdb_handle_t temphandle;
- unsigned int temptracker;
-
- if (confdb_key_get
- (handle, connection_handle, "previous_query",
- strlen("previous_query"), temp, &templen) == CS_OK) {
- if (strcmp(previous_query, temp)) {
- if (confdb_key_replace
- (handle, connection_handle, "previous_query",
- strlen("previous_query"), temp, templen,
- previous_query,
- strlen(previous_query) + 1) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
- } else {
- if (confdb_key_create_typed
- (handle, connection_handle, "previous_query",
- previous_query,
- strlen(previous_query) + 1, CONFDB_VALUETYPE_STRING) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
-
- if (confdb_key_get
- (handle, connection_handle, "query_handle", strlen("query_handle"),
- &temphandle, &templen) == CS_OK) {
- if (temphandle != query_handle) {
- if (confdb_key_replace
- (handle, connection_handle, "query_handle",
- strlen("query_handle"), &temphandle,
- sizeof(hdb_handle_t), &query_handle,
- sizeof(hdb_handle_t)) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
- } else {
- if (confdb_key_create_typed
- (handle, connection_handle, "query_handle",
- &query_handle,
- sizeof(hdb_handle_t), CONFDB_VALUETYPE_UINT64) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
-
- if (confdb_key_get
- (handle, connection_handle, "iterator_tracker",
- strlen("iterator_tracker"), &temptracker, &templen) != CS_OK) {
- temptracker = 1;
- if (confdb_key_create_typed
- (handle, connection_handle, "iterator_tracker",
- &temptracker, sizeof(unsigned int), CONFDB_VALUETYPE_UINT32) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
-
- return 0;
-}
-
-void reset_iterator(confdb_handle_t handle, hdb_handle_t connection_handle)
-{
- unsigned int value = 0;
-
- if (confdb_key_increment
- (handle, connection_handle, "iterator_tracker",
- strlen("iterator_tracker"), &value) != CS_OK)
- return;
-
- confdb_key_delete(handle, connection_handle, "iterator_tracker",
- strlen("iterator_tracker"), &value,
- sizeof(unsigned int));
-
- return;
-}
-
-static int check_cluster_name(int ccs_handle, const char *cluster_name)
-{
- confdb_handle_t handle = 0;
- hdb_handle_t cluster_handle;
- char data[128];
- int found = 0;
- size_t datalen = 0;
-
- handle = confdb_connect();
- if (handle == -1)
- return -1;
-
- if (confdb_object_find_start(handle, OBJECT_PARENT_HANDLE) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- while (confdb_object_find
- (handle, OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"),
- &cluster_handle) == CS_OK) {
- memset(data, 0, sizeof(data));
- if (confdb_key_get
- (handle, cluster_handle, "name", strlen("name"), data,
- &datalen) == CS_OK) {
- if (!strncmp(data, cluster_name, datalen)) {
- found = 1;
- break;
- }
- }
- }
-
- confdb_object_find_destroy(handle, OBJECT_PARENT_HANDLE);
-
- confdb_disconnect(handle);
-
- if (found) {
- return ccs_handle;
- } else {
- errno = ENOENT;
- return -1;
- }
-}
-
-/**
- * _ccs_get
- * @desc:
- * @query:
- * @rtn: value returned
- * @list: 1 to operate in list fashion
- *
- * This function will allocate space for the value that is the result
- * of the given query. It is the user's responsibility to ensure that
- * the data returned is freed.
- *
- * Returns: 0 on success, < 0 on failure
- */
-static int _ccs_get(int desc, const char *query, char **rtn, int list)
-{
- confdb_handle_t handle = 0;
- hdb_handle_t connection_handle = 0;
- char data[128];
- size_t datalen = 0;
- int fullxpathint = 0;
- int myerrno;
-
- *rtn = NULL;
-
- handle = confdb_connect();
- if (handle == -1)
- return -1;
-
- connection_handle = find_ccs_handle(handle, desc);
- if (connection_handle == -1)
- goto fail;
-
- memset(data, 0, sizeof(data));
- if (confdb_key_get
- (handle, connection_handle, "fullxpath", strlen("fullxpath"), &data,
- &datalen) != CS_OK) {
- errno = EINVAL;
- goto fail;
- } else
- fullxpathint = atoi(data);
-
- if (config_reload(handle, connection_handle, fullxpathint) < 0)
- goto fail;
-
- if (!fullxpathint)
- *rtn =
- _ccs_get_xpathlite(handle, connection_handle, query, list);
- else
- *rtn =
- _ccs_get_fullxpath(handle, connection_handle, query, list);
-
-fail:
- myerrno = errno;
-
- confdb_disconnect(handle);
-
- errno = myerrno;
- if (!*rtn)
- return -1;
-
- return 0;
-}
-
-/**** PUBLIC API ****/
-
-/**
- * ccs_connect
- *
- * Returns: ccs_desc on success, < 0 on failure
- */
-int ccs_connect(void)
-{
- confdb_handle_t handle = 0;
- int ccs_handle = 0;
- int myerrno;
-
- handle = confdb_connect();
- if (handle == -1)
- return handle;
-
- get_ccs_handle(handle, &ccs_handle, fullxpath);
- if (ccs_handle < 0)
- goto fail;
-
- if (fullxpath) {
- if (xpathfull_init(handle)) {
- ccs_disconnect(ccs_handle);
- return -1;
- }
- }
-
-fail:
- myerrno = errno;
-
- confdb_disconnect(handle);
-
- errno = myerrno;
-
- return ccs_handle;
-}
-
-/**
- * ccs_force_connect
- *
- * @cluster_name: verify that we are trying to connect to the requested cluster (tbd)
- * @blocking: retry connection forever
- *
- * Returns: ccs_desc on success, < 0 on failure
- */
-int ccs_force_connect(const char *cluster_name, int blocking)
-{
- int res = -1;
-
- if (blocking) {
- while (res < 0) {
- res = ccs_connect();
- if (res < 0)
- sleep(1);
- }
- } else {
- res = ccs_connect();
- if (res < 0)
- return res;
- }
- if (cluster_name)
- return check_cluster_name(res, cluster_name);
- else
- return res;
-}
-
-/**
- * ccs_disconnect
- *
- * @desc: the descriptor returned by ccs_connect
- *
- * Returns: 0 on success, < 0 on error
- */
-int ccs_disconnect(int desc)
-{
- confdb_handle_t handle = 0;
- hdb_handle_t connection_handle = 0;
- int ret;
- char data[128];
- size_t datalen = 0;
- int fullxpathint = 0;
- int myerrno;
-
- handle = confdb_connect();
- if (handle == -1)
- return handle;
-
- connection_handle = find_ccs_handle(handle, desc);
- if (connection_handle == -1) {
- ret = -1;
- goto fail;
- }
-
- memset(data, 0, sizeof(data));
- if (confdb_key_get
- (handle, connection_handle, "fullxpath", strlen("fullxpath"), &data,
- &datalen) != CS_OK) {
- errno = EINVAL;
- ret = -1;
- goto fail;
- } else
- fullxpathint = atoi(data);
-
- if (fullxpathint)
- xpathfull_finish();
-
- ret = destroy_ccs_handle(handle, connection_handle);
-
-fail:
- myerrno = errno;
- confdb_disconnect(handle);
- errno = myerrno;
- return ret;
-}
-
-/* see _ccs_get */
-int ccs_get(int desc, const char *query, char **rtn)
-{
- return _ccs_get(desc, query, rtn, 0);
-}
-
-/* see _ccs_get */
-int ccs_get_list(int desc, const char *query, char **rtn)
-{
- return _ccs_get(desc, query, rtn, 1);
-}
-
-/**
- * ccs_set: set an individual element's value in the config file.
- * @desc:
- * @path:
- * @val:
- *
- * This function is used to update individual elements in a config file.
- * It's effects are cluster wide. It only succeeds when the node is part
- * of a quorate cluster.
- *
- * Note currently implemented.
- *
- * Returns: 0 on success, < 0 on failure
- */
-int ccs_set(int desc, const char *path, char *val)
-{
- errno = ENOSYS;
- return -1;
-}
diff --git a/config/libs/libccsconfdb/libccs.pc.in b/config/libs/libccsconfdb/libccs.pc.in
deleted file mode 100644
index eddc87f..0000000
--- a/config/libs/libccsconfdb/libccs.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: libccs
-Version: @VERSION@
-Description: Cluster Config library
-Requires:
-Libs: -L${libdir} -lccs
-Cflags: -I${includedir}
diff --git a/config/libs/libccsconfdb/xpathlite.c b/config/libs/libccsconfdb/xpathlite.c
deleted file mode 100644
index 6ffbf63..0000000
--- a/config/libs/libccsconfdb/xpathlite.c
+++ /dev/null
@@ -1,454 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <corosync/corotypes.h>
-#include <corosync/confdb.h>
-
-#include "ccs.h"
-#include "ccs_internal.h"
-
-static int tokenizer(char *current_query)
-{
- int tokens = 0;
- char *curpos = current_query;
- char *next = NULL;
- char *end = NULL;
-
- end = current_query + strlen(current_query);
-
- while (curpos <= end) {
- tokens++;
-
- if (!curpos) {
- errno = EINVAL;
- return -1;
- }
-
- if (strncmp(curpos, "/", 1)) {
- errno = EINVAL;
- return -1;
- }
-
- memset(curpos, 0, 1);
- curpos = curpos + 1;
-
- next = strstr(curpos, "/");
- if (next == curpos) {
- errno = EINVAL;
- return -1;
- }
-
- if (!next)
- return tokens;
-
- if ((strstr(curpos, "[") > next) || !strstr(curpos, "[")) {
- curpos = next;
- } else {
- curpos = strstr(curpos, "]");
- if (!curpos) {
- errno = EINVAL;
- return -1;
- }
- curpos = strstr(curpos, "/");
- }
- }
- errno = EINVAL;
- return -1;
-}
-
-/*
- * return 0 on success
- * return -1 on errors
- */
-static int path_dive(confdb_handle_t handle, hdb_handle_t *query_handle,
- char *current_query, int tokens)
-{
- char *pos = NULL, *next = NULL;
- int i;
- hdb_handle_t new_obj_handle;
- confdb_value_types_t type;
-
- pos = current_query + 1;
-
- for (i = 1; i <= tokens; i++) {
- if (confdb_object_find_start(handle, *query_handle) !=
- CS_OK)
- goto fail;
-
- next = pos + strlen(pos) + 1;
-
- if (!strstr(pos, "[")) {
- /* straight path diving */
- if (confdb_object_find
- (handle, *query_handle, pos, strlen(pos),
- &new_obj_handle) != CS_OK)
- goto fail;
- else {
- confdb_object_find_destroy(handle,
- *query_handle);
- *query_handle = new_obj_handle;
- }
- } else {
- /*
- * /something[int]/ or /something[@foo="bar"]/
- * start and end will identify []
- * middle will point to the inside request
- */
-
- char *start = NULL, *middle = NULL, *end = NULL;
- char *key_value = NULL;
- size_t valuelen;
- char data[PATH_MAX];
- size_t datalen = 0;
-
- /*
- * those ones should be always good because
- * the tokenizer takes care of them
- */
-
- start = strstr(pos, "[");
- if (!start)
- goto fail;
-
- end = strstr(pos, "]");
- if (!end)
- goto fail;
-
- middle = start + 1;
- memset(start, 0, 1);
- memset(end, 0, 1);
-
- if (!strcmp(pos, "child::*")) {
- int val, j;
-
- val = atoi(middle);
-
- if (val < 1)
- goto fail;
-
- if (confdb_object_iter_start
- (handle, *query_handle) != CS_OK)
- goto fail;
-
- for (j = 1; j <= val; j++) {
- if (confdb_object_iter
- (handle, *query_handle,
- &new_obj_handle, data,
- &datalen) != CS_OK)
- goto fail;
- }
- confdb_object_iter_destroy(handle,
- *query_handle);
- confdb_object_find_destroy(handle,
- *query_handle);
- *query_handle = new_obj_handle;
-
- } else if (!strstr(middle, "@")) {
- /* lookup something with index num = int */
- int val, j;
-
- val = atoi(middle);
-
- if (val < 1)
- goto fail;
-
- for (j = 1; j <= val; j++) {
- if (confdb_object_find
- (handle, *query_handle, pos,
- strlen(pos),
- &new_obj_handle) != CS_OK)
- goto fail;
- }
- confdb_object_find_destroy(handle,
- *query_handle);
- *query_handle = new_obj_handle;
-
- } else {
- /* lookup something with obj foo = bar */
- char *equal = NULL, *value = NULL, *tmp = NULL;
- int goout = 0;
-
- equal = strstr(middle, "=");
- if (!equal)
- goto fail;
-
- memset(equal, 0, 1);
-
- value = strstr(equal + 1, "\"");
- if (!value)
- goto fail;
-
- value = value + 1;
-
- tmp = strstr(value, "\"");
- if (!tmp)
- goto fail;
-
- memset(tmp, 0, 1);
-
- middle = strstr(middle, "@") + 1;
- if (!middle)
- goto fail;
-
- // middle points to foo
- // value to bar
-
- memset(data, 0, PATH_MAX);
- while (!goout) {
- if (confdb_object_find
- (handle, *query_handle, pos,
- strlen(pos),
- &new_obj_handle) != CS_OK)
- goto fail;
- else {
- key_value = NULL;
- if (confdb_key_get_typed2
- (handle, new_obj_handle,
- middle,
- (void **) &key_value,
- &valuelen, &type) == CS_OK) {
- if (!strcmp
- (key_value, value))
- goout = 1;
- free(key_value);
- key_value = NULL;
- }
- }
- }
- free(key_value);
- key_value = NULL;
- confdb_object_find_destroy(handle,
- *query_handle);
- *query_handle = new_obj_handle;
- }
- }
-
- pos = next;
- }
-
- return 0;
-
-fail:
- errno = EINVAL;
- return -1;
-}
-
-static int get_data(confdb_handle_t handle, hdb_handle_t connection_handle,
- hdb_handle_t query_handle, hdb_handle_t *list_handle,
- char **rtn, char *curpos, int list, int is_oldlist)
-{
- int cmp;
- char data[PATH_MAX];
- char *resval;
- char *keyval;
- hdb_handle_t new_obj_handle;
- unsigned int value = 0;
- confdb_value_types_t type;
- size_t datalen = 0, keyvallen = PATH_MAX;
-
- memset(data, 0, PATH_MAX);
-
- // we need to handle child::*[int value] in non list mode.
- cmp = strcmp(curpos, "child::*");
- if (cmp >= 0) {
- char *start = NULL, *end = NULL;
-
- // a pure child::* request should come down as list
- if (!cmp && !list)
- goto fail;
-
- if (confdb_object_iter_start(handle, query_handle) != CS_OK)
- goto fail;
-
- if (!is_oldlist)
- *list_handle = query_handle;
-
- if (cmp) {
- start = strstr(curpos, "[");
- if (!start)
- goto fail;
-
- start = start + 1;
-
- end = strstr(start, "]");
- if (!end)
- goto fail;
-
- memset(end, 0, 1);
- value = atoi(start);
- if (value <= 0)
- goto fail;
- } else {
- if (confdb_key_increment
- (handle, connection_handle, "iterator_tracker",
- strlen("iterator_tracker"), &value) != CS_OK)
- value = 1;
- }
-
- while (value != 0) {
- memset(data, 0, PATH_MAX);
- if (confdb_object_iter
- (handle, query_handle, &new_obj_handle, data,
- &datalen) != CS_OK) {
- reset_iterator(handle, connection_handle);
- goto fail;
- }
-
- value--;
- }
-
- resval = malloc(datalen + 2);
- if (!resval)
- goto fail;
- snprintf(resval, datalen + 2, "%s=", data);
- *rtn = resval;
-
- } else if (!strncmp(curpos, "@*", strlen("@*"))) {
-
- // this query makes sense only if we are in list mode
- if (!list)
- goto fail;
-
- if (confdb_key_iter_start(handle, query_handle) != CS_OK)
- goto fail;
-
- *list_handle = query_handle;
-
- if (confdb_key_increment
- (handle, connection_handle, "iterator_tracker",
- strlen("iterator_tracker"), &value) != CS_OK)
- value = 1;
-
- while (value != 0) {
- memset(data, 0, PATH_MAX);
- keyval = NULL;
- if (confdb_key_iter_typed2
- (handle, query_handle, data, (void **)&keyval,
- &keyvallen, &type) != CS_OK) {
- reset_iterator(handle, connection_handle);
- goto fail;
- }
-
- value--;
- if (value != 0) {
- free(keyval);
- keyval = NULL;
- }
- }
- datalen = strlen(data);
- resval = malloc(datalen + keyvallen + 2);
- if (!resval)
- goto fail;
- snprintf(resval, datalen + keyvallen + 2, "%s=%s", data, keyval);
- *rtn = resval;
- free(keyval);
-
- } else { /* pure data request */
- char *query;
-
- // this query doesn't make sense in list mode
- if (list)
- goto fail;
-
- if (confdb_object_find_start(handle, query_handle) != CS_OK)
- goto fail;
-
- query = strstr(curpos, "@");
- if (!query)
- goto fail;
-
- query = query + 1;
-
- keyval = NULL;
- if (confdb_key_get_typed2
- (handle, query_handle, query, (void **)&keyval,
- &keyvallen, &type) != CS_OK)
- goto fail;
-
- *rtn = keyval;
- }
-
- return 0;
-
-fail:
- errno = EINVAL;
- return -1;
-}
-
-/**
- * _ccs_get_xpathlite
- * @handle:
- * @connection_handle:
- * @query:
- * @list: 1 to operate in list fashion
- *
- * This function will allocate space for the value that is the result
- * of the given query. It is the user's responsibility to ensure that
- * the data returned is freed.
- *
- * Returns: char * to result or NULL in case of failure.
- */
-char *_ccs_get_xpathlite(confdb_handle_t handle, hdb_handle_t connection_handle,
- const char *query, int list)
-{
- char current_query[PATH_MAX];
- char *datapos, *rtn = NULL;
- char previous_query[PATH_MAX];
- hdb_handle_t list_handle = 0;
- hdb_handle_t query_handle = 0;
- int prev = 0, is_oldlist = 0;
- int tokens, i;
-
- memset(current_query, 0, PATH_MAX);
- strncpy(current_query, query, PATH_MAX - 1);
-
- memset(previous_query, 0, PATH_MAX);
-
- datapos = current_query + 1;
-
- prev =
- get_previous_query(handle, connection_handle, previous_query,
- &list_handle);
-
- if (list && !prev && !strcmp(current_query, previous_query)) {
- query_handle = list_handle;
- is_oldlist = 1;
- } else {
- reset_iterator(handle, connection_handle);
- query_handle = OBJECT_PARENT_HANDLE;
- }
-
- if (confdb_object_find_start(handle, query_handle) != CS_OK) {
- errno = ENOENT;
- goto fail;
- }
-
- tokens = tokenizer(current_query);
- if (tokens < 1)
- goto fail;
-
- for (i = 1; i < tokens; i++)
- datapos = datapos + strlen(datapos) + 1;
-
- if (!is_oldlist)
- if (path_dive(handle, &query_handle, current_query, tokens - 1) < 0) /* path dive can mangle tokens */
- goto fail;
-
- if (get_data
- (handle, connection_handle, query_handle, &list_handle, &rtn,
- datapos, list, is_oldlist) < 0)
- goto fail;
-
- if (list)
- if (set_previous_query
- (handle, connection_handle, (char *)query, list_handle))
- goto fail;
-
- return rtn;
-
-fail:
- return NULL;
-}
diff --git a/config/man/Makefile b/config/man/Makefile
deleted file mode 100644
index 0c003af..0000000
--- a/config/man/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-MANTARGET= cluster.conf.5
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-all:
-
-clean:
diff --git a/config/man/cluster.conf.5 b/config/man/cluster.conf.5
deleted file mode 100644
index ad2cfee..0000000
--- a/config/man/cluster.conf.5
+++ /dev/null
@@ -1,237 +0,0 @@
-.TH CLUSTER.CONF 5 2010-01-12 cluster cluster
-
-.SH NAME
-cluster.conf \- configuration file for cman and related daemons
-
-.SH SYNOPSIS
-.B /etc/cluster/cluster.conf
-
-.SH DESCRIPTION
-When
-.BR cman_tool (8)
-starts the
-.BR corosync (8)
-daemon, the cluster.conf data is read into the corosync in-memory
-database (confdb). The configuration is used by corosync,
-cman and other related cluster daemons and programs. When cman
-configures corosync with cluster.conf, the
-.BR corosync.conf (5)
-file is not used.
-
-A basic cluster configuration is described below.
-Configuration options for other daemons/programs are described in
-their own man pages.
-.BR ccs_tool (8)
-can be used to do some basic cluster.conf editing.
-
-The cluster.rng schema is used to validate cluster.conf. Unrecognized
-items will produce a warning during cluster startup, and invalid xml
-structure will cause the cluster startup to fail. See
-.BR ccs_config_validate (8)
-and
-.BR ccs_config_dump (8).
-
-.SS Cluster
-The top level
-.B cluster
-section contains all other sections and has two required attributes:
-.TP 8
-.B name
-The name of the cluster can be up to 15 characters long (16 including
-terminating null). It is important that this name be unique among
-clusters on the same network.
-.TP 8
-.B config_version
-The config_version specifies the revision level of the file and should be
-increased each time the file is updated.
-.P
-.nf
-<cluster name="alpha" config_version="1">
-</cluster>
-.fi
-
-.SS Cluster Nodes
-The set of nodes that make up the cluster are defined in the
-.B clusternodes
-section which contains multiple
-.B clusternode
-sections. A clusternode has two required attributes:
-.TP 8
-.B name
-The node name should correspond to the hostname on the network interface
-to be used for cluster communication.
-.TP 8
-.B nodeid
-The node id must be greater than zero and unique.
-.P
-.nf
-<cluster name="alpha" config_version="1">
- <clusternodes>
- <clusternode name="node-01" nodeid="1">
- </clusternode>
-
- <clusternode name="node-02" nodeid="2">
- </clusternode>
-
- <clusternode name="node-03" nodeid="3">
- </clusternode>
- </clusternodes>
-</cluster>
-.fi
-
-.SS Logging
-Cluster daemons use a common
-.B logging
-section to configure their loggging behavior.
-.P
-.nf
-<cluster name="alpha" config_version="1">
- <logging/>
-</cluster>
-.fi
-.P
-
-Global settings apply to all:
-.P
-.nf
-<logging debug="on"/>
-.fi
-.P
-
-Per-daemon
-.B logging_daemon
-subsections override the global settings.
-Daemon names that can be configured include: corosync, qdiskd, groupd, fenced,
-dlm_controld, gfs_controld, rgmanager.
-.P
-.nf
-<logging>
- <logging_daemon name="qdiskd" debug="on"/>
- <logging_daemon name="fenced" debug="on"/>
-</logging>
-.fi
-.P
-
-Corosync daemon settings apply to all corosync subsystems by default, but
-subsystems can also be configured individually. These include CLM, CPG, MAIN,
-SERV, CMAN, TOTEM, QUORUM, CONFDB, CKPT, EVT.
-.P
-.nf
-<logging>
- <logging_daemon name="corosync" subsys="QUORUM" debug="on"/>
- <logging_daemon name="corosync" subsys="CONFDB" debug="on"/>
-</logging>
-.fi
-.P
-
-The attributes available at global, daemon and subsystem levels are:
-
-.TP 8
-.B to_syslog
-enable/disable messages to syslog (yes/no), default "yes"
-
-.TP 8
-.B to_logfile
-enable/disable messages to log file (yes/no), default "yes"
-
-.TP 8
-.B syslog_facility
-facility used for syslog messages, default "local4"
-
-.TP 8
-.B syslog_priority
-messages at this level and up will be sent to syslog, default "info"
-
-.TP 8
-.B logfile_priority
-messages at this level and up will be written to log file, default "info"
-
-.TP 8
-.B logfile "\ "
-the log file name, default /var/log/cluster/<daemon>.log
-
-.TP 8
-.B debug="on"
-a shortcut for logfile_priority="debug"
-
-.SH EXAMPLE
-An explicit configuration for the default settings would be:
-.P
-.nf
-<logging to_syslog="yes" to_logfile="yes" syslog_facility="local4"
- syslog_priority="info" logfile_priority="info">
- <logging_daemon name="qdiskd"
- logfile="/var/log/cluster/qdiskd.log"/>
- <logging_daemon name="fenced"
- logfile="/var/log/cluster/fenced.log"/>
- <logging_daemon name="dlm_controld"
- logfile="/var/log/cluster/dlm_controld.log"/>
- <logging_daemon name="gfs_controld"
- logfile="/var/log/cluster/gfs_controld.log"/>
- <logging_daemon name="rgmanager"
- logfile="/var/log/cluster/rgmanager.log"/>
- <logging_daemon name="corosync"
- logfile="/var/log/cluster/corosync.log"/>
-</logging>
-.fi
-.P
-
-To include debug messages (and above) from all daemons in their default
-log files, either of the following which are equivalent:
-.P
-.nf
-<logging debug="on"/>
-<logging logfile_priority="debug"/>
-.fi
-.P
-
-To exclude all log messages from syslog:
-.P
-.nf
-<logging to_syslog="no"/>
-.fi
-.P
-
-To disable logging to all log files:
-.P
-.nf
-<logging to_file="no"/>
-.fi
-.P
-
-To include debug messages (and above) from all daemons in syslog:
-.P
-.nf
-<logging syslog_priority="debug"/>
-.fi
-.P
-
-To limit syslog messages to error (and above), keeping info (and above) in
-log files (this logfile_priority setting is the default so could be omitted):
-.P
-.nf
-<logging syslog_priority="error" logfile_priority="info"/>
-.fi
-.P
-
-.SH FILES
-.TP
-.I /etc/cluster/cluster.conf
-standard location of cluster configuration file
-.TP
-.I /usr/share/cluster/cluster.rng
-standard location of cluster.conf schema
-
-.SH SEE ALSO
-.BR ccs_tool (8),
-.BR ccs_config_dump (8),
-.BR ccs_config_validate (8),
-.BR cman_tool (8),
-.BR cman (5),
-.BR qdisk (5),
-.BR fenced (8),
-.BR fence_node (8),
-.BR dlm_controld (8),
-.BR gfs_controld (8),
-.BR rgmanager (8)
-
diff --git a/config/plugins/Makefile b/config/plugins/Makefile
deleted file mode 100644
index d39b807..0000000
--- a/config/plugins/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS = xml ldap
diff --git a/config/plugins/ldap/99cluster.ldif b/config/plugins/ldap/99cluster.ldif
deleted file mode 100644
index 5ad8f71..0000000
--- a/config/plugins/ldap/99cluster.ldif
+++ /dev/null
@@ -1,1899 +0,0 @@
-# Auto-generated @ 2010-09-02 09:59:03
-dn: cn=schema
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.1 NAME 'rhcsConfig-version'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.5 NAME 'rhcsTwo-node'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.6 NAME 'rhcsExpected-votes'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.241 NAME 'rhcsUpgrading'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.242 NAME 'rhcsDisallowed'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.16 NAME 'rhcsQuorum-dev-poll'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.17 NAME 'rhcsShutdown-timeout'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.18 NAME 'rhcsCcsd-poll'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.19 NAME 'rhcsDebug-mask'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.13 NAME 'rhcsPort'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.3 NAME 'rhcsCluster-id'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.274 NAME 'rhcsHash-cluster-id'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.45 NAME 'rhcsNodename'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.228 NAME 'rhcsBroadcast'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.86 NAME 'rhcsKeyfile'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.229 NAME 'rhcsDisable-openais'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.20 NAME 'rhcsAddr'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.81 NAME 'rhcsConsensus'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.82 NAME 'rhcsJoin'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.8 NAME 'rhcsToken'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.278 NAME 'rhcsFail-recv-const'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.83 NAME 'rhcsToken-retransmits-before-loss-const'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.84 NAME 'rhcsRrp-mode'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.85 NAME 'rhcsSecauth'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.230 NAME 'rhcsRingnumber'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.231 NAME 'rhcsBindnetaddr'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.232 NAME 'rhcsMcastaddr'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.233 NAME 'rhcsMcastport'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.112 NAME 'rhcsInterval'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.113 NAME 'rhcsTko'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.4 NAME 'rhcsVotes'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.114 NAME 'rhcsMin-score'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.39 NAME 'rhcsDevice'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.115 NAME 'rhcsLabel'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.280 NAME 'rhcsCman-label'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.116 NAME 'rhcsStatus-file'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.117 NAME 'rhcsScheduler'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.118 NAME 'rhcsReboot'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.96 NAME 'rhcsPriority'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.119 NAME 'rhcsStop-cman'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.120 NAME 'rhcsParanoid'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.121 NAME 'rhcsAllow-kill'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.122 NAME 'rhcsMax-error-cycles'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.243 NAME 'rhcsIo-timeout'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.244 NAME 'rhcsMaster-wins'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.124 NAME 'rhcsScore'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.123 NAME 'rhcsProgram'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.107 NAME 'rhcsPost-join-delay'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.108 NAME 'rhcsPost-fail-delay'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.109 NAME 'rhcsOverride-path'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.110 NAME 'rhcsOverride-time'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.111 NAME 'rhcsClean-start'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.239 NAME 'rhcsSkip-undefined'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.62 NAME 'rhcsDebug'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.70 NAME 'rhcsUse-uuid'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.64 NAME 'rhcsMulticast-address'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.43 NAME 'rhcsAuth'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.67 NAME 'rhcsHash'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.72 NAME 'rhcsUri'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.68 NAME 'rhcsKey-file'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.73 NAME 'rhcsMulticast-interface'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.23 NAME 'rhcsLog-debug'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.24 NAME 'rhcsTimewarn'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.25 NAME 'rhcsProtocol'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.26 NAME 'rhcsEnable-fencing'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.27 NAME 'rhcsEnable-quorum'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.28 NAME 'rhcsEnable-deadlk'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.29 NAME 'rhcsEnable-plock'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.30 NAME 'rhcsPlock-debug'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.31 NAME 'rhcsPlock-rate-limit'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.32 NAME 'rhcsPlock-ownership'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.33 NAME 'rhcsDrop-resources-time'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.34 NAME 'rhcsDrop-resources-count'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.35 NAME 'rhcsDrop-resources-age'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.37 NAME 'rhcsNodir'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.21 NAME 'rhcsWeight'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.36 NAME 'rhcsEnable-withdraw'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.38 NAME 'rhcsGroupd-compat'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.74 NAME 'rhcsTo-syslog'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.75 NAME 'rhcsTo-logfile'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.76 NAME 'rhcsSyslog-facility'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.77 NAME 'rhcsSyslog-priority'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.79 NAME 'rhcsLogfile-priority'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.78 NAME 'rhcsLogfile'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.80 NAME 'rhcsSubsys'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.2 NAME 'rhcsNodeid'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.22 NAME 'rhcsMcast'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.12 NAME 'rhcsIpaddr'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.40 NAME 'rhcsLogin'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.41 NAME 'rhcsPasswd'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.42 NAME 'rhcsPasswd-script'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.44 NAME 'rhcsLanplus'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.267 NAME 'rhcsKey'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.268 NAME 'rhcsDevices'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.50 NAME 'rhcsAction'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.269 NAME 'rhcsAptpl'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.47 NAME 'rhcsServers'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.48 NAME 'rhcsCserver'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.226 NAME 'rhcsPserver'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.225 NAME 'rhcsLpan'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.288 NAME 'rhcsEsh'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.219 NAME 'rhcsUser'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.286 NAME 'rhcsDelay'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.49 NAME 'rhcsRpowerpath'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.51 NAME 'rhcsOption'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.63 NAME 'rhcsIp-family'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.252 NAME 'rhcsIpport'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.66 NAME 'rhcsRetrans'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.69 NAME 'rhcsDomain'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.71 NAME 'rhcsTimeout'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.270 NAME 'rhcsSerial-device'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.271 NAME 'rhcsSerial-params'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.272 NAME 'rhcsChannel-address'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.289 NAME 'rhcsQuiet'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.59 NAME 'rhcsExec'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.60 NAME 'rhcsVmware-type'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.52 NAME 'rhcsSecure'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.55 NAME 'rhcsIdentity-file'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.61 NAME 'rhcsVmware-datacenter'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.53 NAME 'rhcsVerbose'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.245 NAME 'rhcsVersion'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.246 NAME 'rhcsHelp'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.247 NAME 'rhcsSeparator'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.281 NAME 'rhcsPower-timeout'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.282 NAME 'rhcsShell-timeout'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.283 NAME 'rhcsLogin-timeout'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.284 NAME 'rhcsPower-wait'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.285 NAME 'rhcsRetry-on'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.57 NAME 'rhcsPartition'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.58 NAME 'rhcsManaged'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.248 NAME 'rhcsHmc-version'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.249 NAME 'rhcsCmd-prompt'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.250 NAME 'rhcsInet4-only'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.251 NAME 'rhcsInet6-only'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.287 NAME 'rhcsMissing-as-off'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.253 NAME 'rhcsSnmp-version'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.254 NAME 'rhcsCommunity'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.255 NAME 'rhcsSnmp-auth-prot'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.256 NAME 'rhcsSnmp-sec-level'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.257 NAME 'rhcsSnmp-priv-prot'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.258 NAME 'rhcsSnmp-priv-passwd'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.259 NAME 'rhcsSnmp-priv-passwd-script'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.260 NAME 'rhcsUdpport'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.263 NAME 'rhcsDrac-version'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.264 NAME 'rhcsModule-name'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.54 NAME 'rhcsSwitch'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.265 NAME 'rhcsIo-fencing'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.56 NAME 'rhcsSsl'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.266 NAME 'rhcsRibcl'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.9 NAME 'rhcsAgent'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.87 NAME 'rhcsLog-level'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.88 NAME 'rhcsStatus-child-max'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.89 NAME 'rhcsStatus-poll-interval'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.90 NAME 'rhcsTransition-throttling'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.91 NAME 'rhcsCentral-processing'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.92 NAME 'rhcsLog-facility'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.93 NAME 'rhcsOrdered'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.94 NAME 'rhcsRestricted'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.95 NAME 'rhcsNofailback'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.97 NAME 'rhcsFile'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.98 NAME 'rhcsClass'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.99 NAME 'rhcsService'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.100 NAME 'rhcsService-state'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.101 NAME 'rhcsService-owner'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.102 NAME 'rhcsNode'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.103 NAME 'rhcsNode-id'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.104 NAME 'rhcsNode-state'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.105 NAME 'rhcsNode-clean'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.106 NAME 'rhcsNode-local'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.273 NAME 'rhcsInterface'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.125 NAME 'rhcsRef'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.126 NAME 'rhcsAutostart'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.128 NAME 'rhcsExclusive'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.129 NAME 'rhcsNfslock'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.130 NAME 'rhcsNfs-client-cache'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.131 NAME 'rhcsRecovery'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.132 NAME 'rhcsDepend'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.133 NAME 'rhcsDepend-mode'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.134 NAME 'rhcsMax-restarts'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.135 NAME 'rhcsRestart-expire-time'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.136 NAME 'rhcs--independent-subtree'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.137 NAME 'rhcs--enforce-timeouts'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.275 NAME 'rhcs--max-failures'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.276 NAME 'rhcs--failure-expire-time'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.138 NAME 'rhcsAddress'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.139 NAME 'rhcsFamily'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.140 NAME 'rhcsMonitor-link'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.141 NAME 'rhcsSleeptime'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.142 NAME 'rhcsTarget'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.143 NAME 'rhcsPath'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.144 NAME 'rhcsSvcname'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.145 NAME 'rhcsFsid'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.146 NAME 'rhcsOptions'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.147 NAME 'rhcsAllow-recover'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.148 NAME 'rhcsService-name'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.149 NAME 'rhcsUse-cache'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.150 NAME 'rhcsMountpoint'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.151 NAME 'rhcsHost'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.152 NAME 'rhcsExport'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.153 NAME 'rhcsFstype'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.154 NAME 'rhcsNo-unmount'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.155 NAME 'rhcsForce-unmount'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.156 NAME 'rhcsSelf-fence'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.157 NAME 'rhcsWorkgroup'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.158 NAME 'rhcsServer-root'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.159 NAME 'rhcsConfig-file'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.160 NAME 'rhcsHttpd-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.161 NAME 'rhcsShutdown-wait'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.162 NAME 'rhcsUrl-list'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.163 NAME 'rhcsSlapd-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.164 NAME 'rhcsSmbd-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.165 NAME 'rhcsNmbd-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.166 NAME 'rhcsListen-address'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.167 NAME 'rhcsMysqld-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.168 NAME 'rhcsStartup-wait'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.169 NAME 'rhcsPostmaster-user'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.170 NAME 'rhcsPostmaster-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.171 NAME 'rhcsTomcat-user'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.172 NAME 'rhcsCatalina-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.173 NAME 'rhcsCatalina-base'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.174 NAME 'rhcsVg-name'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.175 NAME 'rhcsLv-name'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.177 NAME 'rhcsMigration-mapping'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.234 NAME 'rhcsUse-virsh'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.235 NAME 'rhcsXmlfile'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.184 NAME 'rhcsMigrate'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.185 NAME 'rhcsSnapshot'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.277 NAME 'rhcsStatus-program'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.236 NAME 'rhcsHypervisor'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.237 NAME 'rhcsHypervisor-uri'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.238 NAME 'rhcsMigration-uri'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.186 NAME 'rhcsInstanceName'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.187 NAME 'rhcsDIR-EXECUTABLE'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.188 NAME 'rhcsDIR-PROFILE'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.189 NAME 'rhcsSTART-PROFILE'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.190 NAME 'rhcsSTART-WAITTIME'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.191 NAME 'rhcsAUTOMATIC-RECOVER'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.192 NAME 'rhcsPRE-START-USEREXIT'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.193 NAME 'rhcsPOST-START-USEREXIT'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.194 NAME 'rhcsPRE-STOP-USEREXIT'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.195 NAME 'rhcsPOST-STOP-USEREXIT'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.196 NAME 'rhcsSID'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.197 NAME 'rhcsDBTYPE'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.198 NAME 'rhcsNETSERVICENAME'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.199 NAME 'rhcsDBJ2EE-ONLY'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.200 NAME 'rhcsJAVA-HOME'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.201 NAME 'rhcsSTRICT-MONITORING'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.202 NAME 'rhcsDIR-BOOTSTRAP'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.203 NAME 'rhcsDIR-SECSTORE'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.204 NAME 'rhcsDB-JARS'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.205 NAME 'rhcsNamed-sdb'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.206 NAME 'rhcsNamed-working-dir'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.207 NAME 'rhcsNamed-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.208 NAME 'rhcsSybase-home'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.209 NAME 'rhcsSybase-ase'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.210 NAME 'rhcsSybase-ocs'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.211 NAME 'rhcsServer-name'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.212 NAME 'rhcsLogin-file'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.213 NAME 'rhcsInterfaces-file'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.214 NAME 'rhcsSybase-user'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.215 NAME 'rhcsStart-timeout'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.216 NAME 'rhcsDeep-probe-timeout'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.240 NAME 'rhcsResource'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.279 NAME 'rhcsNfspath'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.227 NAME 'rhcsQuick-status'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.217 NAME 'rhcsForce-fsck'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.218 NAME 'rhcsListener-name'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.220 NAME 'rhcsHome'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.221 NAME 'rhcsType'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.222 NAME 'rhcsVhost'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.223 NAME 'rhcsDepth'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.1 NAME 'rhcsCluster' SUP top STRUCTURAL
- MUST ( rhcsConfig-version $ name )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.3 NAME 'rhcsCman' SUP top STRUCTURAL
- MUST ( cn )
- MAY ( rhcsDisable-openais $ rhcsKeyfile $ rhcsBroadcast $ rhcsNodename $ rhcsHash-cluster-id $ rhcsCluster-id $ rhcsPort $ rhcsDebug-mask $ rhcsCcsd-poll $ rhcsShutdown-timeout $ rhcsQuorum-dev-poll $ rhcsDisallowed $ rhcsUpgrading $ rhcsExpected-votes $ rhcsTwo-node )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.8 NAME 'rhcsMulticast' SUP top STRUCTURAL
- MUST ( rhcsAddr )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.4 NAME 'rhcsTotem' SUP top STRUCTURAL
- MUST ( cn )
- MAY ( rhcsKeyfile $ rhcsSecauth $ rhcsRrp-mode $ rhcsToken-retransmits-before-loss-const $ rhcsFail-recv-const $ rhcsToken $ rhcsJoin $ rhcsConsensus )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.56 NAME 'rhcsInterface' SUP top STRUCTURAL
- MAY ( rhcsBroadcast $ rhcsMcastport $ rhcsMcastaddr $ rhcsBindnetaddr $ rhcsRingnumber )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.29 NAME 'rhcsQuorumd' SUP top STRUCTURAL
- MUST ( cn )
- MAY ( rhcsMaster-wins $ rhcsIo-timeout $ rhcsMax-error-cycles $ rhcsAllow-kill $ rhcsParanoid $ rhcsStop-cman $ rhcsPriority $ rhcsReboot $ rhcsScheduler $ rhcsStatus-file $ rhcsCman-label $ rhcsLabel $ rhcsDevice $ rhcsMin-score $ rhcsVotes $ rhcsTko $ rhcsInterval )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.30 NAME 'rhcsHeuristic' SUP top STRUCTURAL
- MUST ( rhcsProgram )
- MAY ( rhcsTko $ rhcsInterval $ rhcsScore )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.28 NAME 'rhcsFence-daemon' SUP top STRUCTURAL
- MAY ( rhcsSkip-undefined $ rhcsClean-start $ rhcsOverride-time $ rhcsOverride-path $ rhcsPost-fail-delay $ rhcsPost-join-delay )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.18 NAME 'rhcsFence-xvmd' SUP top STRUCTURAL
- MAY ( rhcsMulticast-interface $ rhcsKey-file $ rhcsUri $ rhcsHash $ rhcsAuth $ rhcsMulticast-address $ rhcsUse-uuid $ rhcsPort $ rhcsDebug )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.12 NAME 'rhcsDlm' SUP top STRUCTURAL
- MUST ( cn )
- MAY ( rhcsDrop-resources-age $ rhcsDrop-resources-count $ rhcsDrop-resources-time $ rhcsPlock-ownership $ rhcsPlock-rate-limit $ rhcsPlock-debug $ rhcsEnable-plock $ rhcsEnable-deadlk $ rhcsEnable-quorum $ rhcsEnable-fencing $ rhcsProtocol $ rhcsTimewarn $ rhcsLog-debug )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.14 NAME 'rhcsLockspace' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsNodir )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.15 NAME 'rhcsMaster' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsWeight )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.13 NAME 'rhcsGfs-controld' SUP top STRUCTURAL
- MAY ( rhcsDrop-resources-age $ rhcsDrop-resources-count $ rhcsDrop-resources-time $ rhcsPlock-ownership $ rhcsPlock-rate-limit $ rhcsPlock-debug $ rhcsEnable-plock $ rhcsEnable-withdraw )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.16 NAME 'rhcsGroup' SUP top STRUCTURAL
- MAY ( rhcsGroupd-compat )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.19 NAME 'rhcsLogging' SUP top STRUCTURAL
- MUST ( cn )
- MAY ( rhcsDebug $ rhcsLogfile $ rhcsLogfile-priority $ rhcsSyslog-priority $ rhcsSyslog-facility $ rhcsTo-logfile $ rhcsTo-syslog )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.57 NAME 'rhcsLogging-daemon' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsDebug $ rhcsLogfile $ rhcsLogfile-priority $ rhcsSyslog-priority $ rhcsSyslog-facility $ rhcsTo-logfile $ rhcsTo-syslog $ rhcsSubsys )
- )
-### Placeholder for rhcsClusternodes
-### This object class currently has no attributes
-#objectClasses: (
-# 1.3.6.1.4.1.2312.8.1.2.9 NAME 'rhcsClusternodes' SUP top STRUCTURAL
-# MUST ( cn )
-# )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.10 NAME 'rhcsClusternode' SUP top STRUCTURAL
- MUST ( rhcsNodeid $ name )
- MAY ( rhcsWeight $ rhcsVotes )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.11 NAME 'rhcsAltname' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsMcast $ rhcsPort )
- )
-### Placeholder for rhcsFencedevices
-### This object class currently has no attributes
-#objectClasses: (
-# 1.3.6.1.4.1.2312.8.1.2.17 NAME 'rhcsFencedevices' SUP top STRUCTURAL
-# MUST ( cn )
-# )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.5 NAME 'rhcsFencedevice' SUP top STRUCTURAL
- MUST ( rhcsAgent $ name )
- MAY ( rhcsRibcl $ rhcsSsl $ rhcsIo-fencing $ rhcsSwitch $ rhcsModule-name $ rhcsDrac-version $ rhcsUdpport $ rhcsSnmp-priv-passwd-script $ rhcsSnmp-priv-passwd $ rhcsSnmp-priv-prot $ rhcsSnmp-sec-level $ rhcsSnmp-auth-prot $ rhcsCommunity $ rhcsSnmp-version $ rhcsMissing-as-off $ rhcsInet6-only $ rhcsInet4-only $ rhcsCmd-prompt $ rhcsHmc-version $ rhcsManaged $ rhcsPartition $ rhcsRetry-on $ rhcsPower-wait $ rhcsLogin-timeout $ rhcsShell-timeout $ rhcsPower-timeout $ rhcsSeparator $ rhcsHelp $ rhcsVersion $ rhcsVerbose $ rhcsVmware-datacenter $ rhcsIdentity-file $ rhcsSecure $ rhcsVmware-type $ rhcsExec $ rhcsQuiet $ rhcsChannel-address $ rhcsSerial-params $ rhcsSerial-device $ rhcsTimeout $ rhcsUse-uuid $ rhcsDomain $ rhcsKey-file $ rhcsHash $ rhcsRetrans $ rhcsIpport $ rhcsMulticast-address $ rhcsIp-family $ rhcsDebug $ rhcsOption $ rhcsRpowerpath $ rhcsDelay $ rhcsUser $ rhcsEsh $ rhcsLpan $ rhcsPserver $ rhcsCserver $ rhcsServers $ rhcsAptpl $ rhcsLogfile $ rhcsActi
on $ rhcsDevices $ rhcsKey $ rhcsNodename $ rhcsLanplus $ rhcsAuth $ rhcsPasswd-script $ rhcsPasswd $ rhcsLogin $ rhcsIpaddr $ rhcsPort $ rhcsDevice )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.21 NAME 'rhcsRm' SUP top STRUCTURAL
- MUST ( cn )
- MAY ( rhcsLog-facility $ rhcsCentral-processing $ rhcsTransition-throttling $ rhcsStatus-poll-interval $ rhcsStatus-child-max $ rhcsLog-level )
- )
-### Placeholder for rhcsFailoverdomains
-### This object class currently has no attributes
-#objectClasses: (
-# 1.3.6.1.4.1.2312.8.1.2.22 NAME 'rhcsFailoverdomains' SUP top STRUCTURAL
-# MUST ( cn )
-# )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.23 NAME 'rhcsFailoverdomain' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsNofailback $ rhcsRestricted $ rhcsOrdered )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.24 NAME 'rhcsFailoverdomainnode' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsPriority )
- )
-### Placeholder for rhcsEvents
-### This object class currently has no attributes
-#objectClasses: (
-# 1.3.6.1.4.1.2312.8.1.2.25 NAME 'rhcsEvents' SUP top STRUCTURAL
-# MUST ( cn )
-# )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.26 NAME 'rhcsEvent' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsNode-local $ rhcsNode-clean $ rhcsNode-state $ rhcsNode-id $ rhcsNode $ rhcsService-owner $ rhcsService-state $ rhcsService $ rhcsClass $ rhcsPriority $ rhcsFile )
- )
-### Placeholder for rhcsResources
-### This object class currently has no attributes
-#objectClasses: (
-# 1.3.6.1.4.1.2312.8.1.2.27 NAME 'rhcsResources' SUP top STRUCTURAL
-# )
-### Placeholder for rhcsResource-defaults
-### This object class currently has no attributes
-#objectClasses: (
-# 1.3.6.1.4.1.2312.8.1.2.62 NAME 'rhcsResource-defaults' SUP top STRUCTURAL
-# )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.59 NAME 'rhcsClvmd' SUP top STRUCTURAL
- MAY ( rhcsInterface )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.31 NAME 'rhcsService' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsPriority $ rhcsRestart-expire-time $ rhcsMax-restarts $ rhcsDepend-mode $ rhcsDepend $ rhcsRecovery $ rhcsNfs-client-cache $ rhcsNfslock $ rhcsExclusive $ rhcsAutostart $ rhcsDomain $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.32 NAME 'rhcsIp' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsSleeptime $ rhcsNfslock $ rhcsMonitor-link $ rhcsFamily $ rhcsAddress $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.33 NAME 'rhcsNfsclient' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsUse-cache $ rhcsService-name $ rhcsAllow-recover $ rhcsOptions $ rhcsFsid $ rhcsSvcname $ rhcsPath $ rhcsTarget $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.34 NAME 'rhcsNfsexport' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsFsid $ rhcsPath $ rhcsDevice $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.35 NAME 'rhcsScript' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsFile $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.36 NAME 'rhcsNetfs' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsOptions $ rhcsForce-unmount $ rhcsNo-unmount $ rhcsFstype $ rhcsExport $ rhcsHost $ rhcsMountpoint $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.37 NAME 'rhcsClusterfs' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsNfslock $ rhcsFsid $ rhcsSelf-fence $ rhcsOptions $ rhcsForce-unmount $ rhcsFstype $ rhcsDevice $ rhcsMountpoint $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.38 NAME 'rhcsSmb' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsWorkgroup $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.39 NAME 'rhcsApache' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsShutdown-wait $ rhcsHttpd-options $ rhcsConfig-file $ rhcsServer-root $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.40 NAME 'rhcsOpenldap' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsShutdown-wait $ rhcsSlapd-options $ rhcsUrl-list $ rhcsConfig-file $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.41 NAME 'rhcsSamba' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsShutdown-wait $ rhcsNmbd-options $ rhcsSmbd-options $ rhcsConfig-file $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.42 NAME 'rhcsMysql' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsShutdown-wait $ rhcsStartup-wait $ rhcsMysqld-options $ rhcsListen-address $ rhcsConfig-file $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.43 NAME 'rhcsPostgres-8' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsShutdown-wait $ rhcsPostmaster-options $ rhcsPostmaster-user $ rhcsConfig-file $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.44 NAME 'rhcsTomcat-5' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsShutdown-wait $ rhcsCatalina-base $ rhcsCatalina-options $ rhcsTomcat-user $ rhcsConfig-file $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.61 NAME 'rhcsTomcat-6' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsShutdown-wait $ rhcsConfig-file $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.45 NAME 'rhcsLvm' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsNfslock $ rhcsSelf-fence $ rhcsLv-name $ rhcsVg-name $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.46 NAME 'rhcsVm' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsMigration-uri $ rhcsHypervisor-uri $ rhcsHypervisor $ rhcsStatus-program $ rhcsRestart-expire-time $ rhcsMax-restarts $ rhcsDepend-mode $ rhcsDepend $ rhcsSnapshot $ rhcsPath $ rhcsMigrate $ rhcsXmlfile $ rhcsUse-virsh $ rhcsMigration-mapping $ rhcsRecovery $ rhcsExclusive $ rhcsAutostart $ rhcsDomain $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.47 NAME 'rhcsSAPInstance' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsPOST-STOP-USEREXIT $ rhcsPRE-STOP-USEREXIT $ rhcsPOST-START-USEREXIT $ rhcsPRE-START-USEREXIT $ rhcsAUTOMATIC-RECOVER $ rhcsSTART-WAITTIME $ rhcsSTART-PROFILE $ rhcsDIR-PROFILE $ rhcsDIR-EXECUTABLE $ rhcsInstanceName $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.48 NAME 'rhcsSAPDatabase' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsPOST-STOP-USEREXIT $ rhcsPRE-STOP-USEREXIT $ rhcsPOST-START-USEREXIT $ rhcsPRE-START-USEREXIT $ rhcsDB-JARS $ rhcsDIR-SECSTORE $ rhcsDIR-BOOTSTRAP $ rhcsAUTOMATIC-RECOVER $ rhcsSTRICT-MONITORING $ rhcsJAVA-HOME $ rhcsDBJ2EE-ONLY $ rhcsNETSERVICENAME $ rhcsDBTYPE $ rhcsDIR-EXECUTABLE $ rhcsSID $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.49 NAME 'rhcsNamed' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsShutdown-wait $ rhcsNamed-options $ rhcsNamed-working-dir $ rhcsNamed-sdb $ rhcsConfig-file $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.50 NAME 'rhcsASEHAagent' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsDeep-probe-timeout $ rhcsStart-timeout $ rhcsShutdown-timeout $ rhcsSybase-user $ rhcsInterfaces-file $ rhcsLogin-file $ rhcsServer-name $ rhcsSybase-ocs $ rhcsSybase-ase $ rhcsSybase-home $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.58 NAME 'rhcsDrbd' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsResource $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.60 NAME 'rhcsNfsserver' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsNfspath $ rhcsPath $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.51 NAME 'rhcsFs' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsOptions $ rhcsForce-fsck $ rhcsFsid $ rhcsNfslock $ rhcsSelf-fence $ rhcsQuick-status $ rhcsForce-unmount $ rhcsFstype $ rhcsDevice $ rhcsMountpoint $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.52 NAME 'rhcsOracledb' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsVhost $ rhcsType $ rhcsHome $ rhcsUser $ rhcsListener-name $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.53 NAME 'rhcsAction' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsTimeout $ rhcsInterval $ rhcsDepth )
- )
-### Placeholder for rhcsFence
-### This object class currently has no attributes
-#objectClasses: (
-# 1.3.6.1.4.1.2312.8.1.2.54 NAME 'rhcsFence' SUP top STRUCTURAL
-# MUST ( cn )
-# )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.7 NAME 'rhcsMethod' SUP top STRUCTURAL
- MUST ( name )
- )
-### Placeholder for rhcsUnfence
-### This object class currently has no attributes
-#objectClasses: (
-# 1.3.6.1.4.1.2312.8.1.2.55 NAME 'rhcsUnfence' SUP top STRUCTURAL
-# )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.6 NAME 'rhcsDevice' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsRibcl $ rhcsSsl $ rhcsIo-fencing $ rhcsSwitch $ rhcsModule-name $ rhcsDrac-version $ rhcsUdpport $ rhcsSnmp-priv-passwd-script $ rhcsSnmp-priv-passwd $ rhcsSnmp-priv-prot $ rhcsSnmp-sec-level $ rhcsSnmp-auth-prot $ rhcsCommunity $ rhcsSnmp-version $ rhcsMissing-as-off $ rhcsInet6-only $ rhcsInet4-only $ rhcsCmd-prompt $ rhcsHmc-version $ rhcsManaged $ rhcsPartition $ rhcsRetry-on $ rhcsPower-wait $ rhcsLogin-timeout $ rhcsShell-timeout $ rhcsPower-timeout $ rhcsSeparator $ rhcsHelp $ rhcsVersion $ rhcsVerbose $ rhcsVmware-datacenter $ rhcsIdentity-file $ rhcsSecure $ rhcsVmware-type $ rhcsExec $ rhcsQuiet $ rhcsChannel-address $ rhcsSerial-params $ rhcsSerial-device $ rhcsTimeout $ rhcsUse-uuid $ rhcsDomain $ rhcsKey-file $ rhcsHash $ rhcsRetrans $ rhcsIpport $ rhcsMulticast-address $ rhcsIp-family $ rhcsDebug $ rhcsOption $ rhcsRpowerpath $ rhcsDelay $ rhcsUser $ rhcsEsh $ rhcsLpan $ rhcsPserver $ rhcsCserver $ rhcsServers $ rhcsAptpl $ rhcsLogfile $ rhcsActi
on $ rhcsDevices $ rhcsKey $ rhcsNodename $ rhcsLanplus $ rhcsAuth $ rhcsPasswd-script $ rhcsPasswd $ rhcsLogin $ rhcsIpaddr $ rhcsPort $ rhcsDevice )
- )
diff --git a/config/plugins/ldap/Makefile b/config/plugins/ldap/Makefile
deleted file mode 100644
index c8621ad..0000000
--- a/config/plugins/ldap/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-TARGET= config_ldap.lcrso
-
-LCRSOT=$(TARGET)
-
-DOCS = 99cluster.ldif \
- example.ldif
-
-all: ${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
-
-CFLAGS += -fPIC
-CFLAGS += -I${ldapincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${ldaplibdir} -lldap
-LDFLAGS += -L${libdir}
-
-OBJS= configldap.o
-
-${TARGET}: ${OBJS}
- $(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
-
-clean: generalclean
-
--include $(OBJS:.o=.Tpo)
diff --git a/config/plugins/ldap/configldap.c b/config/plugins/ldap/configldap.c
deleted file mode 100644
index c9ba2bf..0000000
--- a/config/plugins/ldap/configldap.c
+++ /dev/null
@@ -1,295 +0,0 @@
-#include <sys/types.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <arpa/inet.h>
-
-// CC: temp until I tame SASL ... is this necessary?
-#define LDAP_DEPRECATED 1
-#include <ldap.h>
-
-/* corosync headers */
-#include <corosync/lcr/lcr_comp.h>
-#include <corosync/engine/objdb.h>
-#include <corosync/engine/config.h>
-
-/* These are defaults. they can be overridden with environment variables
- * COROSYNC_LDAP_URL & COROSYNC_LDAP_BASEDN
- */
-#define DEFAULT_LDAP_URL "ldap:///"
-#define DEFAULT_LDAP_BASEDN "dc=chrissie,dc=net"
-
-static int ldap_readconfig(struct objdb_iface_ver0 *objdb, const char **error_string);
-static int ldap_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, const char **error_string);
-static int init_config(struct objdb_iface_ver0 *objdb);
-static char error_reason[1024];
-static const char *ldap_url = DEFAULT_LDAP_URL;
-static const char *ldap_basedn = DEFAULT_LDAP_BASEDN;
-
-/*
- * Exports the interface for the service
- */
-
-static struct config_iface_ver0 ldapconfig_iface_ver0 = {
- .config_readconfig = ldap_readconfig,
- .config_reloadconfig = ldap_reloadconfig
-};
-
-static struct lcr_iface ifaces_ver0[2] = {
- {
- .name = "ldapconfig",
- .version = 0,
- .versions_replace = 0,
- .versions_replace_count = 0,
- .dependencies = 0,
- .dependency_count = 0,
- .constructor = NULL,
- .destructor = NULL,
- .interfaces = NULL,
- }
-};
-
-static struct lcr_comp ldap_comp_ver0 = {
- .iface_count = 1,
- .ifaces = ifaces_ver0,
-};
-
-
-
-__attribute__ ((constructor)) static void ldap_comp_register(void) {
- lcr_interfaces_set(&ifaces_ver0[0], &ldapconfig_iface_ver0);
- lcr_component_register(&ldap_comp_ver0);
-};
-
-static int ldap_readconfig(struct objdb_iface_ver0 *objdb, const char **error_string)
-{
- int ret;
-
- /* Read config tree from LDAP */
- if (!(ret = init_config(objdb)))
- snprintf(error_reason, sizeof(error_reason), "%s", "Successfully read config from LDAP\n");
-
- *error_string = error_reason;
-
- return ret;
-}
-
-static int ldap_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, const char **error_string)
-{
- return ldap_readconfig(objdb, error_string);
-}
-
-/*
- * Convert hyphens to underscores in all attribute names
- */
-static void convert_underscores(char *s, int len)
-{
- int j;
-
- for (j=0; j < len; j++) {
- if (s[j] == '-')
- s[j] = '_';
- }
-}
-
-static void convert_dn_underscores(LDAPDN dn)
-{
- int i=0;
-
- while (dn[i]) {
- convert_underscores(dn[i][0][0].la_attr.bv_val, dn[i][0][0].la_attr.bv_len);
- i++;
- }
-}
-
-/*
- * Return the parent object of a DN.
- * Actually, this returns the LAST parent with that name. which should (!) be correct.
- */
-static hdb_handle_t find_parent(struct objdb_iface_ver0 *objdb, LDAPDN dn, int startdn, const char *parent)
-{
- int i=startdn;
- int gotstart=0;
- int start=0, end=startdn;
- hdb_handle_t parent_handle = OBJECT_PARENT_HANDLE;
- hdb_handle_t object_handle=0;
- hdb_handle_t find_handle;
-
- /*
- * Find the start and end positions first.
- * start is where the 'parent' entry is.
- * end is the end of the list
- */
- do {
- if (!gotstart && dn[i][0][0].la_value.bv_len == 7 &&
- !strncmp(parent, dn[i][0][0].la_value.bv_val, 7)) {
- gotstart = 1;
- start = i;
- }
- i++;
- } while (dn[i]);
- if (start <= 0)
- return parent_handle;
-
- for (i=start; i>=end; i--) {
- objdb->object_find_create(parent_handle,
- dn[i][0][0].la_value.bv_val, dn[i][0][0].la_value.bv_len,
- &find_handle);
- while (!objdb->object_find_next(find_handle, &object_handle)) {
- parent_handle = object_handle;
- }
- objdb->object_find_destroy(find_handle);
- }
- return object_handle;
-}
-
-
-
-static int read_config_for(LDAP *ld, struct objdb_iface_ver0 *objdb, hdb_handle_t parent,
- const char *object, const char *sub_dn)
-{
- char search_dn[4096];
- int rc;
- int first_entry = 1;
- char *dn;
- LDAPMessage *result, *e;
- hdb_handle_t parent_handle = OBJECT_PARENT_HANDLE;
- hdb_handle_t object_handle;
-
- snprintf(search_dn, sizeof(search_dn), "%s,%s", sub_dn, ldap_basedn);
-
- /* Search the whole tree from the base DN provided */
- rc = ldap_search_ext_s(ld, search_dn, LDAP_SCOPE_SUBTREE, "(objectClass=*)", NULL, 0,
- NULL, NULL, NULL, 0, &result);
- if (rc != LDAP_SUCCESS) {
- snprintf(error_reason, sizeof(error_reason), "ldap_search_ext_s: %s\n", ldap_err2string(rc));
- if (rc == LDAP_NO_SUCH_OBJECT)
- return 0;
- else
- return -1;
- }
- for (e = ldap_first_entry(ld, result); e != NULL;
- e = ldap_next_entry(ld, e)) {
- if ((dn = ldap_get_dn(ld, e)) != NULL) {
- char *attr;
- BerElement *attr_ber;
- LDAPDN parsed_dn;
-
- /* Make it parsable so we can discern the hierarchy */
- if (ldap_str2dn(dn, &parsed_dn, LDAP_DN_PEDANTIC)) {
- snprintf(error_reason, sizeof(error_reason), "ldap_str2dn failed: %s\n", ldap_err2string(rc));
- return -1;
- }
-
- /*
- * LDAP doesn't allow underscores in dn names so we replace hypens with
- * underscores so we can have thing like config_version, appear as
- * config-version in ldap
- */
- convert_dn_underscores(parsed_dn);
-
- /* Create a new object if the top-level is NOT name= OR we are the first "cluster" entry */
- if (strncmp(parsed_dn[0][0][0].la_attr.bv_val, "name", 4) || first_entry) {
- parent_handle = find_parent(objdb, parsed_dn, 0, object);
-
- objdb->object_create(parent_handle, &object_handle, parsed_dn[0][0][0].la_value.bv_val,
- parsed_dn[0][0][0].la_value.bv_len);
- first_entry = 0;
- }
- else {
- /* Remove redundant empty parent. */
- objdb->object_destroy(object_handle);
-
- parent_handle = find_parent(objdb, parsed_dn, 2, object);
- /* Create a new object with the same name as the current one */
- objdb->object_create(parent_handle, &object_handle, parsed_dn[1][0][0].la_value.bv_val,
- parsed_dn[1][0][0].la_value.bv_len);
- }
-
- /* Finished with the text representation */
- ldap_memfree(dn);
-
- /* Store the attributes as keys */
- attr = ldap_first_attribute(ld, e, &attr_ber);
- while (attr) {
- int i;
- struct berval **val_ber;
-
- val_ber = ldap_get_values_len(ld, e, attr);
- if (!val_ber)
- goto ldap_next;
- i=0;
- while (val_ber[i]) {
- /*
- * If the attribute starts "rhcs" then remove that bit
- * and make the first letter lower case so it matches the
- * cluster.conf entry.
- * so, after the above underscore change too:
- * eg 'rhcsConfig-version' becomes 'config_version'. magic!
- */
- if (strncmp(attr, "rhcs", 4) == 0) {
- memmove(attr, attr+4, strlen(attr+4)+1);
- attr[0] |= 0x60;
- }
- convert_underscores(attr, strlen(attr));
-
- /*
- * Add a key - but ignore "objectClass" & "cn" attributes
- * as they don't provide anything we can use
- */
- if (strcmp("objectClass", attr) &&
- strcmp("cn", attr)) {
- objdb->object_key_create_typed(object_handle, attr,
- val_ber[i]->bv_val,
- val_ber[i]->bv_len+1,
- OBJDB_VALUETYPE_STRING);
- }
- i++;
- }
- ldap_value_free_len(val_ber);
-ldap_next:
- ldap_memfree(attr);
- attr = ldap_next_attribute(ld, e, attr_ber);
- }
- ldap_memfree(attr);
- ber_free(attr_ber, 0);
- }
- }
- ldap_msgfree(result);
-
- return 0;
-}
-
-/* The real work starts here */
-static int init_config(struct objdb_iface_ver0 *objdb)
-{
- LDAP *ld;
- int version, rc;
-
- if (getenv("COROSYNC_LDAP_URL"))
- ldap_url = getenv("COROSYNC_LDAP_URL");
- if (getenv("COROSYNC_LDAP_BASEDN"))
- ldap_basedn = getenv("COROSYNC_LDAP_BASEDN");
-
- /* Connect to the LDAP server */
- if (ldap_initialize(&ld, ldap_url)) {
- snprintf(error_reason, sizeof(error_reason), "ldap_initialize failed: %s\n", strerror(errno));
- return -1;
- }
- version = LDAP_VERSION3;
- ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
-
- /*
- * CC: Do I need to use sasl ?!
- */
- rc = ldap_simple_bind_s(ld, getenv("COROSYNC_LDAP_BINDDN"), getenv("COROSYNC_LDAP_BINDPWD"));
- if (rc != LDAP_SUCCESS) {
- snprintf(error_reason, sizeof(error_reason), "ldap_simple_bind failed: %s\n", ldap_err2string(rc));
- return -1;
- }
-
- rc = read_config_for(ld, objdb, OBJECT_PARENT_HANDLE, "cluster", "name=cluster");
-
- ldap_unbind(ld);
- return 0;
-}
diff --git a/config/plugins/ldap/example.ldif b/config/plugins/ldap/example.ldif
deleted file mode 100644
index 0182dcf..0000000
--- a/config/plugins/ldap/example.ldif
+++ /dev/null
@@ -1,137 +0,0 @@
-# Example cluster LDIF file
-# Christine Caulfield <ccaulfie(a)redhat.com>
-#
-# You WILL need to change this to suit your needs, in particular a search
-# and replace of dc=chrissie,dc=net with your own domanin name.
-#
-# Load with:
-# ldapmodify -x -a -D"cn=Directory Manager" -f example.ldif -c -v -W
-#
-#
-# What follows is the LDAP equivalent of the following cluster.conf file:
-#
-#<totem token="21000"/>
-#
-#<cluster config_version="1" name="cc_cluster">
-# <cman cluster_id="444"/>
-#
-# <fencedevices>
-# <fencedevice name="myapc"
-# password="apc"
-# username="apc"
-# ipaddr="myapc.chrissie.net"
-# agent="fence_apc"
-# </fencedevice>
-# </fencedevice>
-# <clusternodes>
-# <clusternode name="ford"
-# votes="1"
-# nodeid="32">
-# <fence>
-# <method name="apc">
-# <device name="myapc" port="4"/>
-# </method>
-# </fence>
-# </clusternode>
-#
-# <clusternode name="arthur"
-# votes="1"
-# nodeid="10">
-# </clusternode>
-#
-# <clusternode name="jeltz"
-# votes="2"
-# nodeid="1">
-# </clusternode>
-# </clusternodes>
-#</cluster>
-#
-#
-
-dn: cn=cluster,dc=chrissie,dc=net
-cn: cluster
-objectClass: rhcsCluster
-name: cc_cluster
-rhcsConfig-version: 1
-
-# Some cman parameters
-dn: cn=cman,cn=cluster,dc=chrissie,dc=net
-cn: cman
-objectClass: rhcsCman
-rhcsCluster-id: 444
-
-# Some totem parameters
-dn: cn=totem,cn=cluster,dc=chrissie,dc=net
-cn: totem
-objectClass: rhcsTotem
-rhcsToken: 21000
-
-# Define nodes
-dn: cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-cn: clusternodes
-objectClass: nsContainer
-
-
-dn: cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-cn: clusternode
-objectClass: nsContainer
-
-
-dn: name=jeltz,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-objectClass: rhcsNode
-name: jeltz
-rhcsNodeid: 1
-rhcsVotes: 2
-
-# Define a fence agent for this node ...!
-dn: cn=fence,name=jeltz,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-cn: fence
-objectclass: nsContainer
-
-dn: cn=method,cn=fence,name=jeltz,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-cn: method
-objectclass: nsContainer
-
-dn: name=apc,cn=method,cn=fence,name=jeltz,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-name: apc
-objectclass: rhcsFenceMethod
-
-dn: cn=device,name=apc,cn=method,cn=fence,name=jeltz,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-cn: device
-objectclass: nsContainer
-
-dn: name=myapc,cn=device,name=apc,cn=method,cn=fence,name=jeltz,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-name: myapc
-objectclass: rhcsFenceAgent
-rhcsPort: 4
-
-dn: name=arthur,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-objectClass: rhcsNode
-name: arthur
-rhcsNodeid: 10
-rhcsVotes: 1
-
-dn: name=ford,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-objectClass: rhcsNode
-name: ford
-rhcsNodeid: 32
-rhcsVotes: 1
-
-# Fence agent
-
-dn: cn=fencedevices,cn=cluster,dc=chrissie,dc=net
-cn: fencedevices
-objectClass: nsContainer
-
-dn: cn=fencedevice,cn=fencedevices,cn=cluster,dc=chrissie,dc=net
-cn: fencedevice
-objectClass: nsContainer
-
-
-dn: name=myapc,cn=fencedevice,cn=fencedevices,cn=cluster,dc=chrissie,dc=net
-objectClass: rhcsFencedevice
-name: myapc
-rhcsAgent: fence_apc
-rhcsIpaddr: myapc.chrissie.net
-rhcsUsername: apc
-rhcsPassword: apc
diff --git a/config/plugins/ldap/ldap-base.csv b/config/plugins/ldap/ldap-base.csv
deleted file mode 100644
index ee8a560..0000000
--- a/config/plugins/ldap/ldap-base.csv
+++ /dev/null
@@ -1,352 +0,0 @@
-# Max attribute value: 289
-# Max object class value: 62
-obj,rhcsCluster,cluster,1
-obj,rhcsCman,cman,3
-obj,rhcsTotem,totem,4
-obj,rhcsFencedevice,fencedevice,5
-obj,rhcsDevice,device,6
-obj,rhcsMethod,method,7
-attr,rhcsConfig-version,config_version,1
-attr,rhcsNodeid,nodeid,2
-attr,rhcsCluster-id,cluster_id,3
-attr,rhcsVotes,votes,4
-attr,rhcsTwo-node,two_node,5
-attr,rhcsExpected-votes,expected_votes,6
-attr,rhcsMax-queued,max_queued,7
-attr,rhcsToken,token,8
-attr,rhcsAgent,agent,9
-attr,rhcsUsername,username,10
-attr,rhcsPassword,password,11
-attr,rhcsIpaddr,ipaddr,12
-attr,rhcsPort,port,13
-attr,name,name,14
-attr,rhcsAlias,alias,15
-attr,rhcsQuorum-dev-poll,quorum_dev_poll,16
-attr,rhcsShutdown-timeout,shutdown_timeout,17
-attr,rhcsCcsd-poll,ccsd_poll,18
-attr,rhcsDebug-mask,debug_mask,19
-obj,rhcsMulticast,multicast,8
-attr,rhcsAddr,addr,20
-obj,rhcsClusternodes,clusternodes,9
-obj,rhcsClusternode,clusternode,10
-attr,rhcsWeight,weight,21
-obj,rhcsAltname,altname,11
-attr,rhcsMcast,mcast,22
-obj,rhcsDlm,dlm,12
-attr,rhcsLog-debug,log_debug,23
-attr,rhcsTimewarn,timewarn,24
-attr,rhcsProtocol,protocol,25
-attr,rhcsEnable-fencing,enable_fencing,26
-attr,rhcsEnable-quorum,enable_quorum,27
-attr,rhcsEnable-deadlk,enable_deadlk,28
-attr,rhcsEnable-plock,enable_plock,29
-attr,rhcsPlock-debug,plock_debug,30
-attr,rhcsPlock-rate-limit,plock_rate_limit,31
-attr,rhcsPlock-ownership,plock_ownership,32
-attr,rhcsDrop-resources-time,drop_resources_time,33
-attr,rhcsDrop-resources-count,drop_resources_count,34
-attr,rhcsDrop-resources-age,drop_resources_age,35
-obj,rhcsGfs-controld,gfs_controld,13
-attr,rhcsEnable-withdraw,enable_withdraw,36
-obj,rhcsLockspace,lockspace,14
-attr,rhcsNodir,nodir,37
-obj,rhcsMaster,master,15
-obj,rhcsGroup,group,16
-attr,rhcsGroupd-compat,groupd_compat,38
-obj,rhcsFencedevices,fencedevices,17
-attr,rhcsDevice,device,39
-attr,rhcsLogin,login,40
-attr,rhcsPasswd,passwd,41
-attr,rhcsPasswd-script,passwd_script,42
-attr,rhcsAuth,auth,43
-attr,rhcsLanplus,lanplus,44
-attr,rhcsNodename,nodename,45
-attr,rhcsSelf,self,46
-attr,rhcsServers,servers,47
-attr,rhcsCserver,cserver,48
-attr,rhcsRpowerpath,rpowerpath,49
-attr,rhcsAction,action,50
-attr,rhcsOption,option,51
-attr,rhcsSecure,secure,52
-attr,rhcsVerbose,verbose,53
-attr,rhcsSwitch,switch,54
-attr,rhcsIdentity-file,identity_file,55
-attr,rhcsSsl,ssl,56
-attr,rhcsPartition,partition,57
-attr,rhcsManaged,managed,58
-attr,rhcsExec,exec,59
-attr,rhcsVmware-type,vmware_type,60
-attr,rhcsVmware-datacenter,vmware_datacenter,61
-attr,rhcsDebug,debug,62
-attr,rhcsIp-family,ip_family,63
-attr,rhcsMulticast-address,multicast_address,64
-attr,rhcsMulticast-ttl,multicast_ttl,65
-attr,rhcsRetrans,retrans,66
-attr,rhcsHash,hash,67
-attr,rhcsKey-file,key_file,68
-attr,rhcsDomain,domain,69
-attr,rhcsUse-uuid,use_uuid,70
-attr,rhcsTimeout,timeout,71
-obj,rhcsFence-xvmd,fence_xvmd,18
-attr,rhcsUri,uri,72
-attr,rhcsMulticast-interface,multicast_interface,73
-obj,rhcsLogging,logging,19
-attr,rhcsTo-syslog,to_syslog,74
-attr,rhcsTo-logfile,to_logfile,75
-attr,rhcsSyslog-facility,syslog_facility,76
-attr,rhcsSyslog-priority,syslog_priority,77
-attr,rhcsLogfile,logfile,78
-attr,rhcsLogfile-priority,logfile_priority,79
-obj,rhcsLogging-subsys,logging_subsys,20
-attr,rhcsSubsys,subsys,80
-attr,rhcsConsensus,consensus,81
-attr,rhcsJoin,join,82
-attr,rhcsToken-retransmits-before-loss-const,token_retransmits_before_loss_const,83
-attr,rhcsRrp-mode,rrp_mode,84
-attr,rhcsSecauth,secauth,85
-attr,rhcsKeyfile,keyfile,86
-obj,rhcsRm,rm,21
-attr,rhcsLog-level,log_level,87
-attr,rhcsStatus-child-max,status_child_max,88
-attr,rhcsStatus-poll-interval,status_poll_interval,89
-attr,rhcsTransition-throttling,transition_throttling,90
-attr,rhcsCentral-processing,central_processing,91
-attr,rhcsLog-facility,log_facility,92
-obj,rhcsFailoverdomains,failoverdomains,22
-obj,rhcsFailoverdomain,failoverdomain,23
-attr,rhcsOrdered,ordered,93
-attr,rhcsRestricted,restricted,94
-attr,rhcsNofailback,nofailback,95
-obj,rhcsFailoverdomainnode,failoverdomainnode,24
-attr,rhcsPriority,priority,96
-obj,rhcsEvents,events,25
-obj,rhcsEvent,event,26
-attr,rhcsFile,file,97
-attr,rhcsClass,class,98
-attr,rhcsService,service,99
-attr,rhcsService-state,service_state,100
-attr,rhcsService-owner,service_owner,101
-attr,rhcsNode,node,102
-attr,rhcsNode-id,node_id,103
-attr,rhcsNode-state,node_state,104
-attr,rhcsNode-clean,node_clean,105
-attr,rhcsNode-local,node_local,106
-obj,rhcsResources,resources,27
-obj,rhcsFence-daemon,fence_daemon,28
-attr,rhcsPost-join-delay,post_join_delay,107
-attr,rhcsPost-fail-delay,post_fail_delay,108
-attr,rhcsOverride-path,override_path,109
-attr,rhcsOverride-time,override_time,110
-attr,rhcsClean-start,clean_start,111
-obj,rhcsQuorumd,quorumd,29
-attr,rhcsInterval,interval,112
-attr,rhcsTko,tko,113
-attr,rhcsMin-score,min_score,114
-attr,rhcsLabel,label,115
-attr,rhcsStatus-file,status_file,116
-attr,rhcsScheduler,scheduler,117
-attr,rhcsReboot,reboot,118
-attr,rhcsStop-cman,stop_cman,119
-attr,rhcsParanoid,paranoid,120
-attr,rhcsAllow-kill,allow_kill,121
-attr,rhcsMax-error-cycles,max_error_cycles,122
-obj,rhcsHeuristic,heuristic,30
-attr,rhcsProgram,program,123
-attr,rhcsScore,score,124
-obj,rhcsService,service,31
-attr,rhcsRef,ref,125
-attr,rhcsAutostart,autostart,126
-attr,rhcsHardrecovery,hardrecovery,127
-attr,rhcsExclusive,exclusive,128
-attr,rhcsNfslock,nfslock,129
-attr,rhcsNfs-client-cache,nfs_client_cache,130
-attr,rhcsRecovery,recovery,131
-attr,rhcsDepend,depend,132
-attr,rhcsDepend-mode,depend_mode,133
-attr,rhcsMax-restarts,max_restarts,134
-attr,rhcsRestart-expire-time,restart_expire_time,135
-attr,rhcs--independent-subtree,__independent_subtree,136
-attr,rhcs--enforce-timeouts,__enforce_timeouts,137
-obj,rhcsIp,ip,32
-attr,rhcsAddress,address,138
-attr,rhcsFamily,family,139
-attr,rhcsMonitor-link,monitor_link,140
-attr,rhcsSleeptime,sleeptime,141
-obj,rhcsNfsclient,nfsclient,33
-attr,rhcsTarget,target,142
-attr,rhcsPath,path,143
-attr,rhcsSvcname,svcname,144
-attr,rhcsFsid,fsid,145
-attr,rhcsOptions,options,146
-attr,rhcsAllow-recover,allow_recover,147
-attr,rhcsService-name,service_name,148
-attr,rhcsUse-cache,use_cache,149
-obj,rhcsNfsexport,nfsexport,34
-obj,rhcsScript,script,35
-obj,rhcsNetfs,netfs,36
-attr,rhcsMountpoint,mountpoint,150
-attr,rhcsHost,host,151
-attr,rhcsExport,export,152
-attr,rhcsFstype,fstype,153
-attr,rhcsNo-unmount,no_unmount,154
-attr,rhcsForce-unmount,force_unmount,155
-obj,rhcsClusterfs,clusterfs,37
-attr,rhcsSelf-fence,self_fence,156
-obj,rhcsSmb,smb,38
-attr,rhcsWorkgroup,workgroup,157
-obj,rhcsApache,apache,39
-attr,rhcsServer-root,server_root,158
-attr,rhcsConfig-file,config_file,159
-attr,rhcsHttpd-options,httpd_options,160
-attr,rhcsShutdown-wait,shutdown_wait,161
-obj,rhcsOpenldap,openldap,40
-attr,rhcsUrl-list,url_list,162
-attr,rhcsSlapd-options,slapd_options,163
-obj,rhcsSamba,samba,41
-attr,rhcsSmbd-options,smbd_options,164
-attr,rhcsNmbd-options,nmbd_options,165
-obj,rhcsMysql,mysql,42
-attr,rhcsListen-address,listen_address,166
-attr,rhcsMysqld-options,mysqld_options,167
-attr,rhcsStartup-wait,startup_wait,168
-obj,rhcsPostgres-8,postgres-8,43
-attr,rhcsPostmaster-user,postmaster_user,169
-attr,rhcsPostmaster-options,postmaster_options,170
-obj,rhcsTomcat-5,tomcat-5,44
-attr,rhcsTomcat-user,tomcat_user,171
-attr,rhcsCatalina-options,catalina_options,172
-attr,rhcsCatalina-base,catalina_base,173
-obj,rhcsLvm,lvm,45
-attr,rhcsVg-name,vg_name,174
-attr,rhcsLv-name,lv_name,175
-obj,rhcsVm,vm,46
-attr,rhcsMemory,memory,176
-attr,rhcsMigration-mapping,migration_mapping,177
-attr,rhcsBootloader,bootloader,178
-attr,rhcsRootdisk-physical,rootdisk_physical,179
-attr,rhcsRootdisk-virtual,rootdisk_virtual,180
-attr,rhcsSwapdisk-physical,swapdisk_physical,181
-attr,rhcsSwapdisk-virtual,swapdisk_virtual,182
-attr,rhcsVif,vif,183
-attr,rhcsMigrate,migrate,184
-attr,rhcsSnapshot,snapshot,185
-obj,rhcsSAPInstance,SAPInstance,47
-attr,rhcsInstanceName,InstanceName,186
-attr,rhcsDIR-EXECUTABLE,DIR_EXECUTABLE,187
-attr,rhcsDIR-PROFILE,DIR_PROFILE,188
-attr,rhcsSTART-PROFILE,START_PROFILE,189
-attr,rhcsSTART-WAITTIME,START_WAITTIME,190
-attr,rhcsAUTOMATIC-RECOVER,AUTOMATIC_RECOVER,191
-attr,rhcsPRE-START-USEREXIT,PRE_START_USEREXIT,192
-attr,rhcsPOST-START-USEREXIT,POST_START_USEREXIT,193
-attr,rhcsPRE-STOP-USEREXIT,PRE_STOP_USEREXIT,194
-attr,rhcsPOST-STOP-USEREXIT,POST_STOP_USEREXIT,195
-obj,rhcsSAPDatabase,SAPDatabase,48
-attr,rhcsSID,SID,196
-attr,rhcsDBTYPE,DBTYPE,197
-attr,rhcsNETSERVICENAME,NETSERVICENAME,198
-attr,rhcsDBJ2EE-ONLY,DBJ2EE_ONLY,199
-attr,rhcsJAVA-HOME,JAVA_HOME,200
-attr,rhcsSTRICT-MONITORING,STRICT_MONITORING,201
-attr,rhcsDIR-BOOTSTRAP,DIR_BOOTSTRAP,202
-attr,rhcsDIR-SECSTORE,DIR_SECSTORE,203
-attr,rhcsDB-JARS,DB_JARS,204
-obj,rhcsNamed,named,49
-attr,rhcsNamed-sdb,named_sdb,205
-attr,rhcsNamed-working-dir,named_working_dir,206
-attr,rhcsNamed-options,named_options,207
-obj,rhcsASEHAagent,ASEHAagent,50
-attr,rhcsSybase-home,sybase_home,208
-attr,rhcsSybase-ase,sybase_ase,209
-attr,rhcsSybase-ocs,sybase_ocs,210
-attr,rhcsServer-name,server_name,211
-attr,rhcsLogin-file,login_file,212
-attr,rhcsInterfaces-file,interfaces_file,213
-attr,rhcsSybase-user,sybase_user,214
-attr,rhcsStart-timeout,start_timeout,215
-attr,rhcsDeep-probe-timeout,deep_probe_timeout,216
-obj,rhcsFs,fs,51
-attr,rhcsForce-fsck,force_fsck,217
-obj,rhcsOracledb,oracledb,52
-attr,rhcsListener-name,listener_name,218
-attr,rhcsUser,user,219
-attr,rhcsHome,home,220
-attr,rhcsType,type,221
-attr,rhcsVhost,vhost,222
-obj,rhcsAction,action,53
-attr,rhcsDepth,depth,223
-obj,rhcsFence,fence,54
-obj,rhcsUnfence,unfence,55
-attr,rhcsBlade,blade,224
-attr,rhcsLpan,lpan,225
-attr,rhcsPserver,pserver,226
-attr,rhcsQuick-status,quick_status,227
-attr,rhcsBroadcast,broadcast,228
-attr,rhcsDisable-openais,disable_openais,229
-obj,rhcsInterface,interface,56
-attr,rhcsRingnumber,ringnumber,230
-attr,rhcsBindnetaddr,bindnetaddr,231
-attr,rhcsMcastaddr,mcastaddr,232
-attr,rhcsMcastport,mcastport,233
-attr,rhcsUse-virsh,use_virsh,234
-attr,rhcsXmlfile,xmlfile,235
-attr,rhcsHypervisor,hypervisor,236
-attr,rhcsHypervisor-uri,hypervisor_uri,237
-attr,rhcsMigration-uri,migration_uri,238
-attr,rhcsSkip-undefined,skip_undefined,239
-obj,rhcsLogging-daemon,logging_daemon,57
-obj,rhcsDrbd,drbd,58
-attr,rhcsResource,resource,240
-attr,rhcsUpgrading,upgrading,241
-attr,rhcsDisallowed,disallowed,242
-attr,rhcsIo-timeout,io_timeout,243
-attr,rhcsMaster-wins,master_wins,244
-attr,rhcsVersion,version,245
-attr,rhcsHelp,help,246
-attr,rhcsSeparator,separator,247
-attr,rhcsHmc-version,hmc_version,248
-attr,rhcsCmd-prompt,cmd_prompt,249
-attr,rhcsInet4-only,inet4_only,250
-attr,rhcsInet6-only,inet6_only,251
-attr,rhcsIpport,ipport,252
-attr,rhcsSnmp-version,snmp_version,253
-attr,rhcsCommunity,community,254
-attr,rhcsSnmp-auth-prot,snmp_auth_prot,255
-attr,rhcsSnmp-sec-level,snmp_sec_level,256
-attr,rhcsSnmp-priv-prot,snmp_priv_prot,257
-attr,rhcsSnmp-priv-passwd,snmp_priv_passwd,258
-attr,rhcsSnmp-priv-passwd-script,snmp_priv_passwd_script,259
-attr,rhcsUdpport,udpport,260
-attr,rhcsCipher,cipher,261
-attr,rhcsMethod,method,262
-attr,rhcsDrac-version,drac_version,263
-attr,rhcsModule-name,module_name,264
-attr,rhcsIo-fencing,io_fencing,265
-attr,rhcsRibcl,ribcl,266
-attr,rhcsKey,key,267
-attr,rhcsDevices,devices,268
-attr,rhcsAptpl,aptpl,269
-attr,rhcsSerial-device,serial_device,270
-attr,rhcsSerial-params,serial_params,271
-attr,rhcsChannel-address,channel_address,272
-obj,rhcsClvmd,clvmd,59
-attr,rhcsInterface,interface,273
-attr,rhcsHash-cluster-id,hash_cluster_id,274
-attr,rhcs--max-failures,__max_failures,275
-attr,rhcs--failure-expire-time,__failure_expire_time,276
-attr,rhcsStatus-program,status_program,277
-attr,rhcsFail-recv-const,fail_recv_const,278
-obj,rhcsNfsserver,nfsserver,60
-attr,rhcsNfspath,nfspath,279
-attr,rhcsCman-label,cman_label,280
-obj,rhcsTomcat-6,tomcat-6,61
-attr,rhcsPower-timeout,power_timeout,281
-attr,rhcsShell-timeout,shell_timeout,282
-attr,rhcsLogin-timeout,login_timeout,283
-attr,rhcsPower-wait,power_wait,284
-attr,rhcsRetry-on,retry_on,285
-attr,rhcsDelay,delay,286
-attr,rhcsMissing-as-off,missing_as_off,287
-attr,rhcsEsh,esh,288
-attr,rhcsQuiet,quiet,289
-obj,rhcsResource-defaults,resource-defaults,62
diff --git a/config/plugins/xml/Makefile b/config/plugins/xml/Makefile
deleted file mode 100644
index 8853317..0000000
--- a/config/plugins/xml/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-TARGET= config_xml.lcrso
-
-LCRSOT=$(TARGET)
-
-all: ${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
-
-CFLAGS += -fPIC -D_GNU_SOURCE
-CFLAGS += `xml2-config --cflags`
-CFLAGS += -I${incdir}
-
-LDFLAGS += `xml2-config --libs`
-LDFLAGS += -L${libdir}
-
-OBJS= config.o
-
-${TARGET}: ${OBJS}
- $(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
-
-clean: generalclean
-
--include $(OBJS:.o=.Tpo)
diff --git a/config/plugins/xml/config.c b/config/plugins/xml/config.c
deleted file mode 100644
index a25df09..0000000
--- a/config/plugins/xml/config.c
+++ /dev/null
@@ -1,149 +0,0 @@
-#include <string.h>
-#include <syslog.h>
-
-#include <libxml/tree.h>
-
-#include <corosync/lcr/lcr_comp.h>
-#include <corosync/engine/objdb.h>
-#include <corosync/engine/config.h>
-
-static int xml_readconfig(struct objdb_iface_ver0 *objdb, const char **error_string);
-static int xml_reloadconfig(struct objdb_iface_ver0 *objdb, int flush,
- const char **error_string);
-static int init_config(struct objdb_iface_ver0 *objdb, const char *configfile,
- const char *error_string);
-static char error_reason[1024];
-
-#define DEFAULT_CONFIG DEFAULT_CONFIG_DIR "/" DEFAULT_CONFIG_FILE
-
-/*
- * Exports the interface for the service
- */
-
-static struct config_iface_ver0 xmlconfig_iface_ver0 = {
- .config_readconfig = xml_readconfig,
- .config_reloadconfig = xml_reloadconfig
-};
-
-static struct lcr_iface ifaces_ver0[2] = {
- {
- .name = "xmlconfig",
- .version = 0,
- .versions_replace = 0,
- .versions_replace_count = 0,
- .dependencies = 0,
- .dependency_count = 0,
- .constructor = NULL,
- .destructor = NULL,
- .interfaces = NULL,
- }
-};
-
-static struct lcr_comp xml_comp_ver0 = {
- .iface_count = 1,
- .ifaces = ifaces_ver0,
-};
-
-__attribute__ ((constructor))
-static void xml_comp_register(void)
-{
- lcr_interfaces_set(&ifaces_ver0[0], &xmlconfig_iface_ver0);
- lcr_component_register(&xml_comp_ver0);
-};
-
-static void addkeys(xmlAttrPtr tmpattr_in, struct objdb_iface_ver0 *objdb,
- hdb_handle_t object_handle)
-{
- xmlAttrPtr tmpattr;
-
- for (tmpattr = tmpattr_in; tmpattr; tmpattr = tmpattr->next) {
- if (tmpattr->type == XML_ATTRIBUTE_NODE)
- objdb->object_key_create_typed(object_handle,
- (char *)tmpattr->name,
- (char *)tmpattr->children->
- content,
- strlen((char *)tmpattr->
- children->content) + 1,
- OBJDB_VALUETYPE_STRING);
- }
-}
-
-static void xml2objdb(xmlNodePtr tmpnode_in, struct objdb_iface_ver0 *objdb,
- hdb_handle_t parent)
-{
- hdb_handle_t object_handle = 0;
- xmlNodePtr tmpnode;
-
- for (tmpnode = tmpnode_in; tmpnode; tmpnode = tmpnode->next) {
- if (tmpnode->type == XML_ELEMENT_NODE) {
- objdb->object_create(parent, &object_handle,
- (char *)tmpnode->name,
- strlen((char *)tmpnode->name));
- if (tmpnode->properties)
- addkeys(tmpnode->properties, objdb,
- object_handle);
- }
- xml2objdb(tmpnode->children, objdb, object_handle);
- }
-}
-
-static int xml_reloadconfig(struct objdb_iface_ver0 *objdb, int flush,
- const char **error_string)
-{
- return xml_readconfig(objdb, error_string);
-}
-
-static int xml_readconfig(struct objdb_iface_ver0 *objdb, const char **error_string)
-{
- int ret = 0;
- const char *configfile = DEFAULT_CONFIG;
-
- /* We need to set this up to internal defaults too early */
- openlog("corosync", LOG_CONS | LOG_PID, SYSLOGFACILITY);
-
- if (getenv("COROSYNC_CLUSTER_CONFIG_FILE"))
- configfile = getenv("COROSYNC_CLUSTER_CONFIG_FILE");
-
- /* Read low-level totem/aisexec etc config from cluster.conf */
- if (!(ret = init_config(objdb, configfile, error_reason)))
- snprintf(error_reason, sizeof(error_reason),
- "Successfully read config from %s\n", configfile);
- else
- snprintf(error_reason, sizeof(error_reason),
- "Unable to read config from %s\n", configfile);
-
- *error_string = error_reason;
-
- return ret;
-}
-
-static int init_config(struct objdb_iface_ver0 *objdb, const char *configfile,
- const char *error_string)
-{
- int err = 0;
- xmlDocPtr doc = NULL;
- xmlNodePtr root_node = NULL;
-
- /* openfile */
-
- doc = xmlParseFile(configfile);
- if (!doc) {
- err = -1;
- goto fail;
- }
-
- root_node = xmlDocGetRootElement(doc);
- if (!root_node) {
- err = -1;
- goto fail;
- }
-
- /* load it in objdb */
- xml2objdb(root_node, objdb, OBJECT_PARENT_HANDLE);
-
-fail:
- if (doc)
- xmlFreeDoc(doc);
-
- return err;
-}
diff --git a/config/tools/Makefile b/config/tools/Makefile
deleted file mode 100644
index e695417..0000000
--- a/config/tools/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS=ccs_tool ldap xml man
diff --git a/config/tools/ccs_tool/Makefile b/config/tools/ccs_tool/Makefile
deleted file mode 100644
index 223a41f..0000000
--- a/config/tools/ccs_tool/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-TARGET1 = ccs_tool
-TARGET2 = ccs_test
-
-SBINDIRT = $(TARGET1)
-SBINSYMT = $(TARGET2)
-
-include ../../../make/defines.mk
-
-all: depends ${TARGET1} ${TARGET2}
-
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-OBJS = ccs_tool.o \
- editconf.o
-
-CFLAGS += -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
-CFLAGS += `xml2-config --cflags`
-CFLAGS += -I${ccsincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${ccslibdir} -lccs
-LDFLAGS += `xml2-config --libs`
-LDFLAGS += -L${libdir}
-
-${TARGET1}: ${OBJS} ${LDDEPS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-${TARGET2}: ${TARGET1}
- ln -sf ${TARGET1} ${TARGET2}
-
-depends:
- $(MAKE) -C $(OBJDIR)/config/libs/libccsconfdb all
-
-clean: generalclean
-
--include $(OBJS:.o=.Tpo)
diff --git a/config/tools/ccs_tool/ccs_tool.c b/config/tools/ccs_tool/ccs_tool.c
deleted file mode 100644
index 34c4c1e..0000000
--- a/config/tools/ccs_tool/ccs_tool.c
+++ /dev/null
@@ -1,380 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <string.h>
-#include <errno.h>
-
-#include "copyright.cf"
-#include "editconf.h"
-#include "ccs.h"
-
-
-static void tool_print_usage(FILE *stream);
-
-int globalverbose=0;
-
-static void test_print_usage(FILE *stream);
-
-static int test_main(int argc, char *argv[], int old_format){
- int desc=0;
- int i=0;
- int force = 0, blocking = 0;
- char *str=NULL;
- char *cluster_name = NULL;
-
- if(argc <= 1){
- test_print_usage(stderr);
- exit(EXIT_FAILURE);
- }
-
- for(i=1; i < argc; i++){
- if(!strcmp(argv[i], "-h")){
- test_print_usage(stdout);
- exit(EXIT_SUCCESS);
- }
- if(!strcmp(argv[i], "-V")){
- printf("%s %s (built %s %s)\n", argv[0], RELEASE_VERSION, __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- }
- }
-
- if(!strcmp(argv[1], "connect")){
- for(i=2; i < argc; i++){
- if(!strcmp(argv[i], "force")){
- printf("Force is set.\n");
- force = 1;
- } else if(!strcmp(argv[i], "block")){
- printf("Blocking is set.\n");
- blocking = 1;
- } else {
- cluster_name = argv[i];
- printf("Setting cluster name to %s\n", cluster_name);
- }
- }
- if(blocking && !force){
- fprintf(stderr, "Blocking can only be used with \"force\".\n");
- exit(EXIT_FAILURE);
- }
- if(force){
- desc = ccs_force_connect(cluster_name, blocking);
- } else {
- if(cluster_name){
- fprintf(stderr, "A cluster name can only be specified when using 'force'.\n");
- exit(EXIT_FAILURE);
- }
- desc = ccs_connect();
- }
- if(desc < 0){
- fprintf(stderr, "ccs_connect failed: %s\n", strerror(errno));
- exit(EXIT_FAILURE);
- } else {
- printf("Connect successful.\n");
- printf(" Connection descriptor = %d\n", desc);
- ccs_disconnect(desc);
- }
- }
- else if(!strcmp(argv[1], "disconnect")){
- if(argc < 3){
- fprintf(stderr, "Wrong number of arguments.\n");
- exit(EXIT_FAILURE);
- }
- desc = ccs_connect();
- if (desc < 0) {
- fprintf(stderr, "ccs_disconnect failed: unable to communicate with ccs\n");
- exit(EXIT_FAILURE);
- }
- if(ccs_disconnect(desc)){
- fprintf(stderr, "ccs_disconnect failed: %s\n", strerror(errno));
- exit(EXIT_FAILURE);
- } else {
- printf("Disconnect successful.\n");
- }
- }
- else if(!strcmp(argv[1], "get")){
- if(argc < 4){
- fprintf(stderr, "Wrong number of arguments.\n");
- exit(EXIT_FAILURE);
- }
- desc = ccs_connect();
- if((desc < 0) || ccs_get(desc, argv[3], &str)){
- fprintf(stderr, "ccs_get failed: %s\n", strerror(errno));
- exit(EXIT_FAILURE);
- } else {
- if (old_format) {
- printf("Get successful.\n");
- printf(" Value = <%s>\n", str);
- }
- else {
- printf("%s\n", str);
- }
- if(str)free(str);
- ccs_disconnect(desc);
- }
- }
- else {
- fprintf(stderr, "Unknown command: %s\n", argv[1]);
- exit(EXIT_FAILURE);
- }
-
- exit(EXIT_SUCCESS);
-}
-
-static void test_print_usage(FILE *stream)
-{
- fprintf(stream,
- "Usage:\n"
- "\n"
- "ccs_test [Options] <Command>\n"
- "\n"
- "Options:\n"
- " -h Print usage.\n"
- " -V Print version information.\n"
- "\n"
- "Commands:\n"
- " connect <force> <block> Connect to CCS and return connection descriptor.\n"
- " disconnect <desc> Disconnect from CCS.\n"
- " get <desc> <request> Get a value from CCS.\n"
- );
-}
-
-static int xpath_query(int argc, char **argv)
-{
- int handle;
- char *ret;
- int i;
-
- if (argc < 2) {
- fprintf(stderr,
- "Usage:\n"
- "\n"
- "ccs_tool query [-n] <xpath query>\n"
- "\n"
- "options\n"
- " -n disable full XPath parsing\n");
- return 1;
- }
-
- /* Tell the library we want full XPath parsing */
- fullxpath = 1;
-
- if (strcmp(argv[1], "-n") == 0) {
- argv++;
- argc--;
-
- /* Actually ... no we don't */
- fullxpath = 0;
- }
-
- handle = ccs_connect();
- if (handle < 0) {
- fprintf(stderr, "Unable to connect to ccs\n");
- exit(EXIT_FAILURE);
- }
-
- /* Process all the queries on the command-line */
- for (i=1; i<argc; i++) {
- if (!ccs_get(handle, argv[1], &ret)) {
- printf("%s\n", ret);
- free(ret);
- }
- else {
- fprintf(stderr, "Query failed: %s\n", strerror(errno));
- ccs_disconnect(handle);
- return -1;
- }
- }
- ccs_disconnect(handle);
- return 0;
-}
-
-static int tool_main(int argc, char *argv[])
-{
- optind = 1;
-
- if (argc < 2 || !strcmp(argv[optind], "-h")) {
- tool_print_usage(stdout);
- exit(EXIT_SUCCESS);
- }
- if (!strcmp(argv[optind], "-V")) {
- printf("%s %s (built %s %s)\n", argv[0], RELEASE_VERSION,
- __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- }
-
- if(optind < argc){
- if(!strcmp(argv[optind], "-verbose")){
- optind++;
- globalverbose=1;
- }
- if(!strcmp(argv[optind], "help")){
- tool_print_usage(stdout);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "query")){
- return xpath_query(argc-1, argv+1);
- }
- else if(!strcmp(argv[optind], "addnode")){
- add_node(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "delnode")){
- del_node(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "addservice")){
- add_service(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "delservice")){
- del_node(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "addscript")){
- add_script(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "delscript")){
- del_node(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "addip")){
- add_ip(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "delip")){
- del_node(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "addfs")){
- add_fs(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "delfs")){
- del_node(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "addfdomain")){
- add_fdomain(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "delfdomain")){
- del_node(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "addfence")){
- add_fence(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "delfence")){
- del_fence(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "lsnode")){
- list_nodes(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "lsservice")){
- list_services(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "lsfence")){
- list_fences(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "lsscript")){
- list_scripts(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "lsip")){
- list_ips(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "lsfs")){
- list_fs(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "lsfdomains")){
- list_fdomains(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "create")){
- create_skeleton(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "addnodeids")){
- add_nodeids(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
-
- else {
- fprintf(stderr, "Unknown command, %s.\n"
- "Try 'ccs_tool help' for help.\n", argv[optind]);
- exit(EXIT_FAILURE);
- }
- } else {
- fprintf(stderr, "Too few arguments.\n"
- "Try 'ccs_tool help' for help.\n");
- exit(EXIT_FAILURE);
- }
- exit(EXIT_SUCCESS);
-}
-
-static void tool_print_usage(FILE *stream){
- fprintf(stream,
- "Usage:\n"
- " ccs_tool [options] <command>\n"
- "\n"
- "Options:\n"
- " -verbose Make some operations print more details.\n"
- " -h Print this usage and exit.\n"
- " -V Print version information and exit.\n"
- "\n"
- "Commands:\n"
- " help Print this usage and exit.\n"
- " query <xpath query> Query the cluster configuration.\n"
- " addnode <node> Add a node\n"
- " delnode <node> Delete a node\n"
- " lsnode List nodes\n"
- " addservice <name> Add a service\n"
- " delservice <name> Delete a service\n"
- " lsservice List services\n"
- " lsfence List fence devices\n"
- " addfence <fencedev> Add a new fence device\n"
- " delfence <fencedev> Delete a fence device\n"
- " addscript <name> Add a script resource\n"
- " delscript <name> Delete a script resource\n"
- " lsscript List script resources\n"
- " addip <name> Add an IP address resource\n"
- " delip <name> Delete an IP address resource\n"
- " lsip List IP address resources\n"
- " addfs <name> Add an filesystem resource\n"
- " delfs <name> Delete an filesystem resource\n"
- " lsfs List filesystem resources\n"
- " addfdomain <name> Add an failover domain\n"
- " delfdomain <name> Delete an failover domain\n"
- " lsfdomains List failover domains\n"
- " create Create a skeleton config file\n"
- " addnodeids Assign node ID numbers to all nodes\n"
- "\n");
-}
-
-
-int main(int argc, char *argv[])
-{
- char *name = strdup(argv[0]);
-
- /*
- * Don't be anal about the binary name.
- * We expect either 'ccs_tool' or 'ccs_test',
- * but interpret anything other than 'ccs_test'
- * as 'ccs_tool'.
- * That's not a bug, it's a feature.
- */
-
- if (strcmp(basename(name), "ccs_test") == 0)
- return test_main(argc, argv, 1);
- else
- return tool_main(argc, argv);
-}
diff --git a/config/tools/ccs_tool/editconf.c b/config/tools/ccs_tool/editconf.c
deleted file mode 100644
index c4dcb9c..0000000
--- a/config/tools/ccs_tool/editconf.c
+++ /dev/null
@@ -1,2395 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <getopt.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-
-#include <libxml/tree.h>
-
-#include "editconf.h"
-
-#define MAX_NODES 256
-
-const char *prog_name = "ccs_tool";
-
-#define die(fmt, args...) \
-do { \
- fprintf(stderr, "%s: ", prog_name); \
- fprintf(stderr, fmt "\n", ##args); \
- exit(EXIT_FAILURE); \
-} while (0)
-
-
-#define INT_TO_CHAR(x, str) \
- if (str && atoi((const char *)str)) \
- x = '*'; \
- else \
- x = ' ';
-
-struct option_info
-{
- const char *name;
- const char *altname;
- const char *votes;
- const char *nodeid;
- const char *mcast_addr;
- const char *ip_addr;
- const char *fence_type;
- const char *autostart;
- const char *exclusive;
- const char *recovery;
- const char *fs;
- const char *domain;
- const char *script;
- const char *mountpoint;
- const char *type;
- const char *device;
- const char *options;
- const char *configfile;
- const char *outputfile;
- const char **failover_nodes;
- int do_delete;
- int force_fsck;
- int force_unmount;
- int self_fence;
- int ordered;
- int restricted;
-};
-
-static void config_usage(int rw)
-{
- fprintf(stderr, " -c --configfile Name of configuration file (" DEFAULT_CONFIG_DIR "/" DEFAULT_CONFIG_FILE ")\n");
- if (rw)
- {
- fprintf(stderr, " -o --outputfile Name of output file (defaults to same as --configfile)\n");
- }
-}
-
-static void help_usage(void)
-{
- fprintf(stderr, " -h --help Display this help text\n");
-}
-
-static void list_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options]\n", prog_name, name);
- fprintf(stderr, " -v --verbose Print all properties of the item\n");
- config_usage(0);
- help_usage();
-
- exit(0);
-}
-
-static void create_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [-2] <clustername>\n", prog_name, name);
- fprintf(stderr, " -2 Create a 2-node cman cluster config file\n");
- fprintf(stderr, " -n <num> Create skeleton entries for <num> nodes\n");
- fprintf(stderr, " -f <device> Add a fence device to the node skeletons\n");
- config_usage(0);
- help_usage();
- fprintf(stderr, "\n"
- "Note that \"create\" on its own will not create a valid configuration file.\n"
- "Fence agents and nodes will need to be added to it before handing it over\n"
- "to cman.\n"
- "\n"
- "eg:\n"
- " ccs_tool create MyCluster\n"
- " ccs_tool addfence apc fence_apc ipaddr=apc.domain.net login=apc password=apc\n"
- " ccs_tool addnode node1 -n 1 -f apc port=1\n"
- " ccs_tool addnode node2 -n 2 -f apc port=2\n"
- " ccs_tool addnode node3 -n 3 -f apc port=3\n"
- " ccs_tool addnode node4 -n 4 -f apc port=4\n"
- "\n");
- fprintf(stderr, "If you add -n <numbner> to the command then %s will add skeleton entries for\n", name);
- fprintf(stderr, "that many nodes. This file WILL NEED EDITTING MANUALLY before it can be used\n");
- fprintf(stderr, "by cman.\n");
-
- exit(0);
-}
-
-static void addfence_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options] <name> <agent> [param=value]\n", prog_name, name);
- config_usage(1);
- help_usage();
-
- exit(0);
-}
-
-static void delfence_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options] <name>\n", prog_name, name);
- config_usage(1);
- help_usage();
- fprintf(stderr, "\n");
- fprintf(stderr, "%s will allow you to remove a fence device that is in use by nodes.\n", name);
- fprintf(stderr, "This is to allow changes to be made, but be aware that it may produce an\n");
- fprintf(stderr, "invalid configuration file if you don't add it back in again.\n");
-
- exit(0);
-}
-
-static void delnode_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options] <name>\n", prog_name, name);
- config_usage(1);
- help_usage();
-
- exit(0);
-}
-
-static void addscript_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options] <name> <path_to_script>\n",
- prog_name, name);
- config_usage(1);
- help_usage();
-
- exit(0);
-}
-
-static void addip_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options] <IP_address>\n",
- prog_name, name);
- config_usage(1);
- help_usage();
-
- exit(0);
-}
-
-static void addfs_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options] <name> <device> <mountpoint>\n",
- prog_name, name);
- fprintf(stderr, " -t --type Type of the filesystem (ext3, ext4, etc.)\n");
- fprintf(stderr, " Default type is ext3.\n");
- fprintf(stderr, " -p --options Mount options\n");
- fprintf(stderr, " -k --force_fsck Force fsck before mount\n");
- fprintf(stderr, " -u --force_unmount Call umount with force flag\n");
- fprintf(stderr, " -s --self_fence Use 'self_fence' feature\n");
- config_usage(1);
- help_usage();
-
- exit(0);
-}
-
-static void addfdomain_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options] <name> <node1> ... <nodeN>\n",
- prog_name, name);
- fprintf(stderr, " -p --ordered Allows you to specify a preference order\n");
- fprintf(stderr, " among the members of a failover domain\n");
- fprintf(stderr, " -r --restricted Allows you to restrict the members that can\n");
- fprintf(stderr, " run a particular cluster service.\n");
- config_usage(1);
- help_usage();
-
- exit(0);
-}
-
-static void addnodeid_usage(const char *name)
-{
- fprintf(stderr, "Add node IDs to all nodes in the config file that don't have them.\n");
- fprintf(stderr, "Nodes with IDs will not be afftected, so you can run this as many times\n");
- fprintf(stderr, "as you like without doing any harm.\n");
- fprintf(stderr, "It will optionally add a multicast address to the cluster config too.\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Usage: %s %s [options] <name>\n", prog_name, name);
- fprintf(stderr, " -n --nodeid Nodeid to start with (default 1)\n");
- fprintf(stderr, " -m --multicast Set or change the multicast address\n");
- fprintf(stderr, " -v --verbose Print nodeids that are assigned\n");
- config_usage(1);
- help_usage();
-
- exit(0);
-}
-
-static void addnode_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options] <nodename> [<fencearg>=<value>]...\n", prog_name, name);
- fprintf(stderr, " -n --nodeid Nodeid (required)\n");
- fprintf(stderr, " -v --votes Number of votes for this node (default 1)\n");
- fprintf(stderr, " -a --altname Alternative name/interface for multihomed hosts\n");
- fprintf(stderr, " -f --fence_type Type of fencing to use\n");
- config_usage(1);
- help_usage();
-
- fprintf(stderr, "\n");
- fprintf(stderr, "Examples:\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Add a new node to default configuration file:\n");
- fprintf(stderr, " %s %s newnode1 -n 1 -f wti ipaddr=newnode\n", prog_name, name);
- fprintf(stderr, "\n");
- fprintf(stderr, "Add a new node and dump config file to stdout rather than save it\n");
- fprintf(stderr, " %s %s newnode2 -n 2 -f apc -o- newnode.temp.net port=1\n", prog_name, name);
-
- exit(0);
-}
-
-static void addservice_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options] <servicename>\n", prog_name, name);
- fprintf(stderr, " -a --autostart Start the service on boot\n");
- fprintf(stderr, " -d --domain Failover domain for the service\n");
- fprintf(stderr, " -x --exclusive Do not run other services on the same server\n");
- fprintf(stderr, " -r --recovery Recovery policy\n");
- fprintf(stderr, " -f --fs Filesystem resource for the service\n");
- fprintf(stderr, " -s --script Script resource for the service\n");
- fprintf(stderr, " -i --ip IP address resource for the service\n");
- config_usage(1);
- help_usage();
-
- exit(0);
-}
-
-/* Is it really ?
- * Actually, we don't check that this is a valid multicast address(!),
- * merely that it is a valid IP[46] address.
- */
-static int valid_mcast_addr(char *mcast)
-{
- struct addrinfo *ainfo;
- struct addrinfo ahints;
- int ret;
-
- memset(&ahints, 0, sizeof(ahints));
-
- ret = getaddrinfo(mcast, NULL, &ahints, &ainfo);
- if (ret) {
- freeaddrinfo(ainfo);
- return 0;
- }
- return 1;
-}
-
-static void save_file(xmlDoc *doc, struct option_info *ninfo)
-{
- char tmpconffile[strlen(ninfo->outputfile)+5];
- char oldconffile[strlen(ninfo->outputfile)+5];
- int using_stdout = 0;
- mode_t old_mode;
- int ret;
-
- old_mode = umask(026);
-
- if (strcmp(ninfo->outputfile, "-") == 0)
- using_stdout = 1;
-
- /*
- * Save it to a temp file before moving the old one out of the way
- */
- if (!using_stdout)
- {
- snprintf(tmpconffile, sizeof(tmpconffile), "%s.tmp", ninfo->outputfile);
- snprintf(oldconffile, sizeof(oldconffile), "%s.old", ninfo->outputfile);
- }
- else
- {
- strncpy(tmpconffile, ninfo->outputfile, sizeof(tmpconffile));
- }
-
- xmlKeepBlanksDefault(0);
- ret = xmlSaveFormatFile(tmpconffile, doc, 1);
- if (ret == -1)
- die("Error writing new config file %s", ninfo->outputfile);
-
- if (!using_stdout)
- {
- if (rename(ninfo->outputfile, oldconffile) == -1 && errno != ENOENT)
- die("Can't move old config file out of the way\n");
-
- if (rename(tmpconffile, ninfo->outputfile))
- {
- perror("Error renaming new file to its real filename");
-
- /* Drat, that failed, try to put the old one back */
- if (rename(oldconffile, ninfo->outputfile))
- die("Can't move old config fileback in place - clean up after me please\n");
- }
- }
-
- /* free the document */
- xmlFreeDoc(doc);
-
- umask(old_mode);
-}
-
-static void validate_int_arg(char argopt, char *arg)
-{
- char *tmp;
- int val;
-
- val = strtol(arg, &tmp, 10);
- if (tmp == arg || tmp != arg + strlen(arg))
- die("argument to %c (%s) is not an integer", argopt, arg);
-
- if (val < 0)
- die("argument to %c cannot be negative", argopt);
-}
-
-/* Get the config_version string from the file */
-static xmlChar *find_version(xmlNode *root)
-{
- if (xmlHasProp(root, BAD_CAST "config_version"))
- {
- xmlChar *ver;
-
- ver = xmlGetProp(root, BAD_CAST "config_version");
- return ver;
- }
- return NULL;
-}
-
-/* Get the cluster name string from the file */
-static xmlChar *cluster_name(xmlNode *root)
-{
- if (xmlHasProp(root, BAD_CAST "name"))
- {
- xmlChar *ver;
-
- ver = xmlGetProp(root, BAD_CAST "name");
- return ver;
- }
- return NULL;
-}
-
-static void increment_version(xmlNode *root_element)
-{
- int ver;
- unsigned char *version_string;
- char newver[32];
-
- /* Increment version */
- version_string = find_version(root_element);
- if (!version_string)
- die("Can't find \"config_version\" in config file\n");
-
- ver = atoi((char *)version_string);
- snprintf(newver, sizeof(newver), "%d", ++ver);
- xmlSetProp(root_element, BAD_CAST "config_version", BAD_CAST newver);
-}
-
-static void _xmlSetIntProp(xmlNode *element, const char *property, const int value)
-{
- char buf[32];
- snprintf(buf, sizeof(buf), "%d", value);
- xmlSetProp(element, BAD_CAST property, BAD_CAST buf);
-}
-
-static xmlNode *findnode(xmlNode *root, const char *name)
-{
- xmlNode *cur_node;
-
- for (cur_node = root->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, name)==0)
- {
- return cur_node;
- }
- }
- return NULL;
-}
-
-/* Return the fence type name (& node) for a cluster node */
-static xmlChar *get_fence_type(xmlNode *clusternode, xmlNode **fencenode)
-{
- xmlNode *f;
-
- f = findnode(clusternode, "fence");
- if (f)
- {
- f = findnode(f, "method");
- if (f)
- {
- f = findnode(f, "device");
- *fencenode = f;
- return xmlGetProp(f, BAD_CAST "name");
- }
- }
- return NULL;
-}
-
-/* Check the fence type exists under <fencedevices> */
-static xmlNode *valid_fence_type(xmlNode *root, const char *fencetype)
-{
- xmlNode *devs;
- xmlNode *cur_node;
-
- devs = findnode(root, "fencedevices");
- if (!devs)
- return NULL;
-
- for (cur_node = devs->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "fencedevice") == 0)
- {
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
- assert(name);
- if (strcmp((char *)name, fencetype) == 0)
- return cur_node;
- }
- }
- return NULL;
-}
-
-/* Check the nodeid is not already in use by another node */
-static xmlNode *get_by_nodeid(xmlNode *root, int nodeid)
-{
- xmlNode *cnodes;
- xmlNode *cur_node;
-
- cnodes = findnode(root, "clusternodes");
- if (!cnodes)
- return NULL;
-
- for (cur_node = cnodes->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0)
- {
- xmlChar *idstring = xmlGetProp(cur_node, BAD_CAST "nodeid");
- if (idstring && atoi((char *)idstring) == nodeid)
- return cur_node;
- }
- }
- return NULL;
-}
-
-
-/* Get the multicast address node.
- */
-static xmlNode *find_multicast_addr(xmlNode *clusternodes)
-{
- xmlNode *clnode = findnode(clusternodes, "cman");
- if (clnode)
- {
- xmlNode *mcast = findnode(clnode, "multicast");
- return mcast;
- }
- return NULL;
-}
-
-static xmlNode *do_find_node(xmlNode *root, const char *nodename,
- const char *elem_name, const char *attrib_name)
-{
- xmlNode *cur_node;
-
- for (cur_node = root->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE &&
- strcmp((char *)cur_node->name, elem_name) == 0)
- {
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST attrib_name);
- if (name && strcmp((char *)name, nodename) == 0)
- return cur_node;
- }
- }
- return NULL;
-}
-
-static xmlNode *do_find_resource_ref(xmlNode *root, const char *name,
- const char *res_type)
-{
- xmlNode *cur_node;
- xmlNode *res = NULL;
-
- for (cur_node = root->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE &&
- strcmp((char *)cur_node->name, "service") == 0)
- {
- res = do_find_node(cur_node, name, res_type, "ref");
- if (res)
- break;
- }
- }
-
- return res;
-}
-
-static xmlNode *find_node(xmlNode *clusternodes, const char *nodename)
-{
- return do_find_node(clusternodes, nodename, "clusternode", "name");
-}
-
-static xmlNode *find_service(xmlNode *root, const char *servicename)
-{
- return do_find_node(root, servicename, "service", "name");
-}
-
-static xmlNode *find_fs_resource(xmlNode *root, const char *name)
-{
- return do_find_node(root, name, "fs", "name");
-}
-
-static xmlNode *find_fdomain_resource(xmlNode *root, const char *name)
-{
- return do_find_node(root, name, "failoverdomain", "name");
-}
-
-static xmlNode *find_script_resource(xmlNode *root, const char *name)
-{
- return do_find_node(root, name, "script", "name");
-}
-
-static xmlNode *find_script_ref(xmlNode *root, const char *name)
-{
- return do_find_resource_ref(root, name, "script");
-}
-
-static xmlNode *find_ip_resource(xmlNode *root, const char *name)
-{
- return do_find_node(root, name, "ip", "address");
-}
-
-static xmlNode *find_ip_ref(xmlNode *root, const char *name)
-{
- return do_find_resource_ref(root, name, "ip");
-}
-
-static xmlNode *find_fs_ref(xmlNode *root, const char *name)
-{
- return do_find_resource_ref(root, name, "fs");
-}
-
-static xmlNode *find_fdomain_ref(xmlNode *root, const char *name)
-{
- xmlNode *cur_node;
-
- for (cur_node = root->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE &&
- strcmp((char *)cur_node->name, "service") == 0)
- {
- xmlChar *domain = xmlGetProp(cur_node, BAD_CAST "domain");
- if (domain && strcmp(name, (char *)domain) == 0)
- return cur_node;
- }
- }
-
- return NULL;
-}
-
-/* Print name=value pairs for a (n XML) node.
- * "ignore" is a string to ignore if present as a property (probably already printed on the main line)
- */
-static int print_properties(xmlNode *node, const char *prefix, const char *ignore, const char *ignore2)
-{
- xmlAttr *attr;
- int done_prefix = 0;
-
- for (attr = node->properties; attr; attr = attr->next)
- {
- /* Don't print "name=" */
- if (strcmp((char *)attr->name, "name") &&
- strcmp((char *)attr->name, ignore) &&
- strcmp((char *)attr->name, ignore2)
- )
- {
- if (!done_prefix)
- {
- done_prefix = 1;
- printf("%s", prefix);
- }
- printf(" %s=%s", attr->name, xmlGetProp(node, attr->name));
- }
- }
- if (done_prefix)
- printf("\n");
- return done_prefix;
-}
-
-/* Add name=value pairs from the commandline as properties to a node */
-static void add_fence_args(xmlNode *fencenode, int argc, char **argv, int optindex)
-{
- int i;
-
- for (i = optindex; i<argc; i++)
- {
- char *prop;
- char *value;
- char *equals;
-
- prop = strdup(argv[i]);
- // FIXME: handle failed strdup
- equals = strchr(prop, '=');
- if (!equals)
- die("option '%s' is not opt=value pair\n", prop);
-
- value = equals+1;
- *equals = '\0';
-
- /* "name" is used for the fence type itself, so this is just
- * to protect the user from their own stupidity
- */
- if (strcmp(prop, "name") == 0)
- die("Can't use \"name\" as a fence argument name\n");
-
- xmlSetProp(fencenode, BAD_CAST prop, BAD_CAST value);
- free(prop);
- }
-}
-
-static void add_clusternode(xmlNode *root_element, struct option_info *ninfo,
- int argc, char **argv, int optindex)
-{
- xmlNode *clusternodes;
- xmlNode *newnode;
-
- xmlNode *newfence;
- xmlNode *newfencemethod;
- xmlNode *newfencedevice;
-
- clusternodes = findnode(root_element, "clusternodes");
- if (!clusternodes)
- die("Can't find \"clusternodes\" in %s\n", ninfo->configfile);
-
- /* Don't allow duplicate node names */
- if (find_node(clusternodes, ninfo->name))
- die("node %s already exists in %s\n", ninfo->name, ninfo->configfile);
-
- /* Check for duplicate node ID */
- if (!ninfo->nodeid)
- die("nodeid not specified\n");
-
- if (get_by_nodeid(root_element, atoi((char *)ninfo->nodeid)))
- die("nodeid %s already in use\n", ninfo->nodeid);
-
- /* Don't allow random fence types */
- if (ninfo->fence_type && !valid_fence_type(root_element, ninfo->fence_type))
- die("fence type '%s' not known\n", ninfo->fence_type);
-
- /* Add the new node */
- newnode = xmlNewNode(NULL, BAD_CAST "clusternode");
- xmlSetProp(newnode, BAD_CAST "name", BAD_CAST ninfo->name);
- xmlSetProp(newnode, BAD_CAST "votes", BAD_CAST ninfo->votes);
- xmlSetProp(newnode, BAD_CAST "nodeid", BAD_CAST ninfo->nodeid);
- xmlAddChild(clusternodes, newnode);
-
- if (ninfo->altname)
- {
- xmlNode *altnode;
-
- altnode = xmlNewNode(NULL, BAD_CAST "altname");
- xmlSetProp(altnode, BAD_CAST "name", BAD_CAST ninfo->altname);
- xmlAddChild(newnode, altnode);
- }
-
- /* Add the fence attributes */
- if (ninfo->fence_type)
- {
- newfence = xmlNewNode(NULL, BAD_CAST "fence");
- newfencemethod = xmlNewNode(NULL, BAD_CAST "method");
- xmlSetProp(newfencemethod, BAD_CAST "name", BAD_CAST "single");
-
- newfencedevice = xmlNewNode(NULL, BAD_CAST "device");
- xmlSetProp(newfencedevice, BAD_CAST "name", BAD_CAST ninfo->fence_type);
-
- /* Add name=value options */
- add_fence_args(newfencedevice, argc, argv, optindex+1);
-
- xmlAddChild(newnode, newfence);
- xmlAddChild(newfence, newfencemethod);
- xmlAddChild(newfencemethod, newfencedevice);
- }
-}
-
-static void add_clusterservice(xmlNode *root_element, struct option_info *ninfo,
- int argc, char **argv, int optindex)
-{
- xmlNode *rm;
- xmlNode *rs;
- xmlNode *fdomains;
- xmlNode *newnode;
-
- xmlNode *newfs = NULL;
- xmlNode *newfsscript;
- xmlNode *newfsip;
-
- rm = findnode(root_element, "rm");
- if (!rm)
- die("Can't find \"rm\" in %s\n", ninfo->configfile);
-
- /* Don't allow duplicate service names */
- if (find_service(rm, ninfo->name))
- die("service %s already exists in %s\n", ninfo->name,
- ninfo->configfile);
-
- rs = findnode(rm, "resources");
- fdomains = findnode(rm, "failoverdomains");
- if (ninfo->fs && (!rs || !find_fs_resource(rs, ninfo->fs)))
- die("fs resource %s doesn't exist in %s\n", ninfo->fs,
- ninfo->configfile);
- if (ninfo->script && (!rs || !find_script_resource(rs, ninfo->script)))
- die("script resource %s doesn't exist in %s\n", ninfo->script,
- ninfo->configfile);
- if (ninfo->ip_addr && (!rs || !find_ip_resource(rs, ninfo->ip_addr)))
- die("ip resource %s doesn't exist in %s\n", ninfo->ip_addr,
- ninfo->configfile);
- if (ninfo->domain && (!fdomains || !find_fdomain_resource(fdomains, ninfo->domain)))
- die("failover domain %s doesn't exist in %s\n", ninfo->domain,
- ninfo->configfile);
-
- /* Add the new service */
- newnode = xmlNewNode(NULL, BAD_CAST "service");
- xmlSetProp(newnode, BAD_CAST "name", BAD_CAST ninfo->name);
- xmlSetProp(newnode, BAD_CAST "autostart", BAD_CAST ninfo->autostart);
- if (ninfo->domain)
- xmlSetProp(newnode, BAD_CAST "domain", BAD_CAST ninfo->domain);
- if (ninfo->exclusive)
- xmlSetProp(newnode, BAD_CAST "exclusive",
- BAD_CAST ninfo->exclusive);
- xmlSetProp(newnode, BAD_CAST "recovery", BAD_CAST ninfo->recovery);
- xmlAddChild(rm, newnode);
-
- /* Add the fs reference */
- if (ninfo->fs)
- {
- newfs = xmlNewNode(NULL, BAD_CAST "fs");
- xmlSetProp(newfs, BAD_CAST "ref", BAD_CAST ninfo->fs);
- xmlAddChild(newnode, newfs);
- }
-
- /* Add the script reference */
- if (ninfo->script)
- {
- newfsscript = xmlNewNode(NULL, BAD_CAST "script");
- xmlSetProp(newfsscript, BAD_CAST "ref", BAD_CAST ninfo->script);
- if (newfs)
- xmlAddChild(newfs, newfsscript);
- else
- xmlAddChild(newnode, newfsscript);
- }
-
- /* Add the ip reference */
- if (ninfo->ip_addr)
- {
- newfsip = xmlNewNode(NULL, BAD_CAST "ip");
- xmlSetProp(newfsip, BAD_CAST "ref", BAD_CAST
- ninfo->ip_addr);
- if (newfs)
- xmlAddChild(newfs, newfsip);
- else
- xmlAddChild(newnode, newfsip);
- }
-}
-
-static void add_clusterfs(xmlNode *root_element, struct option_info *ninfo,
- int argc, char **argv, int optindex)
-{
- xmlNode *rm;
- xmlNode *rs;
- xmlNode *node;
-
- rm = findnode(root_element, "rm");
- if (!rm)
- die("Can't find \"rm\" in %s\n", ninfo->configfile);
-
- rs = findnode(rm, "resources");
- if (!rs)
- die("Can't find \"resources\" %s\n", ninfo->configfile);
-
- /* Check it doesn't already exist */
- if (find_fs_resource(rs, ninfo->name))
- die("fs %s already exists\n", ninfo->name);
-
- /* Add the new fs resource */
- node = xmlNewNode(NULL, BAD_CAST "fs");
- xmlSetProp(node, BAD_CAST "device", BAD_CAST ninfo->device);
- _xmlSetIntProp(node, "force_fsck", ninfo->force_fsck);
- _xmlSetIntProp(node, "force_unmount", ninfo->force_unmount);
- xmlSetProp(node, BAD_CAST "fstype", BAD_CAST ninfo->type);
- xmlSetProp(node, BAD_CAST "mountpoint", BAD_CAST ninfo->mountpoint);
- xmlSetProp(node, BAD_CAST "name", BAD_CAST ninfo->name);
- xmlSetProp(node, BAD_CAST "options", (ninfo->options) ?
- BAD_CAST ninfo->options : BAD_CAST "");
- _xmlSetIntProp(node, "self_fence", ninfo->self_fence);
- xmlAddChild(rs, node);
-}
-
-static void add_clusterfdomain(xmlNode *root_element, struct option_info *ninfo,
- int argc, char **argv, int optindex)
-{
- xmlNode *rm;
- xmlNode *fdomains;
- xmlNode *node;
- xmlNode *cn;
- int i = 0;
-
- rm = findnode(root_element, "rm");
- if (!rm)
- die("Can't find \"rm\" in %s\n", ninfo->configfile);
-
- fdomains = findnode(rm, "failoverdomains");
- if (!fdomains)
- die("Can't find \"failoverdomains\" %s\n", ninfo->configfile);
-
- cn = findnode(root_element, "clusternodes");
- if (!cn)
- die("Can't find \"clusternodes\" in %s\n", ninfo->configfile);
-
- /* Check it doesn't already exist */
- if (find_fdomain_resource(fdomains, ninfo->name))
- die("failover domain %s already exists\n", ninfo->name);
-
- /* Check that nodes are defined */
- while (ninfo->failover_nodes[i]) {
- if (!find_node(cn, ninfo->failover_nodes[i]))
- die("Can't find node %s in %s.\n",
- ninfo->failover_nodes[i], ninfo->configfile);
- i++;
- }
-
- /* Add the new failover domain */
- node = xmlNewNode(NULL, BAD_CAST "failoverdomain");
- xmlSetProp(node, BAD_CAST "name", BAD_CAST ninfo->name);
- _xmlSetIntProp(node, "ordered", ninfo->ordered);
- _xmlSetIntProp(node, "restricted", ninfo->restricted);
-
- i = 0;
- while (ninfo->failover_nodes[i]) {
- xmlNode *fnode = xmlNewNode(NULL, BAD_CAST "failoverdomainnode");
- xmlSetProp(fnode, BAD_CAST "name", BAD_CAST ninfo->failover_nodes[i]);
- _xmlSetIntProp(fnode, "priority", i + 1);
- xmlAddChild(node, fnode);
- i++;
- }
- xmlAddChild(fdomains, node);
-}
-
-static xmlDoc *open_configfile(struct option_info *ninfo)
-{
- xmlDoc *doc;
-
- /* Init libxml */
- xmlInitParser();
- LIBXML_TEST_VERSION;
-
- if (!ninfo->configfile)
- ninfo->configfile = DEFAULT_CONFIG_DIR "/" DEFAULT_CONFIG_FILE;
- if (!ninfo->outputfile)
- ninfo->outputfile = ninfo->configfile;
-
- /* Load XML document */
- doc = xmlParseFile(ninfo->configfile);
- if (doc == NULL)
- die("Error: unable to parse requested configuration file\n");
-
- return doc;
-
-}
-
-static void del_clusternode(xmlNode *root_element, struct option_info *ninfo)
-{
- xmlNode *clusternodes;
- xmlNode *oldnode;
-
- clusternodes = findnode(root_element, "clusternodes");
- if (!clusternodes)
- {
- fprintf(stderr, "Can't find \"clusternodes\" in %s\n", ninfo->configfile);
- exit(1);
- }
-
- oldnode = find_node(clusternodes, ninfo->name);
- if (!oldnode)
- {
- fprintf(stderr, "node %s does not exist in %s\n", ninfo->name, ninfo->configfile);
- exit(1);
- }
-
- xmlUnlinkNode(oldnode);
-}
-
-static void del_clusterservice(xmlNode *root_element, struct option_info *ninfo)
-{
- xmlNode *rm;
- xmlNode *oldnode;
-
- rm = findnode(root_element, "rm");
- if (!rm)
- {
- fprintf(stderr, "Can't find \"rm\" in %s\n", ninfo->configfile);
- exit(1);
- }
-
- oldnode = find_service(rm, ninfo->name);
- if (!oldnode)
- {
- fprintf(stderr, "service %s does not exist in %s\n", ninfo->name, ninfo->configfile);
- exit(1);
- }
-
- xmlUnlinkNode(oldnode);
-}
-
-static void del_clusterscript(xmlNode *root_element, struct option_info *ninfo)
-{
- xmlNode *rm, *rs;
- xmlNode *node;
-
- rm = findnode(root_element, "rm");
- if (!rm)
- {
- fprintf(stderr, "Can't find \"rm\" in %s\n", ninfo->configfile);
- exit(1);
- }
-
- rs = findnode(rm, "resources");
- if (!rs)
- {
- fprintf(stderr, "Can't find \"resources\" in %s\n", ninfo->configfile);
- exit(1);
- }
-
- /* Check that not used */
- node = find_script_ref(rm, ninfo->name);
- if (node)
- {
- fprintf(stderr, "Script %s is referenced in service in %s,"
- " please remove reference first.\n", ninfo->name,
- ninfo->configfile);
- exit(1);
- }
-
- node = find_script_resource(rs, ninfo->name);
- if (!node)
- {
- fprintf(stderr, "Script %s does not exist in %s\n", ninfo->name, ninfo->configfile);
- exit(1);
- }
-
- xmlUnlinkNode(node);
-}
-
-static void del_clusterip(xmlNode *root_element, struct option_info *ninfo)
-{
- xmlNode *rm, *rs;
- xmlNode *node;
-
- rm = findnode(root_element, "rm");
- if (!rm)
- {
- fprintf(stderr, "Can't find \"rm\" in %s\n", ninfo->configfile);
- exit(1);
- }
-
- rs = findnode(rm, "resources");
- if (!rs)
- {
- fprintf(stderr, "Can't find \"resources\" in %s\n", ninfo->configfile);
- exit(1);
- }
-
- /* Check that not used */
- node = find_ip_ref(rm, ninfo->name);
- if (node)
- {
- fprintf(stderr, "IP %s is referenced in service in %s,"
- " please remove reference first.\n", ninfo->name,
- ninfo->configfile);
- exit(1);
- }
-
- node = find_ip_resource(rs, ninfo->name);
- if (!node)
- {
- fprintf(stderr, "IP %s does not exist in %s\n", ninfo->name, ninfo->configfile);
- exit(1);
- }
-
- xmlUnlinkNode(node);
-}
-
-static void del_clusterfs(xmlNode *root_element, struct option_info *ninfo)
-{
- xmlNode *rm, *rs;
- xmlNode *node;
-
- rm = findnode(root_element, "rm");
- if (!rm)
- {
- fprintf(stderr, "Can't find \"rm\" in %s\n", ninfo->configfile);
- exit(1);
- }
-
- rs = findnode(rm, "resources");
- if (!rs)
- {
- fprintf(stderr, "Can't find \"resources\" in %s\n", ninfo->configfile);
- exit(1);
- }
-
- /* Check that not used */
- node = find_fs_ref(rm, ninfo->name);
- if (node)
- {
- fprintf(stderr, "fs %s is referenced in service in %s,"
- " please remove reference first.\n", ninfo->name,
- ninfo->configfile);
- exit(1);
- }
-
- node = find_fs_resource(rs, ninfo->name);
- if (!node)
- {
- fprintf(stderr, "fs %s does not exist in %s\n", ninfo->name, ninfo->configfile);
- exit(1);
- }
-
- xmlUnlinkNode(node);
-}
-
-static void del_clusterfdomain(xmlNode *root_element, struct option_info *ninfo)
-{
- xmlNode *rm, *fdomains;
- xmlNode *node;
-
- rm = findnode(root_element, "rm");
- if (!rm)
- {
- fprintf(stderr, "Can't find \"rm\" in %s\n", ninfo->configfile);
- exit(1);
- }
-
- fdomains = findnode(rm, "failoverdomains");
- if (!fdomains)
- {
- fprintf(stderr, "Can't find \"failoverdomains\" in %s\n", ninfo->configfile);
- exit(1);
- }
-
- /* Check that not used */
- node = find_fdomain_ref(rm, ninfo->name);
- if (node)
- {
- fprintf(stderr, "failover domain %s is referenced in service in %s,"
- " please remove reference first.\n", ninfo->name,
- ninfo->configfile);
- exit(1);
- }
-
- node = find_fdomain_resource(fdomains, ninfo->name);
- if (!node)
- {
- fprintf(stderr, "failover domain %s does not exist in %s\n", ninfo->name, ninfo->configfile);
- exit(1);
- }
-
- xmlUnlinkNode(node);
-}
-
-struct option addnode_options[] =
-{
- { "votes", required_argument, NULL, 'v'},
- { "nodeid", required_argument, NULL, 'n'},
- { "altname", required_argument, NULL, 'a'},
- { "fence_type", required_argument, NULL, 'f'},
- { "outputfile", required_argument, NULL, 'o'},
- { "configfile", required_argument, NULL, 'c'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option addfs_options[] =
-{
- { "type", required_argument, NULL, 't'},
- { "options", required_argument, NULL, 'p'},
- { "outputfile", required_argument, NULL, 'o'},
- { "configfile", required_argument, NULL, 'c'},
- { "force_fsck", no_argument, NULL, 'k'},
- { "force_unmount", no_argument, NULL, 'u'},
- { "self_fence", no_argument, NULL, 's'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option addfdomain_options[] =
-{
- { "outputfile", required_argument, NULL, 'o'},
- { "configfile", required_argument, NULL, 'c'},
- { "ordered", no_argument, NULL, 'p'},
- { "restricted", no_argument, NULL, 'r'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option commonw_options[] =
-{
- { "outputfile", required_argument, NULL, 'o'},
- { "configfile", required_argument, NULL, 'c'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option addnodeid_options[] =
-{
- { "outputfile", required_argument, NULL, 'o'},
- { "configfile", required_argument, NULL, 'c'},
- { "multicast", required_argument, NULL, 'm'},
- { "nodeid", no_argument, NULL, 'n'},
- { "verbose", no_argument, NULL, 'v'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option list_options[] =
-{
- { "configfile", required_argument, NULL, 'c'},
- { "verbose", no_argument, NULL, 'v'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option create_options[] =
-{
- { "configfile", required_argument, NULL, 'c'},
- { "nodes", required_argument, NULL, 'n'},
- { "fence", required_argument, NULL, 'f'},
- { "verbose", no_argument, NULL, 'v'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option addservice_options[] =
-{
- { "autostart", required_argument, NULL, 'a'},
- { "domain", required_argument, NULL, 'd'},
- { "exclusive", required_argument, NULL, 'x'},
- { "recovery", required_argument, NULL, 'r'},
- { "fs", required_argument, NULL, 'f'},
- { "script", required_argument, NULL, 's'},
- { "ip", required_argument, NULL, 'i'},
- { "outputfile", required_argument, NULL, 'o'},
- { "configfile", required_argument, NULL, 'c'},
- { NULL, 0, NULL, 0 },
-};
-
-static int parse_commonw_options(int argc, char **argv,
- struct option_info *ninfo)
-{
- int opt;
-
- memset(ninfo, 0, sizeof(*ninfo));
-
- while ( (opt = getopt_long(argc, argv, "o:c:h?", commonw_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo->configfile = strdup(optarg);
- break;
-
- case 'o':
- ninfo->outputfile = strdup(optarg);
- break;
-
- case '?':
- default:
- return 1;
- }
- }
- return 0;
-}
-
-static int next_nodeid(int startid, int *nodeids, int nodecount)
-{
- int i;
- int nextid = startid;
-
-retry:
- for (i=0; i<nodecount; i++)
- {
- if (nodeids[i] == nextid)
- {
- nextid++;
- goto retry;
- }
- }
-
- return nextid;
-}
-
-void add_nodeids(int argc, char **argv)
-{
- struct option_info ninfo;
- unsigned char *nodenames[MAX_NODES];
- xmlDoc *doc;
- xmlNode *root_element;
- xmlNode *clusternodes;
- xmlNode *cur_node;
- xmlNode *mcast;
- int verbose = 0;
- int opt;
- int i;
- int nodenumbers[MAX_NODES];
- int nodeidx;
- int totalnodes;
- int nextid;
-
- memset(nodenames, 0, sizeof(nodenames));
- memset(nodenumbers, 0, sizeof(nodenumbers));
- memset(&ninfo, 0, sizeof(ninfo));
- ninfo.nodeid = "1";
-
- while ( (opt = getopt_long(argc, argv, "n:o:c:m:vh?", addnodeid_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'n':
- validate_int_arg(opt, optarg);
- ninfo.nodeid = strdup(optarg);
- break;
-
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
-
- case 'o':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case 'm':
- if (!valid_mcast_addr(optarg)) {
- fprintf(stderr, "%s is not a valid multicast address\n", optarg);
- return;
- }
- ninfo.mcast_addr = strdup(optarg);
- break;
-
- case 'v':
- verbose++;
- break;
-
- case '?':
- default:
- addnodeid_usage(argv[0]);
- }
- }
-
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
-
- increment_version(root_element);
-
- /* Warn if the cluster doesn't have a multicast address */
- mcast = find_multicast_addr(root_element);
- if (!mcast & !ninfo.mcast_addr) {
- fprintf(stderr, "\nWARNING: The cluster does not have a multicast address.\n");
- fprintf(stderr, "A default will be assigned a run-time which might not suit your installation\n\n");
- }
-
- if (ninfo.mcast_addr) {
- if (!mcast) {
- xmlNode *cman = xmlNewNode(NULL, BAD_CAST "cman");
- mcast = xmlNewNode(NULL, BAD_CAST "multicast");
-
- xmlAddChild(cman, mcast);
- xmlAddChild(root_element, cman);
- }
- xmlSetProp(mcast, BAD_CAST "addr", BAD_CAST ninfo.mcast_addr);
- }
-
- /* Get a list of nodes that /do/ have nodeids so we don't generate
- any duplicates */
- nodeidx=0;
- clusternodes = findnode(root_element, "clusternodes");
- if (!clusternodes)
- die("Can't find \"clusternodes\" in %s\n", ninfo.configfile);
-
-
- for (cur_node = clusternodes->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0)
- {
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
- xmlChar *nodeid = xmlGetProp(cur_node, BAD_CAST "nodeid");
- nodenames[nodeidx] = name;
- if (nodeid)
- nodenumbers[nodeidx] = atoi((char*)nodeid);
- nodeidx++;
- }
- }
- totalnodes = nodeidx;
-
- /* Loop round nodes adding nodeIDs where they don't exist. */
- nextid = next_nodeid(atoi(ninfo.nodeid), nodenumbers, totalnodes);
- for (i=0; i<totalnodes; i++)
- {
- if (nodenumbers[i] == 0)
- {
- nodenumbers[i] = nextid;
- nextid = next_nodeid(nextid, nodenumbers, totalnodes);
- if (verbose)
- fprintf(stderr, "Node %s now has id %d\n", nodenames[i], nodenumbers[i]);
- }
- }
-
- /* Now write them into the tree */
- nodeidx = 0;
- for (cur_node = clusternodes->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0)
- {
- char tmp[80];
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
- assert(name);
-
- assert(strcmp((char*)nodenames[nodeidx], (char*)name) == 0);
-
- snprintf(tmp, sizeof(tmp), "%d", nodenumbers[nodeidx]);
- xmlSetProp(cur_node, BAD_CAST "nodeid", BAD_CAST tmp);
- nodeidx++;
- }
- }
-
-
- /* Write it out */
- save_file(doc, &ninfo);
-
- /* Shutdown libxml */
- xmlCleanupParser();
-}
-
-void add_node(int argc, char **argv)
-{
- struct option_info ninfo;
- int opt;
- xmlDoc *doc;
- xmlNode *root_element;
-
- memset(&ninfo, 0, sizeof(ninfo));
- ninfo.votes = "1";
-
- while ( (opt = getopt_long(argc, argv, "v:n:a:f:o:c:h?", addnode_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'v':
- validate_int_arg(opt, optarg);
- ninfo.votes = optarg;
- break;
-
- case 'n':
- validate_int_arg(opt, optarg);
- ninfo.nodeid = optarg;
- break;
-
- case 'a':
- ninfo.altname = strdup(optarg);
- break;
-
- case 'f':
- ninfo.fence_type = strdup(optarg);
- break;
-
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
-
- case 'o':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case '?':
- default:
- addnode_usage(argv[0]);
- }
- }
-
- /* Get node name parameter */
- if (optind < argc)
- ninfo.name = strdup(argv[optind]);
- else
- addnode_usage(argv[0]);
-
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
-
- increment_version(root_element);
-
- add_clusternode(root_element, &ninfo, argc, argv, optind);
-
- /* Write it out */
- save_file(doc, &ninfo);
- /* Shutdown libxml */
- xmlCleanupParser();
-
-}
-
-void del_node(int argc, char **argv)
-{
- struct option_info ninfo;
- xmlDoc *doc;
- xmlNode *root_element;
-
- if (parse_commonw_options(argc, argv, &ninfo))
- delnode_usage(argv[0]);
-
- /* Get node name parameter */
- if (optind < argc)
- ninfo.name = strdup(argv[optind]);
- else
- delnode_usage(argv[0]);
-
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
-
- increment_version(root_element);
-
- if (!strcmp(argv[0], "delnode"))
- del_clusternode(root_element, &ninfo);
- else if (!strcmp(argv[0], "delservice"))
- del_clusterservice(root_element, &ninfo);
- else if (!strcmp(argv[0], "delscript"))
- del_clusterscript(root_element, &ninfo);
- else if (!strcmp(argv[0], "delip"))
- del_clusterip(root_element, &ninfo);
- else if (!strcmp(argv[0], "delfs"))
- del_clusterfs(root_element, &ninfo);
- else if (!strcmp(argv[0], "delfdomain"))
- del_clusterfdomain(root_element, &ninfo);
-
- /* Write it out */
- save_file(doc, &ninfo);
-}
-
-void list_nodes(int argc, char **argv)
-{
- xmlNode *cur_node;
- xmlNode *root_element;
- xmlNode *clusternodes;
- xmlNode *fencenode = NULL;
- xmlDocPtr doc;
- xmlNode *mcast;
- struct option_info ninfo;
- int opt;
- int verbose = 0;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "c:vh?", list_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
- case 'v':
- verbose++;
- break;
- case '?':
- default:
- list_usage(argv[0]);
- }
- }
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
-
- printf("\nCluster name: %s, config_version: %s\n\n",
- (char *)cluster_name(root_element),
- (char *)find_version(root_element));
-
- clusternodes = findnode(root_element, "clusternodes");
- if (!clusternodes)
- die("Can't find \"clusternodes\" in %s\n", ninfo.configfile);
-
- mcast = find_multicast_addr(root_element);
- if (mcast)
- printf("Multicast address for cluster: %s\n\n", xmlGetProp(mcast, BAD_CAST "addr"));
-
- printf("Nodename Votes Nodeid Fencetype\n");
- for (cur_node = clusternodes->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0)
- {
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
- xmlChar *votes = xmlGetProp(cur_node, BAD_CAST "votes");
- xmlChar *nodeid = xmlGetProp(cur_node, BAD_CAST "nodeid");
- xmlChar *ftype = get_fence_type(cur_node, &fencenode);
-
- if (!nodeid)
- nodeid=(unsigned char *)"0";
- if (!votes)
- votes = (unsigned char *)"1";
-
- printf("%-32s %3d %3d %s\n", name, atoi((char *)votes),
- atoi((char *)nodeid),
- ftype?ftype:(xmlChar *)"");
- if (verbose)
- {
- xmlNode *a = findnode(cur_node, "altname");
- if (a)
- {
- printf(" altname %s=%s", "name", xmlGetProp(a, BAD_CAST "name"));
- if (!print_properties(a, "","",""))
- printf("\n");
- }
- print_properties(cur_node, " Node properties: ", "votes", "nodeid");
- print_properties(fencenode, " Fence properties: ", "agent", "");
- }
-
- }
- }
-}
-
-void add_service(int argc, char **argv)
-{
- struct option_info ninfo;
- int opt;
- xmlDoc *doc;
- xmlNode *root_element;
-
- memset(&ninfo, 0, sizeof(ninfo));
- ninfo.autostart = "1";
- ninfo.recovery = "relocate";
-
- while ( (opt = getopt_long(argc, argv, "a:d:x:r:f:o:c:s:i:h?", addservice_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'a':
- validate_int_arg(opt, optarg);
- ninfo.autostart = optarg;
- break;
-
- case 'd':
- ninfo.domain = strdup(optarg);
- break;
-
- case 'x':
- validate_int_arg(opt, optarg);
- ninfo.exclusive = optarg;
- break;
-
- case 'r':
- ninfo.recovery = strdup(optarg);
- break;
-
- case 'f':
- ninfo.fs = strdup(optarg);
- break;
-
- case 's':
- ninfo.script = strdup(optarg);
- break;
-
- case 'i':
- ninfo.ip_addr = strdup(optarg);
- break;
-
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
-
- case 'o':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case '?':
- default:
- addservice_usage(argv[0]);
- }
- }
-
- /* Get service name parameter */
- if (optind < argc)
- ninfo.name = strdup(argv[optind]);
- else
- addservice_usage(argv[0]);
-
-
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
-
- increment_version(root_element);
-
- add_clusterservice(root_element, &ninfo, argc, argv, optind);
-
- /* Write it out */
- save_file(doc, &ninfo);
- /* Shutdown libxml */
- xmlCleanupParser();
-
-}
-
-void list_services(int argc, char **argv)
-{
- xmlNode *cur_service;
- xmlNode *root_element;
- xmlNode *rm;
- xmlDocPtr doc;
- struct option_info ninfo;
- int opt;
- int verbose = 0;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "c:vh?", list_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
- case 'v':
- verbose++;
- break;
- case '?':
- default:
- list_usage(argv[0]);
- }
- }
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
-
- printf("\nCluster name: %s, config_version: %s\n\n",
- (char *)cluster_name(root_element),
- (char *)find_version(root_element));
-
- rm = findnode(root_element, "rm");
- if (!rm)
- die("Can't find \"rm\" in %s\n", ninfo.configfile);
-
- printf("Name Autostart Exclusive Recovery\n");
- for (cur_service = rm->children; cur_service;
- cur_service = cur_service->next)
- {
- xmlChar *name, *autostart, *exclusive, *recovery;
-
- if (!cur_service->type == XML_ELEMENT_NODE ||
- strcmp((char *)cur_service->name, "service") != 0)
- continue;
-
- name = xmlGetProp(cur_service, BAD_CAST "name");
- autostart = xmlGetProp(cur_service, BAD_CAST "autostart");
- exclusive = xmlGetProp(cur_service, BAD_CAST "exclusive");
- recovery = xmlGetProp(cur_service, BAD_CAST "recovery");
-
- if (!autostart)
- autostart = (unsigned char *)"0";
- if (!exclusive)
- exclusive = (unsigned char *)"0";
- if (!recovery)
- recovery = (unsigned char *)"-";
-
- printf("%-32s %3d %3d %s\n", name,
- atoi((char *)autostart), atoi((char *)exclusive),
- (char *)recovery);
- }
-}
-
-void add_script(int argc, char **argv)
-{
- struct option_info ninfo;
- xmlDoc *doc;
- xmlNode *root_element;
- xmlNode *rm, *rs, *node;
- char *name;
- char *sc_file;
-
- if (parse_commonw_options(argc, argv, &ninfo))
- addscript_usage(argv[0]);
-
- if (argc - optind < 2)
- addscript_usage(argv[0]);
-
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
-
- increment_version(root_element);
-
- rm = findnode(root_element, "rm");
- if (!rm)
- die("Can't find \"rm\" %s\n", ninfo.configfile);
-
- rs = findnode(rm, "resources");
- if (!rs)
- die("Can't find \"resources\" %s\n", ninfo.configfile);
-
- /* First param is the script name - check it doesn't already exist */
- name = argv[optind++];
- if (find_script_resource(rs, name))
- die("Script %s already exists\n", name);
- sc_file = argv[optind++];
-
- /* Add it */
- node = xmlNewNode(NULL, BAD_CAST "script");
- xmlSetProp(node, BAD_CAST "file", BAD_CAST sc_file);
- xmlSetProp(node, BAD_CAST "name", BAD_CAST name);
- xmlAddChild(rs, node);
-
- /* Write it out */
- save_file(doc, &ninfo);
-
- /* Shutdown libxml */
- xmlCleanupParser();
-}
-
-void add_ip(int argc, char **argv)
-{
- struct option_info ninfo;
- xmlDoc *doc;
- xmlNode *root_element;
- xmlNode *rm, *rs, *node;
-
- if (parse_commonw_options(argc, argv, &ninfo))
- addip_usage(argv[0]);
-
- if (optind < argc)
- ninfo.ip_addr = strdup(argv[optind]);
- else
- addip_usage(argv[0]);
-
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
-
- increment_version(root_element);
-
- rm = findnode(root_element, "rm");
- if (!rm)
- die("Can't find \"rm\" %s\n", ninfo.configfile);
-
- rs = findnode(rm, "resources");
- if (!rs)
- die("Can't find \"resources\" %s\n", ninfo.configfile);
-
- /* Check it doesn't already exist */
- if (find_ip_resource(rs, ninfo.ip_addr))
- die("IP %s already exists\n", ninfo.ip_addr);
-
- /* Add it */
- node = xmlNewNode(NULL, BAD_CAST "ip");
- xmlSetProp(node, BAD_CAST "address", BAD_CAST ninfo.ip_addr);
- xmlSetProp(node, BAD_CAST "monitor_link", BAD_CAST "1");
- xmlAddChild(rs, node);
-
- /* Write it out */
- save_file(doc, &ninfo);
-
- /* Shutdown libxml */
- xmlCleanupParser();
-}
-
-void add_fs(int argc, char **argv)
-{
- struct option_info ninfo;
- xmlDoc *doc;
- xmlNode *root_element;
- int opt;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "t:p:o:c:h?kus", addfs_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 't':
- ninfo.type = strdup(optarg);
- break;
-
- case 'p':
- ninfo.options = strdup(optarg);
- break;
-
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
-
- case 'o':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case 'k':
- ninfo.force_fsck = 1;
- break;
-
- case 'u':
- ninfo.force_unmount = 1;
- break;
-
- case 's':
- ninfo.self_fence = 1;
- break;
-
- case '?':
- default:
- addfs_usage(argv[0]);
- }
- }
-
- if (optind < argc - 2) {
- ninfo.name = strdup(argv[optind]);
- ninfo.device = strdup(argv[optind + 1]);
- ninfo.mountpoint = strdup(argv[optind + 2]);
- } else
- addfs_usage(argv[0]);
-
- if (!ninfo.type)
- ninfo.type = "ext3";
-
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
-
- increment_version(root_element);
-
- add_clusterfs(root_element, &ninfo, argc, argv, optind);
-
- /* Write it out */
- save_file(doc, &ninfo);
- /* Shutdown libxml */
- xmlCleanupParser();
-}
-
-void add_fdomain(int argc, char **argv)
-{
- struct option_info ninfo;
- xmlDoc *doc;
- xmlNode *root_element;
- int opt, i;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "pro:c:h?", addfdomain_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'p':
- ninfo.ordered = 1;
- break;
-
- case 'r':
- ninfo.restricted = 1;
- break;
-
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
-
- case 'o':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case '?':
- default:
- addfdomain_usage(argv[0]);
- }
- }
-
- if (optind < argc - 1) {
- ninfo.name = strdup(argv[optind]);
- ninfo.failover_nodes = (const char **)malloc(sizeof(char *) * (argc - optind));
- if (!ninfo.failover_nodes) {
- fprintf(stdout, "Out of mem!\n");
- exit(EXIT_FAILURE);
- }
- for (i = 0; i < argc - optind - 1; i++) {
- ninfo.failover_nodes[i] = strdup(argv[i + optind + 1]);
- assert(ninfo.failover_nodes[i]);
- }
- ninfo.failover_nodes[i] = NULL;
- } else
- addfdomain_usage(argv[0]);
-
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
-
- increment_version(root_element);
-
- add_clusterfdomain(root_element, &ninfo, argc, argv, optind);
-
- /* Write it out */
- save_file(doc, &ninfo);
- /* Shutdown libxml */
- xmlCleanupParser();
-
- for (i = 0; i < argc - optind - 1; i++)
- free((void *)ninfo.failover_nodes[i]);
-
- free(ninfo.failover_nodes);
-}
-
-void create_skeleton(int argc, char **argv)
-{
- char *fencename = NULL;
- char *clustername;
- struct option_info ninfo;
- struct stat st;
- FILE *outfile;
- int i;
- int twonode = 0;
- int numnodes=0;
- int opt;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "c:2hn:f:?", create_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case '2':
- twonode = 1;
- numnodes = 2;
- break;
- case 'n':
- numnodes = atoi(optarg);
- break;
- case 'f':
- fencename = strdup(optarg);
- break;
-
- case '?':
- default:
- create_usage(argv[0]);
- }
- }
- if (!ninfo.outputfile)
- ninfo.outputfile = DEFAULT_CONFIG_DIR "/" DEFAULT_CONFIG_FILE;
- ninfo.configfile = "-";
-
- if (argc - optind < 1)
- create_usage(argv[0]);
-
- clustername = argv[optind];
-
- if (stat(ninfo.outputfile, &st) == 0)
- die("%s already exists", ninfo.outputfile);
-
- /* Init libxml */
- outfile = fopen(ninfo.outputfile, "w+");
- if (!outfile) {
- perror(" Can't open output file");
- return;
- }
-
- fprintf(outfile, "<?xml version=\"1.0\"?>\n");
- fprintf(outfile, "<cluster name=\"%s\" config_version=\"1\">\n", clustername);
- fprintf(outfile, "\n");
- if (twonode) {
- fprintf(outfile, " <cman two_node=\"1\" expected_votes=\"1\"/>\n");
- }
-
- fprintf(outfile, " <clusternodes>\n");
- for (i=1; i <= numnodes; i++) {
- fprintf(outfile, " <clusternode name=\"NEEDNAME-%02d\" votes=\"1\" nodeid=\"%d\">\n", i, i);
- fprintf(outfile, " <fence>\n");
- fprintf(outfile, " <method name=\"single\">\n");
- if (fencename) {
- fprintf(outfile, " <device name=\"fence1\" ADDARGS/>\n");
- }
- fprintf(outfile, " </method>\n");
- fprintf(outfile, " </fence>\n");
- fprintf(outfile, " </clusternode>\n");
- }
- fprintf(outfile, " </clusternodes>\n");
- fprintf(outfile, "\n");
- fprintf(outfile, " <fencedevices>\n");
- if (fencename) {
- fprintf(outfile, " <fencedevice name=\"fence1\" agent=\"%s\" ADDARGS/>\n", fencename);
- }
- fprintf(outfile, " </fencedevices>\n");
- fprintf(outfile, "\n");
- fprintf(outfile, " <rm>\n");
- fprintf(outfile, " <failoverdomains/>\n");
- fprintf(outfile, " <resources/>\n");
- fprintf(outfile, " </rm>\n");
- fprintf(outfile, "</cluster>\n");
-
- fclose(outfile);
-}
-
-void add_fence(int argc, char **argv)
-{
- xmlNode *root_element;
- xmlNode *fencedevices;
- xmlNode *fencenode = NULL;
- xmlDocPtr doc;
- char *fencename;
- char *agentname;
- struct option_info ninfo;
-
- if (parse_commonw_options(argc, argv, &ninfo))
- addfence_usage(argv[0]);
-
- if (argc - optind < 2)
- addfence_usage(argv[0]);
-
- doc = open_configfile(&ninfo);
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
-
- increment_version(root_element);
-
- fencedevices = findnode(root_element, "fencedevices");
- if (!fencedevices)
- die("Can't find \"fencedevices\" %s\n", ninfo.configfile);
-
- /* First param is the fence name - check it doesn't already exist */
- fencename = argv[optind++];
-
- if (valid_fence_type(root_element, fencename))
- die("fence type %s already exists\n", fencename);
-
- agentname = argv[optind++];
-
- /* Add it */
- fencenode = xmlNewNode(NULL, BAD_CAST "fencedevice");
- xmlSetProp(fencenode, BAD_CAST "name", BAD_CAST fencename);
- xmlSetProp(fencenode, BAD_CAST "agent", BAD_CAST agentname);
-
- /* Add name=value options */
- add_fence_args(fencenode, argc, argv, optind);
-
- xmlAddChild(fencedevices, fencenode);
-
- save_file(doc, &ninfo);
-}
-
-void del_fence(int argc, char **argv)
-{
- xmlNode *root_element;
- xmlNode *fencedevices;
- xmlNode *fencenode;
- xmlDocPtr doc;
- char *fencename;
- struct option_info ninfo;
-
- if (parse_commonw_options(argc, argv, &ninfo))
- delfence_usage(argv[0]);
-
- if (argc - optind < 1)
- delfence_usage(argv[0]);
-
- fencename = argv[optind];
-
- doc = open_configfile(&ninfo);
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
- increment_version(root_element);
-
- fencedevices = findnode(root_element, "fencedevices");
- if (!fencedevices)
- die("Can't find \"fencedevices\" in %s\n", ninfo.configfile);
-
- fencenode = valid_fence_type(root_element, fencename);
- if (!fencenode)
- die("fence type %s does not exist\n", fencename);
-
- xmlUnlinkNode(fencenode);
-
- save_file(doc, &ninfo);
-}
-
-void list_fences(int argc, char **argv)
-{
- xmlNode *cur_node;
- xmlNode *root_element;
- xmlNode *fencedevices;
- xmlDocPtr doc;
- struct option_info ninfo;
- int opt;
- int verbose=0;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "c:hv?", list_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
- case 'v':
- verbose++;
- break;
- case '?':
- default:
- list_usage(argv[0]);
- }
- }
- doc = open_configfile(&ninfo);
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
-
- fencedevices = findnode(root_element, "fencedevices");
- if (!fencedevices)
- die("Can't find \"fencedevices\" in %s\n", ninfo.configfile);
-
-
- printf("Name Agent\n");
- for (cur_node = fencedevices->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "fencedevice") == 0)
- {
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
- xmlChar *agent = xmlGetProp(cur_node, BAD_CAST "agent");
-
- printf("%-16s %s\n", name, agent);
- if (verbose)
- print_properties(cur_node, " Properties: ", "agent", "");
- }
- }
-}
-
-void list_scripts(int argc, char **argv)
-{
- xmlNode *cur_node;
- xmlNode *root_element;
- xmlNode *rm, *rs;
- xmlDocPtr doc;
- struct option_info ninfo;
- int opt;
- int verbose=0;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "c:hv?", list_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
- case 'v':
- verbose++;
- break;
- case '?':
- default:
- list_usage(argv[0]);
- }
- }
- doc = open_configfile(&ninfo);
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
-
- rm = findnode(root_element, "rm");
- if (!rm)
- die("Can't find \"rm\" in %s\n", ninfo.configfile);
-
- rs = findnode(rm, "resources");
- if (!rs)
- die("Can't find \"resources\" in %s\n", ninfo.configfile);
-
- printf("Name Path\n");
- for (cur_node = rs->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "script") == 0)
- {
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
- xmlChar *path = xmlGetProp(cur_node, BAD_CAST "file");
-
- printf("%-16s %s\n", name, path);
- }
- }
-}
-
-void list_ips(int argc, char **argv)
-{
- xmlNode *cur_node;
- xmlNode *root_element;
- xmlNode *rm, *rs;
- xmlDocPtr doc;
- struct option_info ninfo;
- int opt;
- int verbose=0;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "c:hv?", list_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
- case 'v':
- verbose++;
- break;
- case '?':
- default:
- list_usage(argv[0]);
- }
- }
- doc = open_configfile(&ninfo);
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
- rm = findnode(root_element, "rm");
- if (!rm)
- die("Can't find \"rm\" in %s\n", ninfo.configfile);
-
- rs = findnode(rm, "resources");
- if (!rs)
- die("Can't find \"resources\" in %s\n", ninfo.configfile);
-
- printf("IP\n");
- for (cur_node = rs->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE &&
- strcmp((char *)cur_node->name, "ip") == 0)
- {
- xmlChar *ip = xmlGetProp(cur_node, BAD_CAST "address");
-
- printf("%s\n", ip);
- }
- }
-}
-
-void list_fs(int argc, char **argv)
-{
- xmlNode *cur_node;
- xmlNode *root_element;
- xmlNode *rm, *rs;
- xmlDocPtr doc;
- struct option_info ninfo;
- int opt;
- int verbose=0;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "c:hv?", list_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
- case 'v':
- verbose++;
- break;
- case '?':
- default:
- list_usage(argv[0]);
- }
- }
- doc = open_configfile(&ninfo);
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
-
- rm = findnode(root_element, "rm");
- if (!rm)
- die("Can't find \"rm\" in %s\n", ninfo.configfile);
-
- rs = findnode(rm, "resources");
- if (!rs)
- die("Can't find \"resources\" in %s\n", ninfo.configfile);
-
- printf("Name Type FUS Device Mountpoint\n");
- for (cur_node = rs->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE &&
- strcmp((char *)cur_node->name, "fs") == 0)
- {
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
- xmlChar *type = xmlGetProp(cur_node, BAD_CAST "fstype");
- xmlChar *force_fsck = xmlGetProp(cur_node,
- BAD_CAST "force_fsck");
- xmlChar *force_unmount = xmlGetProp(cur_node,
- BAD_CAST "force_unmount");
- xmlChar *self_fence = xmlGetProp(cur_node,
- BAD_CAST "self_fence");
- xmlChar *device = xmlGetProp(cur_node,
- BAD_CAST "device");
- xmlChar *mnt = xmlGetProp(cur_node,
- BAD_CAST "mountpoint");
-
- char f, u, s;
- INT_TO_CHAR(f, force_fsck)
- INT_TO_CHAR(u, force_unmount)
- INT_TO_CHAR(s, self_fence)
- printf("%-16.16s %-5.5s %c%c%c %-19.19s %s\n", name, type, f, u,
- s, device, mnt);
- }
- }
-}
-
-void list_fdomains(int argc, char **argv)
-{
- xmlNode *cur_node, *fnode;
- xmlNode *root_element;
- xmlNode *rm, *fdomains;
- xmlDocPtr doc;
- struct option_info ninfo;
- int opt;
- int verbose=0;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "c:hv?", list_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
- case 'v':
- verbose++;
- break;
- case '?':
- default:
- list_usage(argv[0]);
- }
- }
- doc = open_configfile(&ninfo);
- root_element = xmlDocGetRootElement(doc);
- assert(root_element);
- rm = findnode(root_element, "rm");
- if (!rm)
- die("Can't find \"rm\" in %s\n", ninfo.configfile);
-
- fdomains = findnode(rm, "failoverdomains");
- if (!fdomains)
- die("Can't find \"failoverdomains\" in %s\n", ninfo.configfile);
-
- printf("Name OR Nodes\n");
- for (cur_node = fdomains->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE &&
- strcmp((char *)cur_node->name, "failoverdomain") == 0)
- {
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
- xmlChar *ordered = xmlGetProp(cur_node, BAD_CAST "ordered");
- xmlChar *restricted = xmlGetProp(cur_node, BAD_CAST "restricted");
- char o, r;
- int first_node = 1;
-
- INT_TO_CHAR(o, ordered)
- INT_TO_CHAR(r, restricted)
- printf("%-16.16s %c%c ", name, o, r);
- for (fnode = cur_node->children; fnode; fnode = fnode->next)
- if (fnode->type == XML_ELEMENT_NODE &&
- strcmp((char *)fnode->name, "failoverdomainnode") == 0)
- {
- xmlChar *fname = xmlGetProp(fnode, BAD_CAST "name");
- if (first_node) {
- printf("%s", fname);
- first_node = 0;
- } else
- printf(",%s", fname);
- }
- printf("\n");
- }
- }
-}
diff --git a/config/tools/ccs_tool/editconf.h b/config/tools/ccs_tool/editconf.h
deleted file mode 100644
index 7edd52f..0000000
--- a/config/tools/ccs_tool/editconf.h
+++ /dev/null
@@ -1,18 +0,0 @@
-void add_node(int argc, char **argv);
-void add_nodeids(int argc, char **argv);
-void add_service(int argc, char **argv);
-void add_script(int argc, char **argv);
-void add_ip(int argc, char **argv);
-void add_fs(int argc, char **argv);
-void add_fdomain(int argc, char **argv);
-void add_fence(int argc, char **argv);
-void del_node(int argc, char **argv);
-void del_fence(int argc, char **argv);
-void list_nodes(int argc, char **argv);
-void list_services(int argc, char **argv);
-void list_fences(int argc, char **argv);
-void list_scripts(int argc, char **argv);
-void list_ips(int argc, char **argv);
-void list_fs(int argc, char **argv);
-void list_fdomains(int argc, char **argv);
-void create_skeleton(int argc, char **argv);
diff --git a/config/tools/ldap/Makefile b/config/tools/ldap/Makefile
deleted file mode 100644
index 1f0da3f..0000000
--- a/config/tools/ldap/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-TARGET= confdb2ldif
-
-SBINDIRT=$(TARGET)
-
-SUBDIRS=rng2ldif
-
-all: ${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
-include $(OBJDIR)/make/passthrough.mk
-
-OBJS= confdb2ldif.o
-
-CFLAGS += -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
-CFLAGS += -I${corosyncincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${corosynclibdir} -lconfdb
-LDFLAGS += -L${libdir}
-
-${TARGET}: ${OBJS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-clean: generalclean
-
--include $(OBJS:.o=.Tpo)
diff --git a/config/tools/ldap/confdb2ldif.c b/config/tools/ldap/confdb2ldif.c
deleted file mode 100644
index 8ab45b5..0000000
--- a/config/tools/ldap/confdb2ldif.c
+++ /dev/null
@@ -1,180 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <signal.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/un.h>
-
-#include <corosync/confdb.h>
-
-confdb_callbacks_t callbacks = {
-};
-
-static const char *ldap_attr_name(const char *attrname)
-{
- static char newname[1024];
- int i;
-
- if (strcmp(attrname, "name") == 0)
- return attrname;
-
- snprintf(newname, sizeof(newname) - 1, "rhcs");
- for (i=0; i<strlen(attrname)+1; i++) {
- if (i == 0)
- newname[4+i] = attrname[i] & 0x5F;
- else
- if (attrname[i] == '_')
- newname[4+i] = '-';
- else
- newname[4+i] = attrname[i];
- }
- return newname;
-}
-
-
-/* Recursively dump the object tree */
-static void print_config_tree(confdb_handle_t handle, hdb_handle_t parent_object_handle, const char *dn, char *fulldn)
-{
- hdb_handle_t object_handle;
- char object_name[1024];
- size_t object_name_len;
- char key_name[1024];
- char *key_value=NULL;
- confdb_value_types_t type;
- size_t key_value_len;
- char cumulative_dn[4096];
- int res;
- int keycount=0;
-
- printf("\ndn: %s\n", fulldn);
-
- /* Show the keys */
- res = confdb_key_iter_start(handle, parent_object_handle);
- if (res != CS_OK) {
- printf( "error resetting key iterator for object "HDB_X_FORMAT": %d\n", parent_object_handle, res);
- return;
- }
-
- while ( (res = confdb_key_iter_typed2(handle, parent_object_handle, key_name,
- (void**)&key_value, &key_value_len, &type)) == CS_OK) {
- key_value[key_value_len] = '\0';
-
- printf("%s: %s\n", ldap_attr_name(key_name), key_value);
- keycount++;
- free(key_value);
- key_value=NULL;
- }
- if (strncmp(fulldn, "cn=", 3) == 0) {
- printf("cn: %s\n", dn);
- }
-
-
- /* Determine objectclass... */
- if (keycount == 0) {
- printf("objectclass: nsContainer\n");
- }
- else {
- printf("objectclass: %s\n", ldap_attr_name(dn));
- }
-
- /* Show sub-objects */
- res = confdb_object_iter_start(handle, parent_object_handle);
- if (res != CS_OK) {
- printf( "error resetting object iterator for object "HDB_X_FORMAT": %d\n", parent_object_handle, res);
- return;
- }
-
- while ( (res = confdb_object_iter(handle, parent_object_handle, &object_handle, object_name, &object_name_len)) == CS_OK) {
- hdb_handle_t parent;
-
- res = confdb_object_parent_get(handle, object_handle, &parent);
- if (res != CS_OK) {
- printf( "error getting parent for object "HDB_X_FORMAT": %d\n", object_handle, res);
- return;
- }
-
- object_name[object_name_len] = '\0';
-
- /* Check for "name", and create dummy parent object */
- res = confdb_key_get_typed2(handle, object_handle, "name", (void **)&key_value, &key_value_len, &type);
- if (res == CS_OK) {
- snprintf(cumulative_dn, sizeof(cumulative_dn) - 1, "cn=%s,%s", object_name, fulldn);
- printf("\n");
- printf("dn: %s\n", cumulative_dn);
- printf("cn: %s\n", object_name);
- printf("objectclass: %s\n", "nsContainer");
-
- snprintf(cumulative_dn, sizeof(cumulative_dn) - 1, "name=%s,cn=%s,%s", key_value, object_name, fulldn);
- free(key_value);
- key_value = NULL;
- }
- else {
- snprintf(cumulative_dn, sizeof(cumulative_dn) - 1, "cn=%s,%s", object_name, fulldn);
- }
-
- /* Down we go ... */
- print_config_tree(handle, object_handle, object_name, cumulative_dn);
- }
-}
-
-
-int main(int argc, char *argv[])
-{
- confdb_handle_t handle;
- int result;
- hdb_handle_t cluster_handle;
- const char *clusterroot = "cluster";
- char basedn[1024];
-
- if (argc == 1) {
- fprintf(stderr, "usage: \n");
- fprintf(stderr, " %s <dn> [<objdb root>]\n", argv[0]);
- fprintf(stderr, "\n");
- fprintf(stderr, " eg: \n");
- fprintf(stderr, " %s dc=mycompany,dc=com\n", argv[0]);
- fprintf(stderr, " %s dc=mycompany,dc=com rhcluster\n", argv[0]);
- fprintf(stderr, "\n");
- fprintf(stderr, "objdb root defaults to 'cluster'\n");
- fprintf(stderr, "\n");
- return 0;
- }
-
- if (argc > 2) {
- clusterroot = argv[2];
- }
-
- result = confdb_initialize (&handle, &callbacks);
- if (result != CS_OK) {
- printf ("Could not initialize Cluster Configuration Database API instance error %d\n", result);
- exit (1);
- }
-
- /* Find the starting object ... this should be a param */
-
- result = confdb_object_find_start(handle, OBJECT_PARENT_HANDLE);
- if (result != CS_OK) {
- printf ("Could not start object_find %d\n", result);
- exit (1);
- }
-
- result = confdb_object_find(handle, OBJECT_PARENT_HANDLE, clusterroot, strlen(clusterroot), &cluster_handle);
- if (result != CS_OK) {
- printf ("Could not object_find \"cluster\": %d\n", result);
- exit (1);
- }
-
- snprintf(basedn, sizeof(basedn) - 1, "name=%s,%s", clusterroot, argv[1]);
-
- /* Print a header */
- printf("# This file was generated by confdb2ldif, from an existing cluster configuration\n");
- printf("#\n");
-
- /* Print the configuration */
- print_config_tree(handle, cluster_handle, clusterroot, basedn);
-
-
- result = confdb_finalize (handle);
- return (0);
-}
diff --git a/config/tools/ldap/rng2ldif/Makefile b/config/tools/ldap/rng2ldif/Makefile
deleted file mode 100644
index 54e7556..0000000
--- a/config/tools/ldap/rng2ldif/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-TARGET1= rng2ldif
-TARGET2= genclass
-
-all: ${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 += -I.
-CFLAGS += `xml2-config --cflags`
-CFLAGS += -I${incdir}
-
-LDFLAGS += `xml2-config --libs`
-LDFLAGS += -L${libdir}
-
-OBJS1= rng2ldif.o \
- tree.o
-
-OBJS2= genclass.o
-
-SHAREDOBJS= zalloc.o \
- value-list.o \
- ldaptypes.o \
- name.o
-
-${TARGET1}: ${SHAREDOBJS} ${OBJS1}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-${TARGET2}: ${SHAREDOBJS} ${OBJS2}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-ldif-update: all $(SRCDIR)/config/plugins/ldap/ldap-base.csv
- make -C $(OBJDIR)/config/tools/xml cluster.rng
- ./rng2ldif $(OBJDIR)/config/tools/xml/cluster.rng \
- $(SRCDIR)/config/plugins/ldap/ldap-base.csv \
- $(SRCDIR)/config/plugins/ldap/99cluster.ldif
-
-clean: generalclean
-
--include $(OBJS1:.o=.Tpo)
--include $(OBJS2:.o=.Tpo)
--include $(SHAREDOBJS:.o=.Tpo)
diff --git a/config/tools/ldap/rng2ldif/debug.h b/config/tools/ldap/rng2ldif/debug.h
deleted file mode 100644
index 907e096..0000000
--- a/config/tools/ldap/rng2ldif/debug.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _DEBUG_H
-#define _DEBUG_H
-
-#ifdef DEBUG
-#define dbg_printf printf
-#else
-#define dbg_printf(args...)
-#endif
-
-#endif
diff --git a/config/tools/ldap/rng2ldif/genclass.c b/config/tools/ldap/rng2ldif/genclass.c
deleted file mode 100644
index dd69401..0000000
--- a/config/tools/ldap/rng2ldif/genclass.c
+++ /dev/null
@@ -1,106 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include "value-list.h"
-#include "tree.h"
-
-
-static void
-id_gen_object_struct(struct idinfo *oi, FILE *fp)
-{
- struct idval *v;
-
- fprintf(fp, "struct objectclasses\n");
- fprintf(fp, "{\n");
- fprintf(fp, "\tchar *name;\n");
- fprintf(fp, "\tchar *class;\n");
- fprintf(fp, "} objectclasses[] = \n");
- fprintf(fp, "{\n");
-
- for (v = oi->head; v->next; v = v->next) {
- if (v->type != OBJ)
- continue;
- fprintf(fp, "\t{ \"%s\", \"%s\" }, \n",
- v->rawname, v->name);
- }
-
- fprintf(fp, "\t{ \"%s\", \"%s\" }\n};\n",
- v->rawname, v->name);
-}
-
-
-static int
-write_class_struct(char *csv, char *arg, struct idinfo *ids)
-{
- char filename[4096];
- FILE *out = NULL;
- int fd = -1;
- mode_t oldumask;
-
- if (!strcmp(arg, "-")) {
- out = stdout;
- } else {
- oldumask=umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
- snprintf(filename, sizeof(filename), "%s.XXXXXX", arg);
- fd = mkstemp(filename);
- umask(oldumask);
- if (fd < 0) {
- perror("mkstemp");
- return -1;
- }
-
- out = fdopen(fd, "w");
- if (out == NULL) {
- perror("fdopen");
- close(fd);
- return -1;
- }
- }
-
- fprintf(out, "/* Begin autogenerated class struct from %s */\n", csv);
- id_gen_object_struct(ids, out);
- fprintf(out, "/* End autogenerated class struct */\n");
-
- fflush(out);
-
- if (fd >= 0) {
- fsync(fd);
- fclose(out);
- close(fd);
- rename(filename, arg);
- }
-
- return 0;
-}
-
-
-int
-main(int argc, char **argv)
-{
- struct idinfo info;
-
- memset(&info, 0, sizeof(info));
-
- if (argc < 3) {
- printf("Translate csv -> C structure\n"
- "file for future reuse of IDs\n");
- printf("Usage: %s file.csv output.c\n",
- argv[0]);
- return 1;
- }
-
- if (id_readfile(&info, argv[1]) < 0) {
- printf("Can't read %s\n", argv[1]);
- return 1;
- }
-
- write_class_struct(argv[1], argv[2], &info);
-
- return 0;
-}
diff --git a/config/tools/ldap/rng2ldif/ldaptypes.c b/config/tools/ldap/rng2ldif/ldaptypes.c
deleted file mode 100644
index beb0de9..0000000
--- a/config/tools/ldap/rng2ldif/ldaptypes.c
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include "ldaptypes.h"
-#include "debug.h"
-
-struct type_entry {
- const char *rng_name;
- const char *ldap_equality;
- const char *ldap_syntax;
-};
-
-
-struct type_entry type_table[] = {
-{ "boolean", "booleanMatch", "1.3.6.1.4.1.1466.115.121.1.7" },
-{ "integer", "integerMatch", "1.3.6.1.4.1.1466.115.121.1.27" },
-{ "positiveInteger", "integerMatch", "1.3.6.1.4.1.1466.115.121.1.27" },
-{ "nonNegativeInteger", "integerMatch", "1.3.6.1.4.1.1466.115.121.1.27" },
-{ "string", "caseExactIA5Match", "1.3.6.1.4.1.1466.115.121.1.26" },
-{ "ID", "caseExactIA5Match", "1.3.6.1.4.1.1466.115.121.1.26" },
-{ NULL, "caseExactIA5Match", "1.3.6.1.4.1.1466.115.121.1.26" } };
-
-
-void
-find_ldap_type_info(const char *name,
- char **equality,
- char **syntax)
-{
- int x;
-
- for (x = 0; type_table[x].rng_name != NULL; x++)
- if (!strcasecmp(name, type_table[x].rng_name))
- break;
- dbg_printf("%s @ index %d\n", name, x);
-
- *equality = (char *)type_table[x].ldap_equality;
- *syntax = (char *)type_table[x].ldap_syntax;
-}
-
-
-#ifdef STANDALONE
-#include <stdio.h>
-int
-main(int argc, char **argv)
-{
- char *eq, *syn;
-
- find_ldap_type_info(argv[1], &eq, &syn);
-
- printf("EQUALITY %s\nSYNTAX %s\n", eq, syn);
-
- return 0;
-}
-#endif
diff --git a/config/tools/ldap/rng2ldif/ldaptypes.h b/config/tools/ldap/rng2ldif/ldaptypes.h
deleted file mode 100644
index 1546cf3..0000000
--- a/config/tools/ldap/rng2ldif/ldaptypes.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _LDAPTYPES_H
-#define _LDAPTYPES_H
-
-void find_ldap_type_info(const char *name,
- char **equality,
- char **syntax);
-
-#endif
diff --git a/config/tools/ldap/rng2ldif/name.c b/config/tools/ldap/rng2ldif/name.c
deleted file mode 100644
index 8cc5ef7..0000000
--- a/config/tools/ldap/rng2ldif/name.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <ctype.h>
-#include "name.h"
-#include "zalloc.h"
-
-char *
-normalize_name(const char *name)
-{
- char *ret_val;
- int size = 4, x;
-
- if (!strcasecmp(name, "name")) {
- ret_val = strdup(name);
- assert(ret_val!=NULL);
- goto out;
- }
-
- size = strlen(name)+5;
- ret_val = zalloc(size); /* 1 byte for null, 4 for rhcs */
- if (!ret_val)
- return NULL;
-
- snprintf(ret_val, size, "rhcs%s", name);
-
-out:
- for (x = 0; x < 4; x++)
- ret_val[x] |= 32;
- if (ret_val[4] == '_')
- ret_val[4] = '-';
- else
- ret_val[4] &= ~32;
- for (x = 5; x < size; x++) {
- if (ret_val[x] == '_') {
- ret_val[x] = '-';
- }
- }
-
- return ret_val;
-}
-
-#ifdef STANDALONE
-int
-main(int argc, char **argv)
-{
- char *val;
- if (argc < 2)
- return -1;
-
- val = normalize_name(argv[1]);
- if (!val)
- fprintf(stderr, "oops\n");
- printf("%s\n", val);
- free(val);
- return 0;
-}
-#endif
diff --git a/config/tools/ldap/rng2ldif/name.h b/config/tools/ldap/rng2ldif/name.h
deleted file mode 100644
index a332b45..0000000
--- a/config/tools/ldap/rng2ldif/name.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _NAME_H
-#define _NAME_H
-
-char *normalize_name(const char *name);
-
-#endif
diff --git a/config/tools/ldap/rng2ldif/rng2ldif.c b/config/tools/ldap/rng2ldif/rng2ldif.c
deleted file mode 100644
index 635d4c8..0000000
--- a/config/tools/ldap/rng2ldif/rng2ldif.c
+++ /dev/null
@@ -1,242 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <unistd.h>
-#include <time.h>
-
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include "value-list.h"
-#include "tree.h"
-
-
-struct faux_list {
- struct faux_list *next;
-};
-
-
-static void __attribute__((noinline))
-reverse(struct faux_list **list)
-{
- struct faux_list *node = NULL;
- struct faux_list *newlist = NULL;
-
- if (!list || (*list == NULL))
- return;
-
- while ((*list) != NULL) {
- node = *list;
- *list = node->next;
- node->next = newlist;
- newlist = node;
- }
- *list = node;
-}
-
-
-static int
-print_attr_node(FILE *fp, struct ldap_attr_node *node)
-{
- if (!node)
- return -1;
- if (!fp)
- fp = stdout;
-
- if (!strcasecmp(node->name, "name")) {
- /* Don't print 'name' out as an attr. */
- return 0;
- }
-
- fprintf(fp, "attributeTypes: (\n");
- fprintf(fp, " 1.3.6.1.4.1.2312.8.1.1.%d NAME '%s'\n",
- node->idval->value, node->name);
- fprintf(fp, " EQUALITY %s\n", node->ldap_equality);
- fprintf(fp, " SYNTAX %s\n", node->ldap_syntax);
- fprintf(fp, " SINGLE-VALUE\n )\n");
- return 0;
-}
-
-
-static int
-print_obj_node(FILE *fp, struct ldap_object_node *node)
-{
- struct ldap_attr_meta_node *n;
- const char *cmt = "";
-
- if (!node)
- return -1;
- if (!fp)
- fp = stdout;
-
- if (!node->required_attrs && !node->optional_attrs) {
- cmt = "#";
- fprintf(fp, "### Placeholder for %s\n", node->name);
- fprintf(fp,
- "### This object class currently has no attributes\n");
- }
-
- fprintf(fp, "%sobjectClasses: (\n", cmt);
- fprintf(fp, "%s 1.3.6.1.4.1.2312.8.1.2.%d NAME '%s' SUP top STRUCTURAL\n", cmt, node->idval->value, node->name);
-
- if (node->required_attrs) {
- fprintf(fp, "%s MUST ( ", cmt);
-
- if (node->need_cn) {
- fprintf(fp, "cn $ ");
- }
-
- for (n = node->required_attrs; n->next != NULL; n = n->next)
- fprintf(fp, "%s $ ", n->node->name);
- fprintf(fp, "%s )\n", n->node->name);
- } else {
- if (node->need_cn) {
- fprintf(fp, "%s MUST ( cn )\n", cmt);
- }
- }
-
- if (node->optional_attrs) {
- fprintf(fp, "%s MAY ( ", cmt);
- for (n = node->optional_attrs; n->next != NULL; n = n->next)
- fprintf(fp, "%s $ ", n->node->name);
- fprintf(fp, "%s )\n", n->node->name);
- }
- fprintf(fp, "%s )\n", cmt);
- return 0;
-}
-
-
-static xmlDocPtr
-open_relaxng(const char *filename)
-{
- xmlDocPtr p;
- xmlNodePtr n;
-
- p = xmlParseFile(filename);
- if (!p) {
- printf("Failed to parse %s\n", filename);
- }
-
- n = xmlDocGetRootElement(p);
- if (!n) {
- printf("Unable to determine xml root element\n");
- xmlFreeDoc(p);
- return NULL;
- }
-
- if (xmlStrcmp(n->name, (xmlChar *)"grammar")) {
- printf("%s is not a relaxng grammar\n", filename);
- xmlFreeDoc(p);
- return NULL;
- }
-
- return p;
-}
-
-
-static int
-write_ldap_schema(const char *rng, const char *arg,
- struct ldap_attr_node *attrs,
- struct ldap_object_node *objs)
-{
- struct ldap_attr_node *attr = NULL;
- struct ldap_object_node *obj = NULL;
- char filename[4096];
- FILE *out_ldap = NULL;
- char now_asc[128];
- time_t now;
- struct tm now_tm;
- int fd = -1;
- mode_t oldumask;
-
- if (!strcmp(arg, "-")) {
- out_ldap = stdout;
- } else {
- oldumask=umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
- snprintf(filename, sizeof(filename), "%s.XXXXXX", arg);
- fd = mkstemp(filename);
- umask(oldumask);
- if (fd < 0) {
- perror("mkstemp");
- return -1;
- }
-
- out_ldap = fdopen(fd, "w");
- if (out_ldap == NULL) {
- perror("fdopen");
- close(fd);
- return -1;
- }
- }
-
- now = time(NULL);
- memset(&now_tm, 0, sizeof(now_tm));
- if (localtime_r(&now, &now_tm) == NULL) {
- snprintf(now_asc, sizeof(now_asc), "???");
- } else {
- strftime(now_asc, sizeof(now_asc), "%F %T", &now_tm);
- }
-
- fprintf(out_ldap, "# Auto-generated @ %s\n", now_asc);
- fprintf(out_ldap, "dn: cn=schema\n");
-
- for (attr = attrs; attr; attr = attr->next)
- print_attr_node(out_ldap, attr);
- for (obj = objs; obj; obj= obj->next)
- print_obj_node(out_ldap, obj);
-
- fflush(out_ldap);
-
- if (fd >= 0) {
- fsync(fd);
- fclose(out_ldap);
- close(fd);
- rename(filename, arg);
- }
-
- return 0;
-}
-
-
-int
-main(int argc, char **argv)
-{
- struct ldap_attr_node *attrs = NULL;
- struct ldap_object_node *objs = NULL;
- struct idinfo info;
- xmlDocPtr doc;
-
- memset(&info, 0, sizeof(info));
-
- if (argc < 4) {
- printf("Translate cluster RelaxNG -> LDIF schema and update\n"
- "global .csv file for future reuse of IDs\n");
- printf("Usage: %s cluster.rng ldap-base.csv cluster.ldif\n",
- argv[0]);
- return 1;
- }
-
- doc = open_relaxng(argv[1]);
- if (doc == NULL) {
- printf("Cannot continue\n");
- return 1;
- }
-
- if (id_readfile(&info, argv[2]) < 0) {
- printf("Can't read %s\n", argv[2]);
- return 1;
- }
-
- find_objects(xmlDocGetRootElement(doc), &objs, &attrs, &info);
-
- reverse((struct faux_list **)&attrs);
- reverse((struct faux_list **)&objs);
-
- if (write_ldap_schema(argv[1], argv[3], attrs, objs) < 0)
- return -1;
-
- id_writefile(&info, argv[2]);
-
- return 0;
-}
diff --git a/config/tools/ldap/rng2ldif/tree.c b/config/tools/ldap/rng2ldif/tree.c
deleted file mode 100644
index 7c63124..0000000
--- a/config/tools/ldap/rng2ldif/tree.c
+++ /dev/null
@@ -1,469 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/xpath.h>
-#include <assert.h>
-
-#include "zalloc.h"
-#include "value-list.h"
-#include "tree.h"
-#include "name.h"
-#include "ldaptypes.h"
-#include "debug.h"
-
-
-static struct ldap_attr_node *
-find_attr_byname(struct ldap_attr_node *attrs, const char *name)
-{
- struct ldap_attr_node *n;
-
- for (n = attrs; n; n = n->next) {
- if (!strcmp(n->name, name))
- return n;
- }
- return NULL;
-}
-
-
-static struct ldap_attr_meta_node *
-find_meta_attr(struct ldap_attr_meta_node *metas, struct ldap_attr_node *attr)
-{
- struct ldap_attr_meta_node *n;
-
- for (n = metas; n; n = n->next) {
- if (n->node == attr)
- return n;
- }
- return NULL;
-}
-
-
-static struct ldap_attr_meta_node *
-find_meta_attr_byname(struct ldap_attr_meta_node *metas, const char *name)
-{
- struct ldap_attr_meta_node *n;
-
- for (n = metas; n; n = n->next) {
- if (!strcmp(n->node->name, name))
- return n;
- }
- return NULL;
-}
-
-
-static int
-find_data_match_fn(xmlNodePtr curr_node, char **match_fn, char **ldap_syntax)
-{
- xmlNodePtr n = NULL;
- char *type = NULL;
- int need_free = 1;
-
- for (n = curr_node; n; n = n->next) {
- if (!n->name ||
- strcasecmp((char *)n->name, "data"))
- continue;
- break;
- }
-
- if (n)
- type = (char *)xmlGetProp(n, (xmlChar *)"type");
-
- dbg_printf("type %s\n", type);
-
- if (!type) {
- type = (char *)"string";
- need_free = 0;
- }
-
- find_ldap_type_info(type, match_fn, ldap_syntax);
-
- if (need_free)
- xmlFree(type);
-
- return 1;
-}
-
-
-static struct ldap_attr_node *
-get_attr(xmlNodePtr curr_node, struct ldap_attr_node **attrs,
- struct idinfo *ids)
-{
- struct ldap_attr_node *n;
- struct idval *v;
- char *name, *normalized;
-
- name = (char *)xmlGetProp(curr_node, (xmlChar *)"name");
- if (!name) {
- return NULL;
- }
-
- normalized = normalize_name((const char *)name);
-
- n = find_attr_byname(*attrs, normalized);
- if (n) {
- free(normalized);
- return n;
- }
-
- n = zalloc(sizeof(*n));
-
- v = id_find(ids, normalized, ATTR, 0);
- if (!v) {
- v = zalloc(sizeof(*v));
- v->name = normalized;
- v->type = ATTR;
- v->rawname = (char *)name;
- id_insert(ids, v);
- } else {
- free(normalized);
- }
-
- n->idval = v;
- n->name = n->idval->name;
-
- dbg_printf("Lookin for data type for %s\n", n->name);
- find_data_match_fn(curr_node->xmlChildrenNode, &n->ldap_equality,
- &n->ldap_syntax);
-
- n->next = *attrs;
- *attrs = n;
-
- return n;
-}
-
-
-static struct ldap_object_node *
-find_obj(struct ldap_object_node *objs, const char *name)
-{
- struct ldap_object_node *n;
-
- for (n = objs; n; n = n->next) {
- if (!strcmp(n->name, name))
- return n;
- }
- return NULL;
-}
-
-
-static xmlNodePtr
-find_ref(xmlNodePtr curr_node)
-{
- xmlNodePtr n;
- char *name;
- char *tmp_name;
-
- dbg_printf("Trying to parse ref tag\n");
- name = (char *)xmlGetProp(curr_node, (xmlChar *)"name");
- if (!name) {
- fprintf(stderr, "Unable to determine xml name prop\n");
- exit(1);
- }
-
- n = xmlDocGetRootElement(curr_node->doc);
- if (!n) {
- fprintf(stderr, "Unable to determine xml root element\n");
- exit(1);
- }
- n = n->xmlChildrenNode;
- for (; n; n = n->next) {
- if (n->type != XML_ELEMENT_NODE)
- continue;
- if (strcasecmp((char *)n->name, "define"))
- continue;
-
- tmp_name = (char *)xmlGetProp(n, (xmlChar *)"name");
- if (!tmp_name)
- continue;
- if (strcmp(tmp_name, name))
- continue;
-
- break;
- }
-
- if (!n) {
- fprintf(stderr, "Error in RelaxNG schema!\n");
- fprintf(stderr, "Unterminated reference: %s\n",
- name);
- exit(1);
- }
-
- return n->xmlChildrenNode;
-}
-
-
-static int
-find_optional_attributes(xmlNodePtr curr_node, int in_block,
- struct ldap_object_node *curr_obj,
- struct ldap_attr_node **attrs,
- struct idinfo *ids)
-{
- xmlNodePtr node;
- struct ldap_attr_node *attr;
- struct ldap_attr_meta_node *n = NULL;
-
- if (!curr_node || (curr_node->type == XML_ELEMENT_NODE &&
- (curr_node->name && !strcasecmp((char *)curr_node->name, "element")))) {
- return 0;
- }
-
- dbg_printf("lookin for optionals\n");
-
- for (node = curr_node; node; node = node->next) {
- if (node->type != XML_ELEMENT_NODE)
- continue;
-
- if (!node->name)
- continue;
-
- if (strcmp((char *)node->name, "attribute"))
- continue;
-
- if (!strcasecmp((char *)node->name, "ref")) {
- find_optional_attributes(
- find_ref(node), 1, curr_obj, attrs, ids);
- }
- if (!strcasecmp((char *)node->name, "choice")) {
- find_optional_attributes(node->xmlChildrenNode, 1,
- curr_obj,
- attrs, ids);
- continue;
- }
- if (!strcasecmp((char *)node->name, "group")) {
- find_optional_attributes(node->xmlChildrenNode, 1,
- curr_obj,
- attrs, ids);
- continue;
- }
- if (!strcasecmp((char *)node->name, "optional")) {
- find_optional_attributes(node->xmlChildrenNode, 1,
- curr_obj,
- attrs, ids);
- continue;
- }
-
- if (!in_block)
- continue;
-
- attr = get_attr(node, attrs, ids);
- if (!n) {
- n = zalloc(sizeof(*n));
- assert(n);
- }
-
- dbg_printf("opt attr '%s'\n", attr->idval->name);
-
- if (find_meta_attr(curr_obj->required_attrs,
- attr)) {
- dbg_printf("skipping dup attr\n");
- continue;
- }
- if (find_meta_attr(curr_obj->optional_attrs,
- attr)) {
- dbg_printf("skipping dup attr on optional list\n");
- continue;
- }
-
- n->node = attr;
- n->next = curr_obj->optional_attrs;
- curr_obj->optional_attrs = n;
- n=NULL;
- }
-
- if (n) {
- free(n);
- n=NULL;
- }
- return 0;
-}
-
-
-static int
-find_required_attributes(xmlNodePtr curr_node,
- struct ldap_object_node *curr_obj,
- struct ldap_attr_node **attrs,
- struct idinfo *ids)
-{
- xmlNodePtr node;
- struct ldap_attr_node *attr;
- struct ldap_attr_meta_node *n = NULL;
-
- dbg_printf("lookin for required\n");
-
- for (node = curr_node; node; node = node->next) {
- if (node->type != XML_ELEMENT_NODE)
- continue;
- if (xmlStrcmp(node->name, (xmlChar *)"attribute"))
- continue;
-
- attr = get_attr(node, attrs, ids);
- if (!n) {
- n = zalloc(sizeof(*n));
- assert(n);
- }
-
- dbg_printf("req attr '%s'\n", attr->idval->name);
-
- if (find_meta_attr(curr_obj->required_attrs,
- attr)) {
- dbg_printf("skipping dup attr\n");
- continue;
- }
- if (find_meta_attr(curr_obj->optional_attrs,
- attr)) {
- dbg_printf("skipping dup attr on optional list\n");
- continue;
- }
-
- n->node = attr;
- n->next = curr_obj->required_attrs;
- curr_obj->required_attrs = n;
- n=NULL;
- }
-
- if (n) {
- free(n);
- n=NULL;
- }
- return 0;
-}
-
-
-static struct ldap_object_node *
-parse_element_tag(xmlNodePtr curr_node,
- struct ldap_object_node **objs,
- struct ldap_attr_node **attrs,
- struct idinfo *ids)
-{
- struct ldap_object_node *obj;
- char *n, *normalized;
- struct idval *v;
- int need_cn = 1;
-
- dbg_printf("Trying to parse element tag\n");
- n = (char *)xmlGetProp(curr_node, (xmlChar *)"name");
- if (!n) {
- printf("Unable to parse element tag\n");
- exit(1);
- }
- normalized = normalize_name(n);
- v = id_find(ids, normalized, OBJ, 0);
-
- if (!v) {
- v = zalloc(sizeof(*v));
- v->name = normalized;
- v->rawname = n;
- v->type = OBJ;
- id_insert(ids, v);
- }
-
- obj = find_obj(*objs, v->name);
-
- if (!obj) {
- obj = zalloc(sizeof(*obj));
- obj->name = v->name;
- obj->idval = v;
- obj->next = *objs;
- *objs = obj;
- dbg_printf("New object class %s \n",obj->name);
- }
-
- find_optional_attributes(curr_node->xmlChildrenNode, 0,
- obj, attrs, ids);
- find_required_attributes(curr_node->xmlChildrenNode,
- obj, attrs, ids);
-
- if (find_meta_attr_byname(obj->required_attrs, "name") ||
- find_meta_attr_byname(obj->required_attrs, "cn")) {
- need_cn = 0;
- }
-
- if (need_cn &&
- (find_meta_attr_byname(obj->optional_attrs, "name") ||
- find_meta_attr_byname(obj->optional_attrs, "cn"))) {
- need_cn = 0;
- }
-
- if (need_cn) {
- dbg_printf("Object class might %s need 'MUST ( cn )' for proper LDIF\n", obj->name);
- obj->need_cn = 1;
- }
-
- return obj;
-}
-
-
-#if 0
-static struct ldap_object_node *
-parse_ref_tag(xmlNodePtr curr_node,
- struct ldap_object_node **objs,
- struct ldap_attr_node **attrs,
- struct idinfo *ids)
-{
- xmlXPathObjectPtr xobj;
- xmlXPathContextPtr xctx;
- char query[1024];
- char *n;
-
- dbg_printf("Trying to parse ref tag\n");
- n = (char *)xmlGetProp(curr_node, (xmlChar *)"name");
-
- snprintf(query, sizeof(query), "//define[@name=\"%s\"]", n);
- xctx = xmlXPathNewContext(curr_node->doc);
- assert(xctx);
- xobj = xmlXPathEvalExpression((xmlChar *)query, xctx);
-
- printf("%d nodes match %s\n", xobj->nodesetval->nodeNr, query);
-
- assert(0);
- return NULL;
-}
-#endif
-
-int
-find_objects(xmlNodePtr curr_node,
- struct ldap_object_node **objs,
- struct ldap_attr_node **attrs,
- struct idinfo *ids)
-{
- struct ldap_object_node *obj = NULL;
- int ret = 0;
-
- if (!curr_node)
- /* no objects found */
- return 0;
-
- for (; curr_node; curr_node = curr_node->next) {
- if (curr_node->type != XML_ELEMENT_NODE)
- continue;
- if (!strcasecmp((char *)curr_node->name, "element")) {
- obj = parse_element_tag(curr_node, objs, attrs, ids);
- ret = 1;
- } else {
- dbg_printf("Descend on %s\n", curr_node->name);
- }
-
- if (find_objects(curr_node->xmlChildrenNode,
- objs, attrs, ids)) {
- ret = 1;
- } else if (obj) {
- /*
- * We have an object, but when we
- * looked for children, it did not
- * have any. So, we can omit the
- * requirement for 'cn' in the
- * output LDIF here
- */
- if (obj->need_cn) {
- dbg_printf("Object class %s does not have"
- " any children; not outputting "
- "'MUST ( cn )'\n", obj->name);
- }
- obj->need_cn = 0;
- }
- }
-
- /* Child objects were found */
- return ret;
-}
diff --git a/config/tools/ldap/rng2ldif/tree.h b/config/tools/ldap/rng2ldif/tree.h
deleted file mode 100644
index f55c556..0000000
--- a/config/tools/ldap/rng2ldif/tree.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef _TREE_H
-#define _TREE_H
-
-struct ldap_attr_list {
- struct ldap_attr_node *head, *tail;
-};
-
-struct ldap_attr_node {
- struct ldap_attr_node *next;
- char *name; /* self->idval->name; do not free() */
- char *desc;
- char *ldap_equality;
- char *ldap_syntax;
- struct idval *idval;
-};
-
-struct ldap_attr_meta_node {
- struct ldap_attr_meta_node *next;
- struct ldap_attr_node *node;
-};
-
-struct ldap_object_node {
- struct ldap_object_node *next;
- char *name; /* self->idval->name; do not free() */
- char *desc;
- struct idval *idval;
- struct ldap_attr_meta_node *optional_attrs;
- struct ldap_attr_meta_node *required_attrs;
- int need_cn; /* If we don't have a 'name' or a 'cn' attribute,
- add one when we output the LDIF */
-};
-
-int
-find_objects(xmlNodePtr curr_node,
- struct ldap_object_node **objs,
- struct ldap_attr_node **attrs,
- struct idinfo *ids);
-
-
-#endif
diff --git a/config/tools/ldap/rng2ldif/value-list.c b/config/tools/ldap/rng2ldif/value-list.c
deleted file mode 100644
index 010503a..0000000
--- a/config/tools/ldap/rng2ldif/value-list.c
+++ /dev/null
@@ -1,206 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "value-list.h"
-#include "zalloc.h"
-
-void
-id_insert(struct idinfo *i, struct idval *v)
-{
- if (v->type == ATTR) {
- if (v->value > i->max_attr)
- i->max_attr = v->value;
- if (!v->value)
- v->value = ++i->max_attr;
- } else /* if type == OBJ */ {
- if (v->value > i->max_obj)
- i->max_obj = v->value;
- if (!v->value)
- v->value = ++i->max_obj;
- }
-
- if (!i->head)
- i->head = v;
- if (i->tail)
- i->tail->next = v;
- i->tail = v;
-}
-
-
-struct idval *
-id_find(struct idinfo *oi, const char *val, int type, int id)
-{
- struct idval *v;
-
- if (!val && !id)
- return NULL;
-
- /* linear search */
- for (v = oi->head; v; v = v->next) {
- if (v->type != type)
- continue;
- if (val && !strcmp(val, v->name))
- return v;
- if (id && id == v->value)
- return v;
- }
-
- return NULL;
-}
-
-
-void
-id_dump(struct idinfo *oi, FILE *fp)
-{
- struct idval *v;
-
- fprintf(fp, "# Max attribute value: %d\n", oi->max_attr);
- fprintf(fp, "# Max object class value: %d\n", oi->max_obj);
-
- for (v = oi->head; v; v = v->next) {
- fprintf(fp, "%s,%s,%s,%d\n", v->type==OBJ?"obj":"attr",
- v->name, v->rawname, v->value);
- }
-}
-
-
-
-int
-id_writefile(struct idinfo *oi, char *filename)
-{
- char tmpfn[4096];
- FILE *fp = NULL;
- int fd;
- mode_t oldumask;
-
- oldumask=umask(S_IWGRP | S_IRGRP | S_IWOTH | S_IROTH);
-
- snprintf(tmpfn, sizeof(tmpfn), "%s.XXXXXX", filename);
- fd = mkstemp(tmpfn);
- umask(oldumask);
- if (fd < 0)
- return -1;
-
- fp = fdopen(fd, "w");
- if (!fp) {
- close(fd);
- unlink(tmpfn);
- return -1;
- }
-
- id_dump(oi, fp);
- fflush(fp);
- fsync(fd);
- fclose(fp);
- close(fd);
-
- /* done */
- rename(tmpfn, filename);
-
- return 0;
-}
-
-
-int
-id_readfile(struct idinfo *oi, char *filename)
-{
- char *c, *valp;
- struct idval *v;
- struct idval *tmp;
- FILE *fp;
- char buf[4096];
- int len, lineno = 0, entries = 0;
-
- if (!filename) {
- perror("no file?");
- return 1;
- }
-
- fp = fopen(filename, "r");
- if (!fp) {
- perror("fopen");
- return 1;
- }
-
- while (fgets(buf, sizeof(buf), fp)) {
- ++lineno;
- if (!strlen(buf))
- continue;
- if (buf[0] == '#')
- continue;
- len = strlen(buf);
- while (buf[len-1] < ' ') {
- buf[len-1] = 0;
- --len;
- }
- v = zalloc(sizeof(*v));
- assert(v);
-
- /* Attribute / object */
- c = strchr(buf, ',');
- if (!c || strlen(c) == 1) {
- fprintf(stderr,
- "%s: Malformed input on line %d: '%s'\n",
- filename, lineno, buf);
- exit(-2);
- }
-
- *c = 0;
- c++;
- if (!strncasecmp(buf, "attr",4)) {
- v->type = ATTR;
- } else if (!strncasecmp(buf, "obj", 3)) {
- v->type = OBJ;
- } else {
- fprintf(stderr, "%s: Unknown type on line %d: '%s'\n",
- filename, lineno, buf);
- exit(-2);
- }
-
- valp = strchr(c, ',');
- if (valp) {
- *valp = 0;
- valp++;
- }
- v->name = strdup(c);
- assert(v->name);
-
- c = valp;
- assert(c);
-
- valp = strchr(c, ',');
- v->value = 0;
- if (valp) {
- *valp = 0;
- valp++;
- if (strlen(valp))
- v->value = atoi(valp);
- }
-
- v->rawname = strdup(c);
- assert(v->rawname);
-
- if (!id_find(oi, v->name, v->type, 0)) {
- tmp = id_find(oi, NULL, v->type, v->value);
- if (tmp) {
- fprintf(stderr, "%s: Duplicate id value: "
- "%d & %d, type %d\n", filename,
- tmp->value, v->value, v->type);
- exit(-1);
- }
- id_insert(oi, v);
- }
-
- ++entries;
- free(v);
- v = NULL;
- }
-
- fclose(fp);
-
- return 0;
-}
diff --git a/config/tools/ldap/rng2ldif/value-list.h b/config/tools/ldap/rng2ldif/value-list.h
deleted file mode 100644
index 2e43326..0000000
--- a/config/tools/ldap/rng2ldif/value-list.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _VALUE_LIST_H
-#define _VALUE_LIST_H
-
-struct idval {
- struct idval *next;
- char *name;
- char *rawname;
- int type;
- int value;
-};
-
-struct idinfo {
- struct idval *head;
- struct idval *tail;
- int max_obj;
- int max_attr;
-};
-
-void id_insert(struct idinfo *i, struct idval *v);
-struct idval * id_find(struct idinfo *oi, const char *val, int type, int id);
-void id_dump(struct idinfo *oi, FILE *fp);
-int id_readfile(struct idinfo *oi, char *filename);
-int id_writefile(struct idinfo *oi, char *filename);
-
-#define OBJ 1
-#define ATTR 0
-
-#endif
diff --git a/config/tools/ldap/rng2ldif/zalloc.c b/config/tools/ldap/rng2ldif/zalloc.c
deleted file mode 100644
index f05306d..0000000
--- a/config/tools/ldap/rng2ldif/zalloc.c
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <malloc.h>
-#include <string.h>
-#include <assert.h>
-#include "zalloc.h"
-
-void *
-zalloc(size_t size)
-{
- void *ret;
- size_t oddball;
-
- oddball = ( size % sizeof(void *) );
- if (oddball) {
- size -= oddball;
- size += sizeof(void *);
- }
-
- ret = malloc(size);
- if (!ret)
- assert(0);
- memset(ret, 0, size);
- return ret;
-}
diff --git a/config/tools/ldap/rng2ldif/zalloc.h b/config/tools/ldap/rng2ldif/zalloc.h
deleted file mode 100644
index 0992ec2..0000000
--- a/config/tools/ldap/rng2ldif/zalloc.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ZALLOC_H
-#define _ZALLOC_H
-
-void *zalloc(size_t size);
-
-#endif
diff --git a/config/tools/man/Makefile b/config/tools/man/Makefile
deleted file mode 100644
index 5faaf6b..0000000
--- a/config/tools/man/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-MANTARGET= \
- ccs_config_dump.8 \
- ccs_config_validate.8 \
- ccs_update_schema.8 \
- ccs_tool.8 \
- confdb2ldif.8
-
-include ../../../make/defines.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-all:
-
-clean:
diff --git a/config/tools/man/ccs_config_dump.8 b/config/tools/man/ccs_config_dump.8
deleted file mode 100644
index e31d3ce..0000000
--- a/config/tools/man/ccs_config_dump.8
+++ /dev/null
@@ -1,35 +0,0 @@
-.TH "ccs_config_dump" "8" "" "" ""
-.SH "NAME"
-ccs_config_dump \- Tool to generate XML output of running configuration.
-
-.SH "SYNOPSIS"
-.B ccs_config_dump
-[\fIOPTION\fR]..
-
-.SH "DESCRIPTION"
-
-\fBccs_config_dump\fP is part of the Cluster Configuration System (CCS).
-It is used to dump the current running configuration in XML format.
-The running configuration is, sometimes, different from the stored
-configuration on file or ldap because some subsystems store or set
-some default information into the configuration. Those values are
-generally not present on the on-disk version of the configuration
-but are required at runtime for the cluster to work properly.
-
-.SH "OPTIONS"
-.TP
-\fB\-h\fP
-Help. Print out the usage.
-.TP
-\fB\-V\fP
-Print the version information.
-.TP
-\fB\-r\fP
-Force config dump from running cluster. This option is only for expert users
-and debugging sessions. Don't use it for random purposes.
-ccs_config_dump can be configured to use different configuration sources via
-environment variables. This option will clear them to use the default and use
-only the runtime configuration.
-
-.SH "SEE ALSO"
-ccs_config_validate(8), cluster.conf(5)
diff --git a/config/tools/man/ccs_config_validate.8 b/config/tools/man/ccs_config_validate.8
deleted file mode 100644
index ac78178..0000000
--- a/config/tools/man/ccs_config_validate.8
+++ /dev/null
@@ -1,56 +0,0 @@
-.TH CCS_CONFIG_VALIDATE "8" "September 2009"
-.SH NAME
-ccs_config_validate
-.SH DESCRIPTION
-Usage:
-.PP
-ccs_config_validate [options]
-.SH OPTIONS
-.TP
-\fB\-h\fR
-Print this help, then exit
-.TP
-\fB\-V\fR
-Print program version information, then exit
-.TP
-\fB\-v\fR
-Produce verbose output
-.SS "Validating XML configuraton files:"
-.TP
-\fB\-f\fR configfile
-Validate an alternate config file without preloading it with default values.
-.TP
-\fB\-l\fR configfile
-Validate an alternate config file with preloading of default values (recommended option).
-.SS "Advanced options:"
-.TP
-\fB\-u\fR
-Do not update relaxng schema (see ccs_update_schema.8)
-.HP
-.TP
-\fB\-r\fR
-Force validation of runtime config
-.HP
-\fB\-C\fR config_loader
-Override config plugin loader
-.TP
-\fB\-t\fR tempfile
-Force temporay file to tempfile
-.TP
-\fB\-n\fR
-Do not remove temporary file
-.TP
-\fB\-o\fR
-Overwrite temporary file (dangerous)
-.SH "DEFAULT"
-Default operation for ccs_config_validate is to load the currently configured environment
-and verify the outcoming configuration.
-.TP
-Example 1: current environment uses a configuration file (/etc/cluster/cluster.conf).
-The user modifies cluser.conf and executes ccs_config_validate without options.
-The tool will validate the modified cluster.conf after including default values.
-.TP
-Example 2: current environment is set to load the configuration from LDAP. Users
-modifies LDAP databse and before pushing the change to the nodes, she/he can issue
-ccs_config_validate to verify the contents o the LDAP database automatically
-(as long as the correct LDAP environment is set in the cman/cluster sysconfig/defaults files).
diff --git a/config/tools/man/ccs_tool.8 b/config/tools/man/ccs_tool.8
deleted file mode 100644
index 0f52f18..0000000
--- a/config/tools/man/ccs_tool.8
+++ /dev/null
@@ -1,151 +0,0 @@
-.TH "ccs_tool" "8" "" "" ""
-.SH "NAME"
-ccs_tool \- The tool used to make online queries to the cluster configuration.
-
-.SH "SYNOPSIS"
-.B ccs_tool
-[\fIOPTION\fR].. <\fBcommand\fP>
-
-.SH "DESCRIPTION"
-
-\fBccs_tool\fP is part of the Cluster Configuration System (CCS). It used
-to peform different kind of queries to the cluster configuration and has support
-for some cluster.conf editing functions.
-
-.SH "OPTIONS"
-.TP
-\fB\-h\fP
-Help. Print out the usage.
-.TP
-\fB\-V\fP
-Print the version information.
-
-sub\-commands have their own options, see below for more detail
-.SH "COMMANDS"
-
-.TP
-\fBquery\fP \fI<xpath query>\fP
-Perform an xpath query on running cluster configuration.
-
-.TP
-\fBaddnode\fP [options] \fI<node> [<fenceoption=value>]...\fP
-Adds a new node to the cluster configuration file. Fencing device options
-are specified as key=value pairs (as many as required) and are entered into the
-configuration file as is. See the documentation for your fencing agent for more
-details (eg a powerswitch fence device may need to know which port the node is
-connected to).
-.br
-\fIOptions:\fP
-.br
-\-v <votes> Number of votes for this node (mandatory)
-.br
-\-n <nodeid> Node id for this node (optional)
-.br
-\-i <interface> Network interface to use for this node. Mandatory if the cluster
-is using multicast as transport. Forbidden if not.
-.br
-\-m <multicast> Multicast address for cluster. Only allowed on the first node to
-be added to the file. Subsequent nodes will use either multicast or broadcast
-depending on the properties of the first node.
-.br
-\-f <fencedevice> Name of fence device to use for this node. The fence device
-section must already have been added to the file, probably using the addfence command.
-.br
-\-c <file> Config file to use. Defaults to /etc/cluster/cluster.conf
-.br
-\-o <file> Output file. Defaults to the same as -c
-
-
-
-.TP
-\fBdelnode\fP [options] \fI<node>\fP
-Delete a node from the cluster configuration file. Note: there is no
-"edit" command so to change the properties of a node you must delete it
-and add it back in with the new properties.
-.br
-\fIOptions:\fP
-.br
-\-c <file> Config file to use. Defaults to /etc/cluster/cluster.conf
-.br
-\-o <file> Output file. Defaults to the same as -c
-
-
-
-.TP
-\fBaddfence\fP [options] \fI<name> <agent> [<option>=<value>]...\fP
-Adds a new fence device section to the cluster configuration file. <agent> is the
-name of the fence agent that controls the device. the options following are entered
-as key-value pairs. See the fence agent documentation for details about these. eg:
-you may need to enter the IP address and username/password for a powerswitch fencing
-device.
-.br
-\fIOptions:\fP
-.br
-\-c <file> Config file to use. Defaults to /etc/cluster/cluster.conf
-.br
-\-o <file> Output file. Defaults to the same as -c
-
-.TP
-\fBdelfence\fP [options] \fI<node>\fP
-Deletes a fencing device from the cluster configuration file.
-delfence will allow you to remove a fence device that is in use by nodes.
-This is to allow changes to be made, but be aware that it may produce an
-invalid configuration file if you don't add it back in again.
-.br
-\fIOptions:\fP
-.br
-\-c <file> Config file to use. Defaults to /etc/cluster/cluster.conf
-.br
-\-o <file> Output file. Defaults to the same as -c
-
-
-.TP
-\fBlsnode [options] \fP
-List the nodes in the configuration file. This is (hopefully obviously) not
-necessarily the same as the nodes currently in the cluster, but it should
-be a superset.
-.br
-\fIOptions:\fP
-.br
-\-v Verbose. Lists all the properties of the node, and the
-node-specific properties of the fence device too.
-.br
-\-c <file> Config file to use. Defaults to /etc/cluster/cluster.conf
-
-
-.TP
-\fBlsfence [options] \fP
-List all the fence devices in the cluster configuration file.
-.br
-\fIOptions:\fP
-.br
-\-v Verbose. Lists all the properties of the fence device rather
-than just the names and agents.
-.br
-\-c <file> Config file to use. Defaults to /etc/cluster/cluster.conf
-
-
-.TP
-\fBcreate [options] \fP \fI<clustername>\fP
-Create a new, skeleton, configuration file. Note that "create" on its own will
-not create a valid configuration file. Fence agents and nodes will need to be
-added to it before handing it over to ccsd. The new configuration file will
-have a version number of 1. Subsequent addnode/delnode/addfence/delfence operations
-will increment the version number by 1 each time.
-.br
-\fIOptions:\fP
-.br
-.br
-\-c <file> Config file to create. Defaults to /etc/cluster/cluster.conf
-
-.TP
-\fBaddnodeids\fP
-Adds node ID numbers to all the nodes in cluster.conf. In RHEL4, node IDs were optional
-and assigned by cman when a node joined the cluster. In RHEL5 they must be pre-assigned
-in cluster.conf. This command will not change any node IDs that are already set in
-cluster.conf, it will simply add unique node ID numbers to nodes that do not already
-have them.
-
-
-.SH "SEE ALSO"
-cluster.conf(5)
diff --git a/config/tools/man/ccs_update_schema.8 b/config/tools/man/ccs_update_schema.8
deleted file mode 100644
index 3467c9c..0000000
--- a/config/tools/man/ccs_update_schema.8
+++ /dev/null
@@ -1,29 +0,0 @@
-.TH "ccs_update_schema" "8" "" "" ""
-.SH "NAME"
-ccs_update_schema \- Tool to generate cluster relaxng schema for cluster config validation.
-
-.SH "SYNOPSIS"
-.B ccs_update_schema
-[\fIOPTION\fR]..
-
-.SH "DESCRIPTION"
-
-\fBccs_update_schema\fP is part of the Cluster Configuration System (CCS).
-It is used to update the cluster relaxng schema that validates cluster.conf.
-
-.SH "OPTIONS"
-.TP
-\fB\-h\fP
-Help. Print out the usage.
-.TP
-\fB\-V\fP
-Print the version information.
-.TP
-\fB\-v\fP
-Be verbose. Mostly for debugging purposes.
-.TP
-\fB\-f\fP
-Ignore local stored cache and regenerate a fresh schema.
-
-.SH "SEE ALSO"
-ccs_config_validate(8), cluster.conf(5)
diff --git a/config/tools/man/confdb2ldif.8 b/config/tools/man/confdb2ldif.8
deleted file mode 100644
index 2964eec..0000000
--- a/config/tools/man/confdb2ldif.8
+++ /dev/null
@@ -1,64 +0,0 @@
-.TH confdb2ldif 8
-
-.SH NAME
-confdb2ldif - Create an LDIF file from a cluster configuration
-
-.SH SYNOPSIS
-.B confdb2ldap <basedn> [<config object base>]
-
-.SH DESCRIPTION
-\fBconfdb2ldif\fP reads the cluster configuration from the openais object database
-and generates an LDIF file suitable for importing into an LDAP database. The LDIF
-file is written to standard output.
-
-.SH OPTIONS
-.TP
-\fB<basedn>\fP
-This is the base DN of the LDAP server into which the configuration will be imported.
-confdb2ldif will create a "cn=cluster" object below this to contain the cluster configuration.
-The base DN is usually derived from the host's domain name. So if the host is ldapsrv.mycorp.com
-then the base DN could be dc=mycorp,dc=com.
-.TP
-\fB[<config object base>]\fP
-Configuration object in the objdb to start from. This defaults to "cluster" and
-there should rarely be any need to change it.
-
-.SH COMMENTS
-\fBconfdb2ldif\fP uses the openais libconfdb to read the configuration. The default way to
-do this is run against a running aisexec to read the live configuration.
-It is possible to generate an LDIF file from a non-running system by using the standalone feature of openais's libconfdb.
-.br
-eg to read the configuration from /etc/cluster/cluster.conf, use the following command:
-
-.nf
-OPENAIS_DEFAULT_CONFIG_IFACE=xmlconfig:cmanpreconfig confdb2ldif dc=mycompany,dc=com
-.fi
-
-or to do it from CCS
-
-.nf
-OPENAIS_DEFAULT_CONFIG_IFACE=ccsconfig:cmanpreconfig confdb2ldif dc=mycompany,dc=com
-.fi
-
-The LDIF file is written to stdout and so can be saved or piped straight into ldapmodify if required.
-.br
-.br
-It's important that the 99cluster.ldif schema file has been loaded into the LDAP server
-before adding the contents of this generated LDIF file.
-
-.SH EXAMPLE
-
-.nf
-confdb2ldif dc=mycorp,dc=com | ldapmodify -x -a -D"cn=Directory Manager" -c -v -W
-.fi
-
-.SH BUGS
-\fBconfdb2ldif\fP parses the cluster configuration without checking it against the loaded
-schema. So if there are attributes in the config file that are not known to the schema,
-parts of the load will fail. It is important to check the results of feeding the
-output into ldapmodify. In particular aisexec logging operations will not convert
-into LDIF because they rely on duplicate keys.
-
-
-.SH SEE ALSO
-libconfdb(3), openais(8), cluster.conf(5)
diff --git a/config/tools/xml/Makefile b/config/tools/xml/Makefile
deleted file mode 100644
index 3c9e97c..0000000
--- a/config/tools/xml/Makefile
+++ /dev/null
@@ -1,47 +0,0 @@
-include ../../../make/defines.mk
-
-TARGET1 = ccs_config_dump
-TARGET2 = ccs_config_validate
-TARGET3 = ccs_update_schema
-TARGET4 = cluster.rng
-
-SBINDIRT = $(TARGET1) $(TARGET2) $(TARGET3)
-SHAREDIRSYMT = $(TARGET4)
-RELAXNGDIRT = cluster.rng.in.head cluster.rng.in.tail
-
-all: $(TARGET1) $(TARGET2) $(TARGET3) $(TARGET4)
-
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-OBJS = ccs_config_dump.o
-
-CFLAGS += -I${corosyncincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${corosynclibdir} -lconfdb
-LDFLAGS += -L${libdir}
-
-${TARGET1}: ${OBJS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-${TARGET2}: $(S)/${TARGET2}.in
- cat $(S)/$(TARGET2).in | sed \
- -e 's#@SBINDIR@#${sbindir}#g' \
- -e 's#@SHAREDIR@#${sharedir}#g' \
- -e 's#@VERSION@#${RELEASE_VERSION}#g' \
- > $(TARGET2)
-
-${TARGET3}: $(S)/${TARGET3}.in
- cat $(S)/$(TARGET3).in | sed \
- -e 's#@SBINDIR@#${sbindir}#g' \
- -e 's#@SHAREDIR@#${sharedir}#g' \
- -e 's#@VERSION@#${RELEASE_VERSION}#g' \
- > $(TARGET3)
-
-${TARGET4}:
- ln -sf /var/lib/cluster/cluster.rng ${TARGET4}
-
-clean: generalclean
diff --git a/config/tools/xml/ccs_config_dump.c b/config/tools/xml/ccs_config_dump.c
deleted file mode 100644
index 165257d..0000000
--- a/config/tools/xml/ccs_config_dump.c
+++ /dev/null
@@ -1,187 +0,0 @@
-#include <stdio.h>
-#include <limits.h>
-#include <unistd.h>
-#include <corosync/corotypes.h>
-#include <corosync/confdb.h>
-
-#include "copyright.cf"
-
-#define OPTION_STRING "hVr"
-
-static confdb_callbacks_t callbacks = {};
-
-static int dump_objdb_buff(confdb_handle_t dump_handle, hdb_handle_t cluster_handle,
- hdb_handle_t parent_object_handle, int level)
-{
- hdb_handle_t object_handle;
- char object_name[PATH_MAX], key_name[PATH_MAX];
- char *key_value=NULL;
- size_t key_value_len = 0, object_name_len = 0;
- int current_level = level+1;
- int has_children = 0;
- confdb_value_types_t type;
-
- if (confdb_key_iter_start(dump_handle, parent_object_handle) != CS_OK)
- return -1;
-
- while (confdb_key_iter_typed2(dump_handle, parent_object_handle, key_name,
- (void**)&key_value,
- &key_value_len, &type) == CS_OK) {
- int char_pos = 0;
-
- key_value[key_value_len] = '\0';
- printf(" %s=\"", key_name);
- for (char_pos = 0; char_pos < key_value_len-1; char_pos++) {
- switch (key_value[char_pos]) {
-
- case '&':
- printf("&");
- break;
- case '<':
- printf("<");
- break;
- case '>':
- printf(">");
- break;
- case '"':
- printf(""");
- break;
- case '\'':
- printf("'");
- break;
- default:
- putchar(key_value[char_pos]);
- break;
- }
- }
- printf("\"");
- free(key_value);
- key_value = NULL;
- }
-
- if (confdb_object_iter_start(dump_handle, parent_object_handle) != CS_OK)
- return -1;
-
- while (confdb_object_iter(dump_handle, parent_object_handle,
- &object_handle, object_name,
- &object_name_len) == CS_OK) {
- hdb_handle_t parent;
- int i;
- int found_children;
-
- if ((!has_children) && (parent_object_handle > 0))
- printf(">\n");
-
- has_children = 1;
-
- if (confdb_object_parent_get(dump_handle, object_handle, &parent) != CS_OK)
- return -1;
-
- object_name[object_name_len] = '\0';
- for (i=0; i<current_level; i++) {
- printf("\t");
- }
- printf("<%s", object_name);
-
- found_children = dump_objdb_buff(dump_handle, cluster_handle, object_handle, current_level);
- if (found_children < 0)
- return -1;
-
- if ((object_handle != parent_object_handle) && (found_children)) {
- for (i=0; i<current_level; i++) {
- printf("\t");
- }
- printf("</%s>\n", object_name);
- }
- }
-
- if(!has_children)
- printf("/>\n");
-
- return has_children;
-}
-
-static void print_usage(void)
-{
- printf("Usage:\n");
- printf("\n");
- printf("ccs_config_dump [options]\n");
- printf("\n");
- printf("Options:\n");
- printf(" -r Force dump of runtime configuration (see man page)\n");
- printf(" -h Print this help, then exit\n");
- printf(" -V Print program version information, then exit\n");
- printf("\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 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case 'V':
- printf("ccs_config_dump %s (built %s %s)\n%s\n",
- RELEASE_VERSION, __DATE__, __TIME__,
- REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- break;
-
- case 'r':
- if(unsetenv("COROSYNC_DEFAULT_CONFIG_IFACE") < 0) {
- fprintf(stderr, "Unable to unset env vars\n");
- exit(EXIT_FAILURE);
- }
- break;
-
- case EOF:
- cont = 0;
- break;
-
- default:
- fprintf(stderr, "unknown option: %c\n", optchar);
- print_usage();
- exit(EXIT_FAILURE);
- break;
- }
- }
-}
-
-int main(int argc, char *argv[])
-{
- confdb_handle_t handle = 0;
- hdb_handle_t cluster_handle;
-
- read_arguments(argc, argv);
-
- if (confdb_initialize(&handle, &callbacks) != CS_OK)
- return -1;
-
- if (confdb_object_find_start(handle, OBJECT_PARENT_HANDLE) != CS_OK)
- return -1;
-
- if (confdb_object_find(handle, OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"), &cluster_handle) != CS_OK)
- return -1;
-
- printf("<?xml version=\"1.0\"?>\n<cluster");
-
- if (dump_objdb_buff(handle, cluster_handle, cluster_handle, 0) < 0)
- return -1;
-
- printf("</cluster>\n");
-
- if (confdb_finalize(handle) != CS_OK)
- return -1;
-
- return 0;
-}
diff --git a/config/tools/xml/ccs_config_validate.in b/config/tools/xml/ccs_config_validate.in
deleted file mode 100644
index 6573fef..0000000
--- a/config/tools/xml/ccs_config_validate.in
+++ /dev/null
@@ -1,242 +0,0 @@
-#!/bin/bash
-
-if [ -z "$COROSYNC_DEFAULT_CONFIG_IFACE" ]; then
- # rpm based distros
- if [ -d /etc/sysconfig ]; then
- [ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster
- [ -f /etc/sysconfig/cman ] && . /etc/sysconfig/cman
- fi
-
- # deb based distros
- if [ -d /etc/default ]; then
- [ -f /etc/default/cluster ] && . /etc/default/cluster
- [ -f /etc/default/cman ] && . /etc/default/cman
- fi
-
- [ -z "$CONFIG_LOADER" ] && CONFIG_LOADER=xmlconfig
- export COROSYNC_DEFAULT_CONFIG_IFACE=$CONFIG_LOADER:cmanpreconfig
-fi
-
-get_config_version() {
- local file=$1
-
- echo "xpath /cluster/@config_version" | \
- xmllint --shell "$file" | \
- grep content | \
- cut -f2 -d=
-}
-
-print_usage() {
- echo "Usage:"
- echo ""
- echo "ccs_config_validate [options]"
- echo ""
- echo "Options:"
- echo " -h Print this help, then exit"
- echo " -V Print program version information, then exit"
- echo " -v Produce verbose output"
- echo " -q Be very quiet"
- echo ""
- echo "Validating XML configuraton files:"
- echo " -f configfile Validate an alternate config file"
- echo " -l configfile Validate an alternate config file (load test)"
- echo ""
- echo "Advanced options:"
- echo " -u Do not update relaxng schema"
- echo " -r Force validation of runtime config"
- echo " -C config_loader Override config plugin loader"
- echo " -t tempfile Force temporay file to tempfile"
- echo " -n Do not remove temporary file"
- echo " -o Overwrite temporary file (dangerous)"
- echo " -R version When validating configuration update, ensure the"
- echo " new config is newer than the specified version."
-}
-
-check_opts() {
- while [ "$1" != "--" ]; do
- case $1 in
- -h)
- print_usage
- exit 0
- ;;
- -V)
- echo "ccs_config_validate version @VERSION@"
- exit 0
- ;;
- -t)
- shift
- tempfile="$1"
- ;;
- -n)
- notempfilerm=1
- ;;
- -o)
- overwritetempfile=1
- ;;
- -R)
- shift
- old_version=$1
- ;;
- -C)
- shift
- export COROSYNC_DEFAULT_CONFIG_IFACE=$1:cmanpreconfig
- loaderoverride=1
- if [ -n "$runtimetest" ] || \
- [ -n "$filetest" ] || \
- [ -n "$noloadtest" ]; then
- echo "Error: invalid options. -C can not be set together with -l or -r or -f" >&2
- exit 255
- fi
- ;;
- -l)
- shift
- export COROSYNC_CLUSTER_CONFIG_FILE=$1
- export COROSYNC_DEFAULT_CONFIG_IFACE=xmlconfig:cmanpreconfig
- filetest=1
- if [ -n "$loaderoverride" ] || \
- [ -n "$runtimetest" ] || \
- [ -n "$noloadtest" ]; then
- echo "Error: invalid options. -l can not be set together with -r or -C or -f" >&2
- exit 255
- fi
- ;;
- -f)
- shift
- export COROSYNC_CLUSTER_CONFIG_FILE=$1
- unset COROSYNC_DEFAULT_CONFIG_IFACE
- noloadtest=1
- if [ -n "$loaderoverride" ] || \
- [ -n "$runtimetest" ] || \
- [ -n "$filetest" ]; then
- echo "Error: invalid options. -f can not be set together with -r or -C or -l" >&2
- exit 255
- fi
- ;;
- -r)
- unset COROSYNC_DEFAULT_CONFIG_IFACE
- runtimetest=1
- if [ -n "$noloadtest" ] || \
- [ -n "$loaderoverride" ] || \
- [ -n "$filetest" ]; then
- echo "Error: invalid options. -r can not be set together with -l or -C or -f" >&2
- exit 255
- fi
- ;;
- -v)
- verbose=1
- if [ -n "$quiet" ]; then
- echo "Error: invalid options. -v can not be set together with -q" >&2
- exit 255
- fi
- ;;
- -q)
- quiet=1
- if [ -n "$verbose" ]; then
- echo "Error: invalid options. -q can not be set together with -v" >&2
- exit 255
- fi
- ;;
- -u)
- updaterelaxng=0
- ;;
- esac
- shift
- done
-}
-
-lecho()
-{
- [ -n "$verbose" ] && echo $@
- return 0
-}
-
-opts=$(getopt t:hVnC:f:l:rR:ovqu $@)
-if [ "$?" != 0 ]; then
- print_usage >&2
- exit 255
-fi
-check_opts $opts
-
-if [ -n "$tempfile" ]; then
- if [ -f "$tempfile" ] && [ -z "$overwritetempfile" ]; then
- echo "Selected temporary file $tempfile already exists" >&2
- echo "Use -o to force overwrite (dangerous)" >&2
- exit 255
- fi
-else
- tempfile=$(mktemp)
- if [ -z "$tempfile" ]; then
- echo "Unable to create temporary file" >&2
- exit 255
- fi
-fi
-lecho "Creating temporary file: $tempfile"
-lecho "Config interface set to: $COROSYNC_DEFAULT_CONFIG_IFACE"
-
-if [ -n "$noloadtest" ]; then
- cp $COROSYNC_CLUSTER_CONFIG_FILE $tempfile
-else
- export CMAN_PIPE=2
- if ! ccs_config_dump > $tempfile; then
- [ -z "$notempfilerm" ] && rm -f $tempfile
- echo
- echo "Unable to get the configuration" >&2
- exit 255
- fi
-fi
-lecho "Configuration stored in temporary file"
-
-lecho "Updating relaxng schema"
-if [ "$updaterelaxng" != 0 ]; then
- updateerr="$(ccs_update_schema 2>&1)"
- if [ $? != 0 ]; then
- echo "Unable to update relaxng schema: $updateerr" >&2
- exit 255
- fi
-fi
-
-if [ -f /var/lib/cluster/rng_update.lock ]; then
- echo "Relax-ng schema update in progress" >&2
- exit 255
-fi
-
-if [ ! -e @SHAREDIR@/cluster.rng ]; then
- echo "Unable to verify a configuration without relaxng schema" >&2
- exit 255
-fi
-
-lecho "Validating.."
-
-xmlout=$(xmllint --noout \
- --relaxng @SHAREDIR@/cluster.rng \
- $tempfile 2>&1)
-res=$?
-
-if [ -n "$old_version" ] && [ $old_version -ne 0 ] && [ $res -eq 0 ]; then
- new_version=$(get_config_version $tempfile)
- if [ -z "$new_version" ]; then
- [ -z "$quiet" ] && \
- echo "Error: Unable to determine new config version!" >&2
- [ -z "$notempfilerm" ] && rm -f $tempfile
- exit 253
- fi
- lecho "Old version: $old_version New version: $new_version"
- if [ $new_version -le $old_version ]; then
- [ -z "$quiet" ] && \
- echo "Error: Configuration version is older than running config!" >&2
- [ -z "$notempfilerm" ] && rm -f $tempfile
- exit 254
- fi
-fi
-
-if [ -z "$quiet" ] || [ "$res" != "0" ]; then
- echo "$xmlout" | sed \
- -e 's#.*validates$#Configuration validates#g' \
- -e 's#.*validate$#Configuration fails to validate#g' \
- -e 's#'$tempfile'#tempfile#g'
-fi
-
-lecho "Validation completed"
-
-[ -z "$notempfilerm" ] && rm -f $tempfile
-exit $res
diff --git a/config/tools/xml/ccs_update_schema.in b/config/tools/xml/ccs_update_schema.in
deleted file mode 100644
index b63c987..0000000
--- a/config/tools/xml/ccs_update_schema.in
+++ /dev/null
@@ -1,382 +0,0 @@
-#!/bin/bash
-
-set +e
-export LC_ALL=C
-umask 022
-
-rngdir=@SHAREDIR@/relaxng
-rasdir=@SHAREDIR@
-fasdir=@SBINDIR@
-vardir=/var/lib/cluster
-force=""
-verbose=""
-
-print_usage() {
- echo "Usage:"
- echo ""
- echo "ccs_update_schema [options]"
- echo ""
- echo "Options:"
- echo " -h Print this help, then exit"
- echo " -V Print program version information, then exit"
- echo " -v Produce verbose output"
- echo " -f Force schema regeneration and ignore cache"
-}
-
-lecho() {
- [ -n "$verbose" ] && echo "$@"
- return 0
-}
-
-check_opts() {
- while [ "$1" != "--" ]; do
- case $1 in
- -h)
- print_usage
- exit 0
- ;;
- -V)
- echo "ccs_update_schema version @VERSION@"
- exit 0
- ;;
- -v)
- verbose=1
- ;;
- -f)
- force=1
- ;;
- esac
- shift
- done
-}
-
-opts=$(getopt hvVf $@)
-if [ "$?" != 0 ]; then
- print_usage >&2
- exit 1
-fi
-check_opts $opts
-
-tmpdir="$(mktemp -d -q)" || {
- echo "unable to create tempdir" >&2
- exit 1
-}
-export tmpdir
-
-# need to be careful (might have to mask traps on exit)
-cleanup() {
- [ "$1" != "0" ] && rm -f $vardir/*.cache $vardir/*.hash
- [ -n "$tmpdir" ] && [ -d "$tmpdir" ] && rm -rf "$tmpdir"
- rm -f $vardir/rng_update.lock
- exit $1
-}
-
-trap "cleanup 1" ABRT
-trap "cleanup 1" QUIT
-trap "cleanup 1" TERM
-trap "cleanup 1" INT
-trap "cleanup 1" ERR
-
-filter_file_list() {
- filelist="$@"
- for i in $filelist; do
- [ "${i%\~}" != "${i}" ] && continue
- [ "${i%,}" != "${i}" ] && continue
- [ "${i%.orig}" != "${i}" ] && continue
- [ "${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
- echo "$i"
- done
-}
-
-filter_fence_list() {
- filelist="$@"
- for i in $faslist; do
- [ "${i}" = "$fasdir/fence_legacy" ] && continue
- [ "${i}" = "$fasdir/fence_node" ] && continue
- [ "${i}" = "$fasdir/fence_nss_wrapper" ] && continue
- [ "${i}" = "$fasdir/fence_pcmk" ] && continue
- [ "${i}" = "$fasdir/fence_tool" ] && continue
- [ "${i}" = "$fasdir/fence_vmware_helper" ] && continue
- echo "$i"
- done
-}
-
-generate_hash() {
- outputfile="$1"
- shift
- filelist="$@"
-
- if [ -n "$filelist" ]; then
- md5sum $filelist > $outputfile
- return $?
- else
- echo -n > $outputfile
- return $?
- fi
-}
-
-create_ras_stubs() {
- lecho " ras: cannot find rng files. Creating stubs"
- touch "$outputdir/resources.rng.hash"
- cat > "$outputdir/resources.rng.cache" << EOF
-<!-- STUB resource-agents definitions -->
-<define name="SERVICE">
- <element name="service" rha:description="Stub service">
- <optional>
- <ref name="CHILDREN"/>
- </optional>
- </element>
-</define>
-<define name="VM" >
- <element name="vm" rha:description="Stub VM">
- <optional>
- <ref name="CHILDREN"/>
- </optional>
- </element>
-</define>
-<define name="CHILDREN">
- <zeroOrMore>
- <choice>
- <ref name="SERVICE"/>
- <ref name="VM"/>
- </choice>
- </zeroOrMore>
-</define>
-<!-- end STUB resource-agents definitions -->
-EOF
-}
-
-generate_ras() {
- outputdir="$1"
- raslist=""
-
- lecho " ras: checking required files"
-
- doras_stub=""
- for i in ra2rng.xsl ra2ref.xsl \
- resources.rng.head resources.rng.mid resources.rng.tail; do
- if [ ! -f "$rngdir/$i" ]; then
- doras_stub=yes
- fi
- done
-
- for i in service.sh vm.sh; do
- if [ ! -x "$rasdir/$i" ]; then
- doras_stub=yes
- fi
- done
-
- [ "$doras_stub" = yes ] && create_ras_stubs && return 0
-
- lecho " ras: looking for agents"
-
- if [ -d "$rasdir" ]; then
- raslist=$(find $rasdir \
- -mindepth 1 -maxdepth 1 -type f -executable | sort -u)
- raslist=$(filter_file_list $raslist)
- # ordering is important apparently
- [ -x $rasdir/service.sh ] && \
- raslist="$rasdir/service.sh \
- $(echo $raslist | sed -e 's#'$rasdir'/service.sh##g')"
- fi
-
- lecho " ras: generating hashes"
-
- if ! generate_hash \
- "$outputdir/resources.rng.hash" \
- "$raslist $rngdir/ra2*.xsl $rngdir/resources.rng.* $0"; then
- echo "Unable to generate resource agents hash" >&2
- return 1
- fi
-
- if [ -z "$force" ] && \
- [ -f $vardir/resources.rng.hash ] && \
- [ -f $vardir/resources.rng.cache ] && \
- [ "$(cat $vardir/resources.rng.hash | md5sum -)" = \
- "$(cat "$outputdir/resources.rng.hash" | md5sum -)" ]; then
- lecho " ras: using local cache"
- cp $vardir/resources.rng.cache $outputdir/resources.rng.cache
- return 0
- fi
-
- lecho " ras: generating rng data"
-
- cat $rngdir/resources.rng.head > "$outputdir/resources.rng.cache"
- lecho " ras: generating rng data"
- for i in $raslist; do
- lecho " ras: processing $(basename $i)"
- $i meta-data 2>/dev/null | xsltproc $rngdir/ra2rng.xsl - >> \
- "$outputdir/resources.rng.cache" 2>/dev/null
- [ "$?" != 0 ] && \
- echo " <!-- Problem evaluating metadata for $i" \
- "-->" >> "$outputdir/resources.rng.cache"
- done
- cat $rngdir/resources.rng.mid >> "$outputdir/resources.rng.cache"
- lecho " ras: generating ref data"
- for i in $raslist; do
- lecho " ras: processing $(basename $i)"
- $i meta-data 2>/dev/null | xsltproc $rngdir/ra2ref.xsl - >> \
- "$outputdir/resources.rng.cache" 2>/dev/null
- done
- cat $rngdir/resources.rng.tail >> "$outputdir/resources.rng.cache"
-}
-
-create_fas_stubs() {
- lecho " fas: cannot find rng files. Creating stubs"
- touch "$outputdir/fence_agents.rng.hash"
- cat > "$outputdir/fence_agents.rng.cache" << EOF
-<!-- STUB fence-agents definitions -->
-<define name="FENCEDEVICEOPTIONS">
- <element name="service" rha:description="Stub fence device options">
- <optional>
- <ref name="STUBFENCEDEVICEOPTIONS"/>
- </optional>
- </element>
-</define>
-<define name="STUBFENCEDEVICEOPTIONS">
- <zeroOrMore>
- <choice>
- <ref name="FENCEDEVICEOPTIONS"/>
- </choice>
- </zeroOrMore>
-</define>
-<!-- end STUB fence-agents definitions -->
-EOF
-}
-
-generate_fas() {
- outputdir="$1"
- faslist=""
-
- lecho " fas: checking required files"
-
- dofas_stub=""
- for i in fence2rng.xsl fence.rng.head fence.rng.tail; do
- if [ ! -f "$rngdir/$i" ]; then
- dofas_stub=yes
- fi
- done
-
- [ "$dofas_stub" = yes ] && create_fas_stubs && return 0
-
- lecho " fas: looking for agents"
-
- if [ -d "$fasdir" ]; then
- faslist=$(ls -1 $fasdir/fence_*)
- faslist=$(filter_file_list $faslist)
- faslist=$(filter_fence_list $faslist)
- fi
-
- lecho " fas: generating hashes"
-
- if ! generate_hash \
- "$outputdir/fence_agents.rng.hash" \
- "$faslist $rngdir/fence2*.xsl $rngdir/fence.rng.* $0"; then
- echo "Unable to generate fence agents hash" >&2
- return 1
- fi
-
- if [ -z "$force" ] && \
- [ -f $vardir/fence_agents.rng.hash ] && \
- [ -f $vardir/fence_agents.rng.cache ] && \
- [ "$(cat $vardir/fence_agents.rng.hash | md5sum -)" = \
- "$(cat "$outputdir/fence_agents.rng.hash" | md5sum -)" ]; then
- lecho " fas: using local cache"
- cp $vardir/fence_agents.rng.cache \
- $outputdir/fence_agents.rng.cache
- return 0
- fi
-
- lecho " fas: generating new cache"
-
- cat $rngdir/fence.rng.head > "$outputdir/fence_agents.rng.cache"
- for i in $faslist; do
- lecho " fas: processing $(basename $i)"
- $i -o metadata 2>/dev/null | \
- xsltproc $rngdir/fence2rng.xsl - >> \
- "$outputdir/fence_agents.rng.cache" 2>/dev/null
- [ "$?" != 0 ] && \
- echo " <!-- Problem evaluating metadata for $i" \
- "-->" >> "$outputdir/fence_agents.rng.cache"
- done
- cat $rngdir/fence.rng.tail >> "$outputdir/fence_agents.rng.cache"
-}
-
-build_schema() {
- cat $rngdir/cluster.rng.in.head \
- $outputdir/resources.rng.cache \
- $outputdir/fence_agents.rng.cache \
- $rngdir/cluster.rng.in.tail \
- > $outputdir/cluster.rng || {
- echo "generic error linking relaxng schema" >&2
- return 1
- }
-
- xmllint --noout $outputdir/cluster.rng || {
- echo "generated schema does not pass xmllint validation" >&2
- return 1
- }
-
- return 0
-}
-
-# NOTE
-# failure to delete cache and hash or failure to install them
-# is not fatal and will result in both being regenerated at the next run
-
-install_schema() {
- mkdir -p $outputdir/backup || {
- echo "Unable to create backup dir" >&2
- return 1
- }
- cp -a $vardir/*rng* $outputdir/backup/ || {
- echo "Unable to perform backup of current schema" >&2
- return 1
- }
- rm -f $vardir/*.cache $vardir/*.hash
- cp -f $outputdir/cluster.rng $vardir/ || {
- cp -a $outputdir/backup/* $vardir/
- echo "Failed to update relaxng ondisk data" >&2
- return 1
- }
- cp $outputdir/*.cache $outputdir/*.hash $vardir/
- return 0
-}
-
-(
- flock --exclusive 200
-
- lecho "Generating resource-agents cache"
-
- generate_ras "$tmpdir" || {
- echo "generic error creating resource agents relaxng schema" >&2
- cleanup 1
- }
-
- lecho "Generating fence-agents cache"
-
- generate_fas "$tmpdir" || {
- echo "generic error creating fence agents relaxng schema" >&2
- cleanup 1
- }
-
- lecho "Building final relaxng schema"
-
- build_schema || cleanup 1
-
- lecho "Installing schema in $vardir"
-
- install_schema || cleanup 1
-
- lecho "all done. have a nice day!"
-
- cleanup 0
-) 200>$vardir/rng_update.lock
diff --git a/config/tools/xml/cluster.rng.in.head b/config/tools/xml/cluster.rng.in.head
deleted file mode 100644
index 003ceaf..0000000
--- a/config/tools/xml/cluster.rng.in.head
+++ /dev/null
@@ -1,1126 +0,0 @@
-<grammar datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
-xmlns="http://relaxng.org/ns/structure/1.0"
-xmlns:rha="http://redhat.com/~pkennedy/annotation_namespace/cluster_conf_annot_namespa…">
-
-<!-- The cluster.conf schema follows this outline:
-
-cluster
-- cman
-- totem
-- uidgid
-- quorumd
-- fence_daemon
-- fence_xvmd
-- dlm
-- gfs_controld
-- group
-- logging
-- clusternodes
-- fencedevices
-- rm
-- clvmd
-
-Element definitions:
-- Resource
-- Fence
-
-To validate your cluster.conf against this schema, run:
-
- xmllint \-\-relaxng cluster.rng /path/to/cluster.conf
-
--->
-
-<start>
-<element name="cluster" rha:description="Defines cluster properties, and
- contains all other configuration. cluster.conf(5)">
- <attribute name="name" rha:description="Name of the cluster.
- cluster.conf(5)"/>
- <attribute name="config_version" rha:description="Revision level
- of cluster.conf file. cluster.conf(5)"/>
- <interleave>
-
-<!-- cman block -->
- <optional>
- <element name="cman" rha:description="The cman element contains
- attributes that define the following cluster-wide parameters and
- behaviors: whether the cluster is a two-node cluster, expected
- votes, user-specified multicast address, and logging.">
- <optional>
- <attribute name="two_node" rha:description="The two_node attribute
- allows you to configure a cluster with only two
- nodes. Ordinarily, the loss of quorum after one of two nodes
- fails prevents the remaining node from continuing (if both
- nodes have one vote.) To enable a two-node cluster, set the
- two_node value equal to 1. If the two_node value is enabled,
- the expected_votes value must be set to 1." rha:sample="1"/>
- </optional>
- <optional>
- <attribute name="expected_votes" rha:description="The expected
- votes value is used by cman to determine quorum. The cluster
- is quorate if the sum of votes of 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 overriden by setting an explicit
- expected_votes value." rha:sample="4">
- <data type="positiveInteger"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="upgrading" rha:description="Set this if you are
- performing a rolling upgrade of the cluster between major
- releases." rha:sample="no"/>
- </optional>
- <optional>
- <attribute name="disallowed" rha:description="Set this to 1 enable
- cman's Disallowed mode. This is usually only needed for
- backwards compatibility." rha:sample="1">
- <data type="nonNegativeInteger"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="quorum_dev_poll" rha:description="The amount of time
- after a qdisk poll, in milliseconds, before a quorum disk is
- considered dead. The quorum disk daemon, qdisk, periodically
- sends hello messages to cman and ais, indicating that qdisk
- is present. If qdisk takes more time to send a hello message
- to cman and ais than by quorum_dev_poll, then cman declares
- qdisk dead and prints a message indicating that connection to
- the quorum device has been lost." rha:sample="50000">
- <data type="nonNegativeInteger"/>
- </attribute>
- </optional>
- <!--FIXME: Clarify the following. What is meant by "service"? Also, is
- there a default value? What is a good sample value?-->
- <optional>
- <attribute name="shutdown_timeout" rha:description="Timeout period,
- in milliseconds, to allow a service to respond during a
- shutdown." rha:sample="5000">
- <data type="nonNegativeInteger"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="ccsd_poll" rha:description="" rha:sample=""
- rha:default="1000">
- <data type="nonNegativeInteger"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="debug_mask" rha:description="" rha:sample=""/>
- </optional>
- <optional>
- <attribute name="port">
- <data type="nonNegativeInteger"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="cluster_id">
- <data type="nonNegativeInteger"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="hash_cluster_id" rha:description="Enable stronger hashing of cluster ID to avoid collisions." />
- </optional>
- <optional>
- <attribute name="nodename" rha:description="Local node name; this is set internally by cman-preconfig and should never be set by a user."/>
- </optional>
- <optional>
- <attribute name="broadcast" rha:description="enable cman broadcast" rha:default="no"/>
- </optional>
- <optional>
- <attribute name="transport" rha:description="Specifies transport mechanism to use. Available values are udp (multicast default), udpb (broadcast), udpu (unicast) and rdma (Infiniband). corosync.conf(5)" rha:sample="">
- <choice>
- <value>udp</value>
- <value>udpb</value>
- <value>udpu</value>
- <value>rdma</value>
- </choice>
- </attribute>
- </optional>
- <optional>
- <attribute name="keyfile" rha:description=""/>
- </optional>
- <optional>
- <attribute name="disable_openais"/>
- </optional>
- <optional>
- <element name="multicast" rha:description="The multicast element
- provides the ability for a user to specify a multicast address,
- port and TTL (Time To Live) instead of using cman defaults. If
- a user does not specify a multicast address, cman creates one. It
- forms the upper 16 bits of the multicast address with 239.192 for
- IPv4 and ff15:: for IPv6 and forms the lower 16 bits based on
- the cluster ID.">
- <ref name="MULTICASTOPTS"/>
- </element>
- </optional>
- <optional>
- <element name="altmulticast" rha:description="The altmulticast element
- provides the ability for a user to specify a multicast address,
- port and TTL (Time To Live) instead of using cman defaults for
- the alternate communication channel (RRP). If a user does not
- specify an alternate multicast address, cman creates one. It
- forms the upper 16 bits of the multicast address with 239.192 for
- IPv4 and ff15:: for IPv6 and forms the lower 16 bits based on
- the cluster ID + 1.">
- <ref name="MULTICASTOPTS"/>
- </element>
- </optional>
- </element>
- </optional>
-<!-- end cman block -->
-
-<!-- uidgid block -->
- <optional>
- <zeroOrMore>
- <element name="uidgid" rha:description="Access control to corosync IPC">
- <optional>
- <attribute name="uid" rha:description="This is an unprivileged username,
- as globally available to the system via /etc/passwd, including nis/ldap,
- allowed to connect to corosync IPC. This value cannot be updated at runtime,
- a full cman restart is required." rha:default="" rha:samble="userfoo"/>
- </optional>
- <optional>
- <attribute name="gid" rha:description="This is an unprivileged group name,
- as globally available to the system via /etc/group, including nis/ldap,
- allowed to connect to corosync IPC. This value cannot be updated at runtime,
- a full cman restart is required." rha:default="" rha:samble="groupfoo"/>
- </optional>
- </element>
- </zeroOrMore>
- </optional>
-<!-- end uidgid block -->
-
-<!-- totem block -->
- <optional>
- <element name="totem" rha:description="OpenAIS msg transport
- protocol">
- <optional>
- <attribute name="consensus" rha:description="This is a timeout value
- that specifies how many milliseconds to wait for consensus
- to be achieved before starting a new round of membership
- configuration." rha:default="200" rha:sample="235"/>
- </optional>
- <optional>
- <attribute name="join" rha:description="This is a timeout value that
- specifies how many milliseconds to wait for join messages in
- the membership protocol." rha:default="100" rha:sample="95"/>
- </optional>
- <optional>
- <attribute name="token" rha:description="This is a timeout value
- that specifies how many milliseconds elapse before a
- token loss is declared after not receiving a token. This
- is the time spent detecting a failure of a processor in
- the current configuration. Reforming a new configuration
- takes about 50 milliseconds in addition to this
- timeout." rha:default="5000" rha:sample="5300"/>
- </optional>
- <optional>
- <attribute name="fail_recv_const" />
- </optional>
- <optional>
- <attribute name="seqno_unchanged_const"
- rha:description="Specifies how many rotations of the token without
- any multicast traffic should occur before the merge detection timeout
- is started." rha:default="30" rha:sample="5000"/>
- </optional>
- <optional>
- <attribute name="netmtu"
- rha:description="Specifies the network maximum transmit unit. To set
- this value beyond 1500, the regular frame MTU, requires ethernet
- devices that support large, or also called jumbo, frames. If any
- device in the network does not support large frames, the protocol will
- not operate properly. The hosts must also have their mtu size set
- from 1500 to whatever frame size is specified here."
- rha:default="1500" rha:sample="9174"/>
- </optional>
- <optional>
- <attribute name="window_size"
- rha:description="Specifies the maximum number of messages that may
- be sent on one token rotation. window_size should be no larger then
- 256000 / netmtu to avoid overflow of the kernel receive buffers."
- rha:default="50" rha:sample="300"/>
- </optional>
- <optional>
- <attribute name="max_messages"
- rha:description="Specifies the maximum number of messages that may
- be sent by one processor on receipt of the token. This parameter is
- limited to 256000 / netmtu to prevent overflow of the kernel
- transmit buffers" rha:default="17" rha:sample="25"/>
- </optional>
- <optional>
- <attribute name="token_retransmits_before_loss_const"
- rha:description="This value identifies how many token retransmits
- should be attempted before forming a new configuration. If
- this value is set, retransmit and hold will be automatically
- calculated from retransmits_before_loss and token." rha:default="4"
- rha:sample="5"/>
- </optional>
- <optional>
- <attribute name="miss_count_const"
- rha:description="This constant defines the maximum number of times
- on receipt of a token a message is checked for retransmission before
- retransmission occurs. This parameter is useful to modify for switches
- that delay multicast packets compared to unicast packets.
- The default setting works well for nearly all modern switches."
- rha:default="5" rha:sample="10"/>
- </optional>
- <!-- FIXME: The following description was adapted from the man page.
- It may be tool long for the schema document. Consider cutting text
- after the second sentence and referring the reader to the openais.conf
- man page. -->
- <optional>
- <attribute name="rrp_mode" rha:description="This attribute
- specifies the redundant ring protocol mode. Its value can be
- set to active, passive, or none. Active replication offers
- slightly lower latency from transmit to delivery in faulty
- network environments but with less performance. Passive
- replication may nearly double the speed of the totem protocol
- if the protocol doesn't become cpu bound. The final option is
- none, in which case only one network interface is used to
- operate the totem protocol. If only one interface directive is
- specified, none is automatically chosen. If multiple interface
- directives are specified, only active or passive may be
- chosen." rha:sample="active"/>
- </optional>
- <optional>
- <attribute name="rrp_problem_count_threshold" rha:description="This
- specifies the number of times a problem is detected with a link
- before setting the link faulty. Once a link is set faulty, no more
- data is transmitted upon it. Corosync default is 10, cman default is 3"
- rha:default="3" rha:sample="5"/>
- </optional>
- <optional>
- <attribute name="secauth" rha:description="This attribute specifies
- that HMAC/SHA1 authentication should be used to authenticate all
- messages. It further specifies that all data should be encrypted
- with the sober128 encryption algorithm to protect data from
- eavesdropping. For more information setting this value, refer
- the the openais.conf man page." rha:default="on" rha:sample=""/>
- </optional>
- <optional>
- <attribute name="keyfile" rha:description="" rha:sample=""/>
- </optional>
- <!-- multicast address -->
- <zeroOrMore>
- <element name="interface" rha:description="Defines Totem interface options. corosync.conf(5)" rha:sample="">
- <optional>
- <attribute name="ringnumber" rha:description="Sets the ring interface for the interface for RRP mode. corosync.conf(5)" rha:sample=""/>
- </optional>
- <optional>
- <attribute name="bindnetaddr" rha:description="Specifies the address to which the corosync executive should bind. corosync.conf(5)" rha:sample=""/>
- </optional>
- <optional>
- <attribute name="mcastaddr" rha:description="Defines the multicast address used by corosync for this interface. corosync.conf(5)" rha:sample=""/>
- </optional>
- <optional>
- <attribute name="mcastport" rha:description="Specifies the UDP port number when using multicast. corosync.conf(5)" rha:sample=""/>
- </optional>
- <optional>
- <attribute name="broadcast" rha:description="If set to yes, use broadcast instead of multicast for communication. corosync.conf(5)" rha:sample=""/>
- </optional>
- </element>
- </zeroOrMore>
- </element>
- </optional>
-<!-- end totem block -->
-
-<!-- quorumd block -->
- <optional>
- <element name="quorumd" rha:description="This element and its
- attributes define parameters for the quorum disk daemon,
- quorumd. qdisk(5).">
- <optional>
- <attribute name="interval" rha:description="The frequency of
- read/write cycles, in seconds. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="tko" rha:description="The number of cycles a node
- must miss to be declared dead. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="votes" rha:description="The number of votes the
- quorum daemon advertises to CMAN when it has a high enough
- score. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="min_score" rha:description="The minimum score for a
- node to be considered alive. If omitted or set to 0, the default
- function, floor((n+1)/2), is used, where n is the sum of the
- heuristics scores. The Minimum Score value must never exceed the
- sum of the heuristic scores; otherwise, the quorum disk cannot
- be available. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="device" rha:description="The storage device the
- quorum daemon uses. The device must be the same on all
- nodes. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="label" rha:description="Specifies the quorum disk
- label created by the mkqdisk utility. If this field contains an
- entry, the label overrides the Device field. If this field is
- used, the quorum daemon reads /proc/partitions and checks for
- qdisk signatures on every block device found, comparing the
- label against the specified label. This is useful in configurations
- where the quorum device name differs among nodes. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="cman_label" rha:description="This is the name used by CMAN for the quorum device instead of the device name. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="status_file" rha:description="Debugging file. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="scheduler" rha:description="Scheduler. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="reboot" rha:description="Reboot if our score drops too low. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="priority" rha:description="Scheduler priority. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="tko_up" rha:description="Amount of positive changes before a host is considered online. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="upgrade_wait" rha:description="Amount of cycles wait for conflicts for a bid for master status. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="use_uptime" rha:description="Use /proc/uptime instead of gettimeofday(). qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="stop_cman" rha:description="Stop cman if the quorum disk cannot be found during startup. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="paranoid" rha:description="Reboot if we are running too slowly. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="allow_kill" rha:description="Instruct cman to evict nodes which are not updating the quorum disk. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="max_error_cycles" rha:description="Die after this many cycles which receive I/O errors. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="io_timeout" rha:description="Die if we cannot get a write out to disk after interval*tko. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="master_wins" rha:description="Enable master-wins mode (two node clusters). qdisk(5)." rha:sample=""/>
- </optional>
- <zeroOrMore>
- <element name="heuristic" rha:description="Defines a heuristic. qdisk(5).">
- <attribute name="program" rha:description="The program used to
- determine if this heuristic is alive. This can be anything that
- can be executed by /bin/sh -c. A return value of 0 indicates
- success; anything else indicates failure." rha:sample=""/>
- <optional>
- <attribute name="score" rha:description="The weight of this
- heuristic. Be careful when determining scores for
- heuristics." rha:default="1" rha:sample=""/>
- </optional>
- <optional>
- <attribute name="interval" rha:description="The frequency (in
- seconds) at which the heuristic is polled. qdisk(5)." rha:default="2"
- rha:sample=""/>
- </optional>
- <optional>
- <attribute name="tko" rha:description="The number of consecutive failures before a heuristic is discounted. qdisk(5)." rha:sample=""/>
- </optional>
- </element>
- </zeroOrMore>
- </element>
- </optional>
-<!-- end quorumd block -->
-
-<!-- fence_daemon block -->
- <optional>
- <element name="fence_daemon" rha:description="Configuration for fenced
- daemon. fenced(8)">
- <optional>
- <attribute name="post_join_delay" rha:description="Number of seconds
- the daemon will wait before fencing any victims after a node joins
- the fence domain. fenced(8)"/>
- </optional>
- <optional>
- <attribute name="post_fail_delay" rha:description="Number of seconds
- the daemon will wait before fencing any victims after a node
- fails. fenced(8)"/>
- </optional>
- <optional>
- <attribute name="override_path" rha:description="Location of a FIFO
- used for communication between fenced and fence_ack_manual.
- fenced(8)"/>
- </optional>
- <optional>
- <attribute name="override_time" rha:description="Number of seconds to
- wait for a manual override after a failed fencing attempt before
- the next attempt. fenced(8)"/>
- </optional>
- <optional>
- <attribute name="clean_start" rha:description="Set to 1 to disable
- startup fencing. fenced(8)"/>
- </optional>
-
- <optional>
- <attribute name="skip_undefined" rha:description="Set to 1 to disable
- startup fencing of nodes with no fence methods defined.
- fenced(8)"/>
- </optional>
- </element>
- </optional>
-<!-- end fence_daemon block -->
-
-<!-- fence_xvmd block -->
- <optional>
- <element name="fence_xvmd" rha:description="Fence_xvm daemon. The
- fence_xvmd fence device is an I/O fencing host that resides
- on dom0 and is used in conjunction with the fence_xvm fencing
- agent. Together, these two programs fence Xen virtual machines
- that are in a cluster. There is a requirement that the parent
- dom0s are also a part of their own CMAN/OpenAIS based cluster,
- and that the dom0 cluster does not share any members with the domU
- cluster. Furthermore, the dom0 cluster is required to have fencing
- if domU recovery is expected to be automatic.">
- <optional>
- <attribute name="debug" rha:description="" >
- <data type="integer"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="port" rha:description="" >
- <data type="integer"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="use_uuid" rha:description="" />
- </optional>
- <optional>
- <attribute name="multicast_address" rha:description="" />
- </optional>
- <optional>
- <attribute name="auth" rha:description="" />
- </optional>
- <optional>
- <attribute name="hash" rha:description="" />
- </optional>
- <optional>
- <attribute name="uri" rha:description="" />
- </optional>
- <optional>
- <attribute name="key_file" rha:description="" />
- </optional>
- <optional>
- <attribute name="multicast_interface" rha:description="" />
- </optional>
- </element>
- </optional>
-<!-- end fence_xvmd block -->
-
-<!-- dlm block -->
- <optional>
- <element name="dlm" rha:description="Configuration for dlm and
- dlm_controld daemon. dlm_controld(8)">
-
- <optional>
- <attribute name="log_debug" rha:description="Set to 1 to enable
- dlm kernel debugging messages. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="timewarn" rha:description="Number of centiseconds
- a lock is blocked before notifying dlm_controld deadlock code.
- dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="protocol" rha:description="The dlm lowcomms protocol.
- dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="enable_fencing" rha:description="Fencing recovery
- dependency. dlm_controld(8)" />
- </optional>
-
- <optional>
- <attribute name="enable_quorum" rha:description="Quorum recovery
- dependency. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="enable_deadlk" rha:description="Deadlock detection
- capability. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="enable_plock" rha:description="Cluster fs posix
- lock capability. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="plock_debug" rha:description="Set to 1 to enable
- posix lock debugging. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="plock_rate_limit" rha:description="Limit the rate of
- plock operations. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="plock_ownership" rha:description="Set to 1/0 to
- enable/disable plock ownership. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="drop_resources_time" rha:description="Plock ownership
- drop resources time. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="drop_resources_count" rha:description="Plock ownership
- drop resources count. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="drop_resources_age" rha:description="Plock ownership
- drop resources age. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <zeroOrMore>
- <element name="lockspace" rha:description="Individual lockspace
- configuration. dlm_controld(8)">
- <attribute name="name" rha:description="Name of the lockspace.
- dlm_controld(8)"/>
-
- <optional>
- <attribute name="nodir" rha:description="Set to 1 to disable the
- internal resource directory. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <zeroOrMore>
- <element name="master" rha:description="Defines a master node.
- dlm_controld(8)">
-
- <attribute name="name" rha:description="The name of a node that
- should be master resources/locks. dlm_controld(8)"/>
-
- <optional>
- <attribute name="weight" rha:description="The proportion of
- resources this node should master. dlm_controld(8)"/>
- </optional>
- </element>
- </zeroOrMore>
- </optional>
-
- </element>
- </zeroOrMore>
- </optional>
- </element>
- </optional>
-<!-- end dlm block -->
-
-<!-- gfs_controld block -->
- <optional>
- <element name="gfs_controld" rha:description="Configuration for
- gfs_controld daemon. gfs_controld(8)">
-
- <optional>
- <attribute name="enable_withdraw" rha:description="Set to 1/0 to
- enable/disable a response to a withdraw. gfs_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="enable_plock" rha:description="Cluster fs posix
- lock capability. gfs_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="plock_debug" rha:description="Set to 1 to enable
- posix lock debugging. gfs_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="plock_rate_limit" rha:description="Limit the rate of
- plock operations. gfs_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="plock_ownership" rha:description="Set to 1/0 to
- enable/disable plock ownership. gfs_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="drop_resources_time" rha:description="Plock ownership
- drop resources time. gfs_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="drop_resources_count" rha:description="Plock ownership
- drop resources count. gfs_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="drop_resources_age" rha:description="Plock ownership
- drop resources age. gfs_controld(8)"/>
- </optional>
-
- </element>
- </optional>
-<!-- end gfs_controld block -->
-
-<!-- group block -->
- <optional>
- <element name="group" rha:description="Defines groupd configuration.
- groupd(8)">
- <optional>
- <attribute name="groupd_compat" rha:description="Enable compatibility with
- cluster2 nodes. groupd(8)"/>
- </optional>
- </element>
- </optional>
-<!-- end group block -->
-
-<!-- logging block -->
- <optional>
- <element name="logging" rha:description="Defines global logging
- configuration, and contains daemon-specific configuration.
- cluster.conf(5)">
-
- <optional>
- <attribute name="to_syslog" rha:description="Set to yes/no to
- enable/disable messages to syslog. cluster.conf(5)"/>
- </optional>
-
- <optional>
- <attribute name="to_logfile" rha:description="Set to yes/no to
- enable/disable messages to log file. cluster.conf(5)"/>
- </optional>
-
- <optional>
- <attribute name="syslog_facility" rha:description="The facility
- used for syslog messages. cluster.conf(5)"/>
- </optional>
-
- <optional>
- <attribute name="syslog_priority" rha:description="Messages at this
- level and higher are sent to syslog. cluster.conf(5)"/>
- </optional>
-
- <optional>
- <attribute name="logfile_priority" rha:description="Messages at this
- level and higher are written to log file. cluster.conf(5)"/>
- </optional>
-
- <optional>
- <attribute name="logfile" rha:description="The log file path name.
- cluster.conf(5)"/>
- </optional>
-
- <optional>
- <attribute name="debug" rha:description="Set to on to enable debugging
- messages in log file. cluster.conf(5)"/>
- </optional>
-
- <zeroOrMore>
- <element name="logging_daemon" rha:description="Defines
- daemon-specific logging configuration. cluster.conf(5)">
-
- <attribute name="name" rha:description="The daemon name.
- cluster.conf(5)"/>
-
- <optional>
- <attribute name="subsys" rha:description="A corosync subsystem name.
- cluster.conf(5)"/>
- </optional>
-
- <optional>
- <attribute name="to_syslog" rha:description="Same as global."/>
- </optional>
- <optional>
- <attribute name="to_logfile" rha:description="Same as global."/>
- </optional>
- <optional>
- <attribute name="syslog_facility" rha:description="Same as global."/>
- </optional>
- <optional>
- <attribute name="syslog_priority" rha:description="Same as global."/>
- </optional>
- <optional>
- <attribute name="logfile_priority" rha:description="Same as global."/>
- </optional>
- <optional>
- <attribute name="logfile" rha:description="Same as global."/>
- </optional>
- <optional>
- <attribute name="debug" rha:description="Same as global."/>
- </optional>
-
- </element>
- </zeroOrMore>
-
- </element>
- </optional>
-<!-- end logging block -->
-
-<!-- clusternodes block -->
- <element name="clusternodes" rha:description="Contains all cluster
- node definitions. cluster.conf(5)">
-
- <zeroOrMore>
- <element name="clusternode" rha:description="Defines cluster node
- properties, and contains other node specific configuration.
- cluster.conf(5)">
-
- <attribute name="name" rha:description="The hostname or IP address
- of the node. cluster.conf(5)"/>
-
- <attribute name="nodeid" rha:description="A unique integer to use
- as a node identifier. cluster.conf(5)">
- <data type="positiveInteger"/>
- </attribute>
-
- <optional>
- <attribute name="votes" rha:description="The number of votes the
- node contributes to quorum. cman(5)">
- <data type="positiveInteger"/>
- </attribute>
- </optional>
-
- <optional>
- <attribute name="weight" rha:description="The dlm locking weight.
- dlm_controld(8)"/>
- </optional>
-
- <interleave>
- <optional>
- <ref name="ALTNAME"/>
- </optional>
- <optional>
- <ref name="FENCE"/>
- </optional>
- <optional>
- <ref name="UNFENCE"/>
- </optional>
- </interleave>
-
- </element>
- </zeroOrMore>
- </element>
-<!-- end clusternode block -->
-
-<!-- fencedevices block -->
- <optional>
- <element name="fencedevices" rha:description="Contains all fence
- device definitions. fenced(8)">
- <zeroOrMore>
- <element name="fencedevice" rha:description="Defines fence device
- properties. fenced(8)">
-
- <attribute name="name" rha:description="A name that is used to
- reference this fence device from clusternode fence section.
- For XML validation purposes, it shall not start with a digit.
- fenced(8)">
- <data type="ID"/>
- </attribute>
-
- <attribute name="agent" rha:description="The fence agent to be
- used. fenced(8)"/>
-
- <ref name="FENCEDEVICEOPTIONS"/>
-
- </element>
- </zeroOrMore>
- </element>
- </optional>
-<!-- end fencedevices block -->
-
-<!-- rm block -->
- <optional>
- <element name="rm" rha:description="This element and its attributes
- define resources (for example an IP address) required to create HA
- cluster services, the HA cluster services themselves, and failover
- domains for the HA cluster services.">
- <optional>
- <!-- FIXME: The following text needs clarifying. What is meant by
- "...for all levels less than the selected."? -->
- <attribute name="log_level" rha:description="An integer 0-7,
- inclusive, for all levels less than the selected.
- 0, system is unusable, emergency;
- 1, action must be taken immediately;
- 2, critical conditions;
- 3, error conditions;
- 4, warning conditions;
- 5, normal but significant condition;
- 6, informational;
- 7, debug-level messages." rha:sample="6">
- <data type="integer"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="status_child_max" rha:description="Maximum number of status child threads." rha:sample="">
- <data type="integer"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="status_poll_interval" rha:description="Scan the resource tree every X seconds for resources which need to be checked."
- rha:sample="">
- <data type="integer"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="transition_throttling" rha:description="During transitions, keep the event processor alive for this many seconds."
- rha:sample="">
- <data type="integer"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="central_processing" rha:description="Enable central processing mode (requires cluster-wide shut down and restart of rgmanager.)."
- rha:sample="">
- <data type="integer"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="log_facility" rha:description="The facility is one
- of the following keywords: auth, authpriv, cron, daemon, kern,
- lpr, mail, news, syslog, user, uucp and local0 through local7"/>
- </optional>
- <optional>
- <attribute name="disabled" rha:description="Disables rgmanager entirely if set to 1. Do not set unless you really mean it." rha:sample="">
- <data type="integer"/>
- </attribute>
- </optional>
- <interleave>
- <optional>
- <element name="failoverdomains" rha:description="Failover domain definitions.">
- <zeroOrMore>
- <element name="failoverdomain" rha:description="Specifies
- properties of a specific failover domain">
- <attribute name="name" rha:description="The name of the failover
- domain." rha:sample="foo"/>
- <optional>
- <attribute name="ordered" rha:description="Set value to 1 if
- the failover domain is ordered; set value to 0 if
- unordered." rha:default="0" rha:sample="1"/>
- </optional>
- <optional>
- <attribute name="restricted" rha:description="Set value to 1 if
- the failover domain is restricted; set value to 0 if
- unrestricted." rha:default="0" rha:sample="1"/>
- </optional>
- <optional>
- <attribute name="nofailback" rha:description="Do not move service to a more preferred node if it is currently running." rha:sample=""/>
- </optional>
- <zeroOrMore>
- <element name="failoverdomainnode" rha:description="A node in
- a failover domain">
- <optional>
- <attribute name="priority" rha:description="A number
- specifying the priority; lower numbers having higher
- priority"
- rha:sample="1"/>
- </optional>
- <attribute name="name" rha:description="Name of the node."
- rha:sample="member2"/>
- </element>
- </zeroOrMore>
- </element>
- </zeroOrMore>
- </element>
- </optional> <!-- End of failoverdomains block -->
- <optional>
- <element name="events" rha:description="Event definitions (central_processing only).">
- <zeroOrMore>
- <element name="event" rha:description="Defines an event.">
- <attribute name="name" rha:description="Symbolic name for an event." rha:sample=""/>
- <optional>
- <text/>
- </optional>
- <optional>
- <attribute name="file" rha:description="Path to S/Lang script to execute." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="priority" rha:description="Order (1..99) of event." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="class" rha:description="Event class (service, node)." rha:sample=""/>
- </optional>
- <!-- Service event class attributes -->
- <optional>
- <attribute name="service" rha:description="(Service) The service name (service:foo) must match the specified value in order for the event script to be run." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="service_state" rha:description="(Service) The service's state must match the specified value in order for the script to be run (started, stopped, disabled, failed)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="service_owner" rha:description="(Service) The service owner must match the specified value in order for the event script to be run." rha:sample=""/>
- </optional>
- <!-- Node event -->
- <optional>
- <attribute name="node" rha:description="(Node) The node name must match the specified value in order for the script to be run." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="node_id" rha:description="(Node) The node ID must match the specified value in order for the script to be run." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="node_state" rha:description="(Node) The node state must match the specified value (0 or 1) in order for the script to be run." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="node_clean" rha:description="(Node) The node must have been fenced in order for the script to be run." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="node_local" rha:description="(Node) This script may only run on the current central processing node." rha:sample=""/>
- </optional>
- <!-- Config event attributes -->
- <!-- NOT USED -->
- </element>
- </zeroOrMore>
- </element>
- </optional> <!-- End of events block -->
- <optional>
- <element name="resources" rha:description="Defines global resources which may be referenced in services. You may redefine actions for resources here, but child resource definitions are ignored in this section.">
- <zeroOrMore>
- <ref name="CHILDREN"/>
- </zeroOrMore>
- </element>
- </optional>
- <optional>
- <element name="resource-defaults" rha:description="This section allows the administrator to change defaults for resource agents. Overriding parameters which must be unique is not allowed. Overriding a value which, by default, inherits a value from a parent resource will disable inheritance for that resource type.">
- <zeroOrMore>
- <ref name="CHILDREN"/>
- </zeroOrMore>
- </element>
- </optional>
- <zeroOrMore>
- <ref name="SERVICE"/>
- </zeroOrMore>
- <zeroOrMore>
- <ref name="VM"/>
- </zeroOrMore>
- </interleave>
- </element>
- </optional>
-
-<!-- clvmd block -->
- <optional>
- <element name="clvmd" rha:description="The clvmd element contains
- attributes that define parameters for the cluster LVM daemon.">
- <optional>
- <attribute name="interface" rha:description="The interface attribute
- tells clvmd which cluster interface it should use for internode
- communications and locking. Valid values for this depend on
- how the daemon is configured at compile-time, but are typically
- cman, corosync or openais." rha:sample="cman"/>
- </optional>
- </element>
- </optional>
-
- </interleave>
-
-
-</element> <!-- cluster end -->
-</start>
-
-<!-- begin mcast definitions -->
-
- <define name="MULTICASTOPTS">
- <optional>
- <attribute name="addr" rha:description="A multicast address specified
- by a user. If you do specify a multicast address, you should
- use the 239.192.x.x series that cman uses. Otherwise, using a
- multicast address outside that range may cause unpredictable
- results. For example, using 224.0.0.x (All hosts on the network)
- may not be routed correctly, or even routed at all by some
- hardware." rha:sample="239.192.0.1"/>
- </optional>
- <optional>
- <attribute name="ttl" rha:description="Define the TTL (time to live) of
- a multicast packets. Useful only if nodes are on different subnets and
- a multicast router is available in between." rha:default="1"
- rha:sample="24"/>
- </optional>
- <optional>
- <attribute name="port">
- <data type="nonNegativeInteger"/>
- </attribute>
- </optional>
- </define>
-
-<!-- end mcast definitions -->
-
-<!-- begin node altname definitions -->
-
- <define name="ALTNAME">
- <element name="altname" rha:description="Defines a second network
- interface to use for corosync redundant ring mode. cman(5)">
-
- <attribute name="name" rha:description="A second hostname or IP
- address of the node. cman(5)"/>
-
- <optional>
- <attribute name="port" rha:description="The network port to use
- on the second interface. cman(5)"/>
- </optional>
-
- <optional>
- <attribute name="mcast" rha:description="The multicast address
- to use on the second interface. cman(5)"/>
- </optional>
-
- <optional>
- <attribute name="ttl" rha:description="The multicast TTL
- to use on the second interface. cman(5)"/>
- </optional>
- </element>
- </define>
-
-<!-- end node altname definitions -->
-
-<!-- begin node fence definitions -->
-
- <define name="FENCE">
- <element name="fence" rha:description="Contains methods for fencing
- the node in different ways. fenced(8)">
-
- <zeroOrMore>
-
- <element name="method" rha:description="Contains one or more devices
- for fencing the node a single way. fenced(8)">
-
- <attribute name="name" rha:description="A name used to distinguish
- multiple methods from each other. fenced(8)"/>
-
- <zeroOrMore>
- <ref name="DEVICE"/>
- </zeroOrMore>
-
- </element>
-
- </zeroOrMore>
- </element>
- </define>
-
- <define name="UNFENCE">
- <element name="unfence" rha:description="Contains devices for unfencing
- the node. fence_node(8)">
- <zeroOrMore>
- <ref name="DEVICE"/>
- </zeroOrMore>
- </element>
- </define>
-
- <define name="DEVICE">
- <element name="device" rha:description="Defines the properties of a
- device used for fencing or unfencing a node. fenced(8)">
-
- <attribute name="name" rha:description="The name of a fencedevice
- defined in the fencedevices section. fenced(8)">
- <data type="IDREF"/>
- </attribute>
-
- <ref name="FENCEDEVICEOPTIONS"/>
-
- </element>
- </define>
-<!-- end node fence definitions -->
diff --git a/config/tools/xml/cluster.rng.in.tail b/config/tools/xml/cluster.rng.in.tail
deleted file mode 100644
index d4e2278..0000000
--- a/config/tools/xml/cluster.rng.in.tail
+++ /dev/null
@@ -1 +0,0 @@
-</grammar>
diff --git a/configure b/configure
deleted file mode 100755
index 677d305..0000000
--- a/configure
+++ /dev/null
@@ -1,686 +0,0 @@
-#!/usr/bin/perl -w
-
-use warnings;
-use Getopt::Long;
-use POSIX qw(uname);
-use Cwd 'abs_path';
-use File::Basename;
-use File::Spec;
-
-print "\nConfiguring Makefiles for your system...\n";
-
-# Set a bunch of variables
-
-my @invoke = @ARGV;
-
-my $ret = 0;
-
-# this should be only the major version without the extra version
-# eg. only the first 3 digits
-my $required_kernelversion = '2.6.31';
-
-my $outoftree = '';
-
-my %options = (
- help => \$help,
- cc => \$cc,
- debug => \$debug,
- cflags => \$cflags,
- extracflags => \$extracflags,
- enable_paranoia_cflags => \$enable_paranoia_cflags,
- ldflags => \$ldflags,
- extraldflags => \$extraldflags,
- objdir => \$objdir,
- kernel_src => \$kernel_src,
- incdir => \$incdir,
- libdir => \$libdir,
- ccsincdir => \$ccsincdir,
- ccslibdir => \$ccslibdir,
- cmanincdir => \$cmanincdir,
- cmanlibdir => \$cmanlibdir,
- dlmincdir => \$dlmincdir,
- dlmlibdir => \$dlmlibdir,
- dlmcontrolincdir => \$dlmcontrolincdir,
- dlmcontrollibdir => \$dlmcontrollibdir,
- fenceincdir => \$fenceincdir,
- fencelibdir => \$fencelibdir,
- fencedincdir => \$fencedincdir,
- fencedlibdir => \$fencedlibdir,
- logtincdir => \$logtincdir,
- logtlibdir => \$logtlibdir,
- ncursesincdir => \$ncursesincdir,
- ncurseslibdir => \$ncurseslibdir,
- slangincdir => \$slangincdir,
- slanglibdir => \$slanglibdir,
- corosyncincdir => \$corosyncincdir,
- corosynclibdir => \$corosynclibdir,
- openaisincdir => \$openaisincdir,
- openaislibdir => \$openaislibdir,
- corosyncbin => \$corosyncbin,
- zlibincdir => \$zlibincdir,
- zliblibdir => \$zliblibdir,
- ldapincdir => \$ldapincdir,
- ldaplibdir => \$ldaplibdir,
- libexecdir => \$libexecdir,
- mandir => \$mandir,
- prefix => \$prefix,
- sbindir => \$sbindir,
- initddir => \$initddir,
- sharedir => \$sharedir,
- docdir => \$docdir,
- logdir => \$logdir,
- logrotatedir => \$logrotatedir,
- syslogfacility => \$syslogfacility,
- sysloglevel => \$sysloglevel,
- confdir => \$confdir,
- conffile => \$conffile,
- enable_contrib => \$enable_contrib,
- disable_dbus => \$disable_dbus,
- somajor => \$somajor,
- sominor => \$sominor,
- release_version => \$release_version,
- without_common => \$without_common,
- without_config => \$without_config,
- without_cman => \$without_cman,
- without_dlm => \$without_dlm,
- without_group => \$without_group,
- without_fence => \$without_fence,
- without_rgmanager => \$without_rgmanager,
- without_bindings => \$without_bindings,
- disable_kernel_check => \$disable_kernel_check,
-);
-
-my $err = &GetOptions (\%options,
- 'help',
- 'cc=s',
- 'debug',
- 'cflags=s',
- 'extracflags=s',
- 'enable_paranoia_cflags',
- 'ldflags=s',
- 'extraldflags=s',
- 'objdir=s',
- 'kernel_src=s',
- 'incdir=s',
- 'libdir=s',
- 'ccsincdir=s',
- 'ccslibdir=s',
- 'cmanincdir=s',
- 'cmanlibdir=s',
- 'dlmincdir=s',
- 'dlmlibdir=s',
- 'dlmcontrolincdir=s',
- 'dlmcontrollibdir=s',
- 'fenceincdir=s',
- 'fencelibdir=s',
- 'fencedincdir=s',
- 'fencedlibdir=s',
- 'logtincdir=s',
- 'logtlibdir=s',
- 'ncursesincdir=s',
- 'ncurseslibdir=s',
- 'slangincdir=s',
- 'slanglibdir=s',
- 'corosyncincdir=s',
- 'corosynclibdir=s',
- 'openaisincdir=s',
- 'openaislibdir=s',
- 'corosyncbin=s',
- 'zlibincdir=s',
- 'zliblibdir=s',
- 'ldapincdir=s',
- 'ldaplibdir=s',
- 'libexecdir=s',
- 'mandir=s',
- 'prefix=s',
- 'sbindir=s',
- 'initddir=s',
- 'sharedir=s',
- 'docdir=s',
- 'logdir=s',
- 'logrotatedir=s',
- 'syslogfacility=s',
- 'sysloglevel=s',
- 'confdir=s',
- 'conffile=s',
- 'somajor=s',
- 'sominor=s',
- 'release_version=s',
- 'enable_contrib',
- 'disable_dbus',
- 'without_common',
- 'without_config',
- 'without_cman',
- 'without_dlm',
- 'without_group',
- 'without_fence',
- 'without_rgmanager',
- 'without_bindings',
- 'disable_kernel_check');
-
-if(!$err) {
- $ret = 1;
- print "*** ERROR: Invalid option detected ***\n";
-}
-
-# Check for the --help flag
-if ($help || !$err) {
- $_ = $0;
- s/.*\.\/(.*)/$1/;
- print "Usage: $_ [flags]\n";
- print "--help\t\tPrints this usage information\n\n";
- print "install flags:\n";
- print "--prefix=\tthe base directory to install into. (Default: /usr)\n";
- print "--sbindir=\tthe base directory for system binaries. (Default: {prefix}/sbin)\n";
- print "--initddir=\tthe base directory for init.d scripts. (Default: /etc/init.d)\n";
- print "--libdir=\tthe base directory for libraries. (Default: {prefix}/lib)\n";
- print "--libexecdir=\tthe base directory for executable components. (Default: {prefix}/libexec)\n";
- print "--sharedir=\tthe base directory for misc cluster files. (Default: {prefix}/share/cluster)\n";
- print "--docdir=\tthe base directory for misc cluster documentation files. (Default: {prefix}/share/doc/cluster)\n";
- print "--logdir=\tthe base directory for cluster logging files. (Default: /var/log/cluster/)\n";
- print "--logrotatedir=\tthe base directory for logrorate.d files. (Default: /etc/logrotate.d/)\n";
- print "--syslogfacility=\tset the default syslog facility. (Default: LOG_LOCAL4)\n";
- print "--sysloglevel=\tset the default syslog level. (Default: LOG_INFO)\n";
- print "--confdir=\tthe cluster config directory. (Default: /etc/cluster)\n";
- print "--conffile=\tthe cluster config file. (Default: cluster.conf)\n";
- print "--mandir=\tthe base directory for man pages. (Default: {prefix}/share/man)\n";
- print "\nbuild flags:\n";
- print "--cc=\t\tcompiler to use. (Default: gcc)\n";
- print "--debug\t\tEnable debugging build. Changes default optimization CFLAGS to -O0 -DDEBUG -ggdb3\n";
- print "--cflags=\toverride default CFLAGS settings.\n";
- print "--extracflags=\tadd extra compiler options to default CFLAGS setting. (Default: none)\n";
- print "--enable_paranoia_cflags=\tadd paranoia compiler options to default CFLAGS setting. (Default: -Werror)\n";
- print "--ldflags=\toverride default LDFLAGS settings. (Default: none)\n";
- print "--extraldflags=\tadd extra linking options to default LDFLAGS settings. (Default: none)\n";
- print "--objdir=\tspecify directory where to store object files. (Defaults: current build dir)\n";
- print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: /lib/modules/`uname -r`/source\n\t\tif available or \$kernel_build as fallback)\n";
- print "--incdir=\tthe base directory for include files. (Default: {prefix}/include)\n";
- print "--ccsincdir=\tthe base directory for ccs include files. (Default: ./config/libs/libccsconfdb)\n";
- print "--ccslibdir=\tthe base directory for ccs libraries. (Default: ./config/libs/libccsconfdb)\n";
- print "--cmanincdir=\tthe base directory for cman include files. (Default: ./cman/lib)\n";
- print "--cmanlibdir=\tthe base directory for cman libraries. (Default: ./cman/lib)\n";
- print "--dlmincdir=\tthe base directory for dlm include files. (Default: ./dlm/libdlm)\n";
- print "--dlmlibdir=\tthe base directory for dlm libraries. (Default: ./dlm/libdlm)\n";
- print "--dlmcontrolincdir=\tthe base directory for dlmcontrol include files. (Default: ./dlm/libdlmcontrol)\n";
- print "--dlmcontrollibdir=\tthe base directory for dlmcontrol libraries. (Default: ./dlm/libdlmcontrol)\n";
- print "--fenceincdir=\tthe base directory for fence include files. (Default: ./fence/libfence)\n";
- print "--fencelibdir=\tthe base directory for fence libraries. (Default: ./fence/libfence)\n";
- print "--fencedincdir=\tthe base directory for fence include files. (Default: ./fence/libfenced)\n";
- print "--fencedlibdir=\tthe base directory for fence libraries. (Default: ./fence/libfenced)\n";
- print "--logtincdir=\tthe base directory for logthread include files. (Default: ./common/liblogthread)\n";
- print "--logtlibdir=\tthe base directory for logthread libraries. (Default: ./common/liblogthread)\n";
- print "--ncursesincdir=\tthe base directory for ncurses include files. (Default: {incdir})\n";
- print "--ncurseslibdir=\tthe base directory for ncurses libraries. (Default: {libdir})\n";
- print "--slangincdir=\tthe base directory for S-Lang include files. (Default: {incdir})\n";
- print "--slanglibdir=\tthe base directory for S-Lang libraries. (Default: {libdir})\n";
- print "--corosyncincdir=\tthe base directory for corosync include files. (Default: {incdir})\n";
- print "--corosynclibdir=\tthe base directory for corosync libraries. (Default: {libdir}/corosync)\n";
- print "--openaisincdir=\tthe base directory for openais include files. (Default: {incdir})\n";
- print "--openaislibdir=\tthe base directory for openais libraries. (Default: {libdir}/openais)\n";
- print "--corosyncbin=\tlocation of corosync executable file. (Default: /usr/sbin/corosync)\n";
- print "--zlibincdir=\tthe base directory for libz include files. (Default: {incdir})\n";
- print "--zliblibdir=\tthe base directory for libz libraries. (Default: {libdir})\n";
- print "--ldapincdir=\tthe base directory for ldap include files. (Default: {incdir})\n";
- print "--ldaplibdir=\tthe base directory for ldap libraries. (Default: {libdir})\n";
- print "--enable_contrib\tEnable build of community contributed code/tools. (Default: no)\n";
- print "--disable_dbus\tDisable built-in support for dbus notifications. (Default: no)\n";
- print "--without_common\tDisable common building (Default: enabled)\n";
- print "--without_config\tDisable config building (Default: enabled)\n";
- print "--without_cman\tDisable cman building (Default: enabled)\n";
- print "--without_dlm\tDisable dlm building (Default: enabled)\n";
- print "--without_group\tDisable group building (Default: enabled)\n";
- print "--without_fence\tDisable fence building (Default: enabled)\n";
- print "--without_rgmanager\tDisable rgmanager building (Default: enabled)\n";
- print "--without_bindings\tDisable perl/python bindings building (Default: enabled)\n";
- print "--disable_kernel_check\tDisable kernel version check (Default: enabled)\n";
- exit $ret;
-}
-
-sub kernel_version {
- my $makefile_path = shift;
- my $required_version = shift;
-
- print "\nChecking kernel:\n";
-
- # add autoconf to the path
- $makefile_path .= '/Makefile';
- my @version = split /\./, $required_version;
- if ( -f $makefile_path ) {
- # open the toplevel Makefile to feth VERSION, PATCHLEVEL and SUBLEVEL
- open MAKEFILE, '<', $makefile_path;
- while (<MAKEFILE>) {
- $build_version = $1 if /^VERSION = (\d+)/;
- $build_patchlevel = $1 if /^PATCHLEVEL = (\d+)/;
- $build_sublevel = $1 if /^SUBLEVEL = (\d+)/;
- last if (defined $build_version && defined $build_patchlevel && defined $build_sublevel);
- }
- close MAKEFILE;
- # Warn and continue if kernel version was not found
- if (not defined $build_version || not defined $build_patchlevel || not defined $build_sublevel) {
- print " WARNING: Could not determine kernel version.\n";
- print " Build might fail!\n";
- return 1;
- }
- # checking VERSION, PATCHLEVEL and SUBLEVEL for the supplied kernel
- if (($build_version > $version[0]) ||
- $build_version == $version[0] &&
- $build_patchlevel >= $version[1] &&
- $build_sublevel >= $version[2]) {
- print " Current kernel version appears to be OK\n";
- return 1;
- } else {
- print " Current kernel version: ",$build_version, "." , $build_patchlevel, ".", $build_sublevel, "\n Minimum kernel version: ",$required_version,"\n";
- print " FAILED!\n";
- return 0;
- }
- } else {
- print " Unable to find ($makefile_path)!\n";
- print " Make sure that:\n - the above path is correct\n";
- print " - your kernel is properly configured and prepared.\n";
- print " - kernel_build and kernel_src options to configure are set properly.\n";
- return 0;
- }
-}
-
-sub symlinks {
- my $dir = shift;
- my $pattern = shift;
- @args = "find $dir -type f -name $pattern";
- open (IFILE, "@args |");
- while (<IFILE>) {
- chomp;
- s|\./||g;
- s|.*make\/defines.mk||g;
- $dirname = dirname($_);
- $filename = basename($_);
- system("mkdir -p $objdir/$dirname");
- symlink("${cdir}/$_","$objdir/$dirname/$filename");
- }
- close IFILE;
- return 0;
-}
-
-$pwd = `pwd`;
-chomp($pwd);
-
-if (!$cc) {
- $cc="gcc";
-}
-if (!$cflags) {
- $cflags="";
- $cflags="${cflags} -Wall -Wformat=2 -Wshadow -Wmissing-prototypes";
- $cflags="${cflags} -Wstrict-prototypes -Wdeclaration-after-statement";
- $cflags="${cflags} -Wpointer-arith -Wwrite-strings -Wcast-align";
- $cflags="${cflags} -Wbad-function-cast -Wmissing-format-attribute";
- $cflags="${cflags} -Wformat-security -Wformat-nonliteral -Wno-long-long";
- $cflags="${cflags} -Wno-strict-aliasing -Wmissing-declarations";
- if (!$debug) {
- $cflags="${cflags} -O2";
- } else {
- $cflags="${cflags} -O0 -DDEBUG";
- }
- $cflags="${cflags} -ggdb3 -MD -MP -MF \$<.Tpo";
-}
-if ($extracflags) {
- $cflags="${cflags} ${extracflags}";
-}
-if ($enable_paranoia_cflags) {
- $cflags="-Werror ${cflags}";
-}
-if (!$ldflags) {
- $ldflags="";
-}
-if ($extraldflags) {
- $ldflags="${ldflags} ${extraldflags}";
-}
-if (!$prefix) {
- $prefix="/usr";
-}
-
-print "\nChecking tree: ";
-if (!$objdir) {
- $objdir="${pwd}";
-}
-$objdir = abs_path( $objdir );
-$cdir = dirname ( abs_path( $0 ) );
-unless ("$cdir" eq "$objdir") {
- chdir "$cdir";
-}
-
-if (! -d "$objdir/make") {
- print "setting up $objdir\n";
- mkdir "$objdir";
- symlinks(".","Makefile");
- symlinks(".","*.mk");
- symlinks("bindings","*.bindings");
- symlinks("bindings","*.pl");
- symlinks("bindings","*.xs");
- symlinks("bindings","*.PL");
- symlinks("bindings","MANIFEST");
- symlinks("bindings","typemap");
- $outoftree = 1;
-} else {
- print "nothing to do\n";
-}
-
-my @un = POSIX::uname();
-if (!$kernel_build) {
- if (-d "/lib/modules/$un[2]/build") {
- $kernel_build="/lib/modules/$un[2]/build";
- } else {
- $kernel_build="/usr/src/linux";
- }
-}
-if (!$kernel_src) {
- if (-d "/lib/modules/$un[2]/source") {
- $kernel_src="/lib/modules/$un[2]/source";
- } else {
- $kernel_src=$kernel_build;
- }
-}
-if (not $disable_kernel_check and !kernel_version($kernel_src,$required_kernelversion)) {
- exit 1;
-}
-if (!$incdir) {
- $incdir="${prefix}/include";
-}
-if (!$libdir) {
- $libdir="${prefix}/lib";
-}
-if (!$ccsincdir) {
- $ccsincdir="${cdir}/config/libs/libccsconfdb";
-}
-if (!$ccslibdir) {
- $ccslibdir="${objdir}/config/libs/libccsconfdb";
-}
-if (!$cmanincdir) {
- $cmanincdir="${cdir}/cman/lib";
-}
-if (!$cmanlibdir) {
- $cmanlibdir="${objdir}/cman/lib";
-}
-if (!$dlmincdir) {
- $dlmincdir="${cdir}/dlm/libdlm";
-}
-if (!$dlmlibdir) {
- $dlmlibdir="${objdir}/dlm/libdlm";
-}
-if (!$dlmcontrolincdir) {
- $dlmcontrolincdir="${cdir}/dlm/libdlmcontrol";
-}
-if (!$dlmcontrollibdir) {
- $dlmcontrollibdir="${objdir}/dlm/libdlmcontrol";
-}
-if (!$fenceincdir) {
- $fenceincdir="${cdir}/fence/libfence";
-}
-if (!$fencelibdir) {
- $fencelibdir="${objdir}/fence/libfence";
-}
-if (!$fencedincdir) {
- $fencedincdir="${cdir}/fence/libfenced";
-}
-if (!$fencedlibdir) {
- $fencedlibdir="${objdir}/fence/libfenced";
-}
-if (!$logtincdir) {
- $logtincdir="${cdir}/common/liblogthread";
-}
-if (!$logtlibdir) {
- $logtlibdir="${objdir}/common/liblogthread";
-}
-if (!$ncursesincdir) {
- $ncursesincdir="${incdir}";
-}
-if (!$ncurseslibdir) {
- $ncurseslibdir="${libdir}";
-}
-if (!$slangincdir) {
- $slangincdir="${incdir}";
- if (! -f "$slangincdir/slang.h") {
- $slangincdir="${incdir}/slang";
- }
-}
-if (!$slanglibdir) {
- $slanglibdir="${libdir}";
-}
-if (!$corosyncincdir) {
- $corosyncincdir="${incdir}";
-}
-if (!$corosynclibdir) {
- $corosynclibdir="${libdir}/corosync";
-}
-if (!$openaisincdir) {
- $openaisincdir="${incdir}";
-}
-if (!$openaislibdir) {
- $openaislibdir="${libdir}/openais";
-}
-if (!$corosyncbin) {
- $corosyncbin="/usr/sbin/corosync";
-}
-if (!$zlibincdir) {
- $zlibincdir="${incdir}";
-}
-if (!$zliblibdir) {
- $zliblibdir="${libdir}";
-}
-if (!$ldapincdir) {
- $ldapincdir="${incdir}";
-}
-if (!$ldaplibdir) {
- $ldaplibdir="${libdir}";
-}
-if (!$libexecdir) {
- $libexecdir="${prefix}/libexec";
-}
-if (!$mandir) {
- $mandir="${prefix}/share/man";
-}
-if (!$sbindir) {
- $sbindir="${prefix}/sbin";
-}
-$relativesbin=File::Spec->abs2rel("/sbin", $sbindir);
-if (!$initddir) {
- $initddir="/etc/init.d";
-}
-if (!$sharedir) {
- $sharedir="${prefix}/share/cluster";
-}
-if (!$docdir) {
- $docdir="${prefix}/share/doc/cluster";
-}
-if (!$logdir) {
- $logdir="/var/log/cluster";
-}
-if (!$logrotatedir) {
- $logrotatedir="/etc/logrotate.d";
-}
-if (!$syslogfacility) {
- $syslogfacility="LOG_LOCAL4";
-}
-if (!$sysloglevel) {
- $sysloglevel="LOG_INFO";
-}
-if (!$confdir) {
- $confdir="/etc/cluster";
-}
-if (!$conffile) {
- $conffile="cluster.conf";
-}
-if (!$enable_contrib) {
- $enable_contrib="";
-}
-if (!$disable_dbus) {
- $disable_dbus="";
-}
-if (!$without_common) {
- $without_common="";
-}
-if (!$without_config) {
- $without_config="";
-}
-if (!$without_cman) {
- $without_cman="";
-}
-if (!$without_dlm) {
- $without_dlm="";
-}
-if (!$without_group) {
- $without_group="";
-}
-if (!$without_fence) {
- $without_fence="";
-}
-if (!$without_rgmanager) {
- $without_rgmanager="";
-}
-if (!$without_bindings) {
- $without_bindings="";
-}
-if (!$disable_kernel_check) {
- $disable_kernel_check=0;
-}
-if (defined($somajor) && not length $somajor) {
- $somajor="";
-}
-if (defined($sominor) && not length $sominor) {
- $sominor="";
-}
-if (defined($release_version) && not length $release_version) {
- $release_version="";
-}
-
-open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin";
-open OFILE, ">${objdir}/make/defines.mk" or die "Can't redirect stdout";
-
-print OFILE "# This file was generated by configure from defines.mk.input\n";
-
-while (<IFILE>) {
- chomp;
- $_ =~ s/\@SRCDIR\@/$cdir/;
- $_ =~ s/\@CC\@/$cc/;
- $_ =~ s/\@CFLAGS\@/$cflags/;
- $_ =~ s/\@LDFLAGS\@/$ldflags/;
- $_ =~ s/\@OBJDIR\@/$objdir/;
- $_ =~ s/\@KERNEL_SRC\@/$kernel_src/;
- $_ =~ s/\@INCDIR\@/$incdir/;
- $_ =~ s/\@LIBDIR\@/$libdir/;
- $_ =~ s/\@CCSINCDIR\@/$ccsincdir/;
- $_ =~ s/\@CCSLIBDIR\@/$ccslibdir/;
- $_ =~ s/\@CMANINCDIR\@/$cmanincdir/;
- $_ =~ s/\@CMANLIBDIR\@/$cmanlibdir/;
- $_ =~ s/\@DLMINCDIR\@/$dlmincdir/;
- $_ =~ s/\@DLMLIBDIR\@/$dlmlibdir/;
- $_ =~ s/\@DLMCONTROLINCDIR\@/$dlmcontrolincdir/;
- $_ =~ s/\@DLMCONTROLLIBDIR\@/$dlmcontrollibdir/;
- $_ =~ s/\@FENCEINCDIR\@/$fenceincdir/;
- $_ =~ s/\@FENCELIBDIR\@/$fencelibdir/;
- $_ =~ s/\@FENCEDINCDIR\@/$fencedincdir/;
- $_ =~ s/\@FENCEDLIBDIR\@/$fencedlibdir/;
- $_ =~ s/\@LOGTINCDIR\@/$logtincdir/;
- $_ =~ s/\@LOGTLIBDIR\@/$logtlibdir/;
- $_ =~ s/\@NCURSESINCDIR\@/$ncursesincdir/;
- $_ =~ s/\@NCURSESLIBDIR\@/$ncurseslibdir/;
- $_ =~ s/\@SLANGINCDIR\@/$slangincdir/;
- $_ =~ s/\@SLANGLIBDIR\@/$slanglibdir/;
- $_ =~ s/\@COROSYNCINCDIR\@/$corosyncincdir/;
- $_ =~ s/\@COROSYNCLIBDIR\@/$corosynclibdir/;
- $_ =~ s/\@OPENAISINCDIR\@/$openaisincdir/;
- $_ =~ s/\@OPENAISLIBDIR\@/$openaislibdir/;
- $_ =~ s/\@COROSYNCBIN\@/$corosyncbin/;
- $_ =~ s/\@LDAPINCDIR\@/$ldapincdir/;
- $_ =~ s/\@LDAPLIBDIR\@/$ldaplibdir/;
- $_ =~ s/\@ZLIBINCDIR\@/$zlibincdir/;
- $_ =~ s/\@ZLIBLIBDIR\@/$zliblibdir/;
- $_ =~ s/\@LIBEXECDIR\@/$libexecdir/;
- $_ =~ s/\@MANDIR\@/$mandir/;
- $_ =~ s/\@SBINDIR\@/$sbindir/;
- $_ =~ s/\@RELATIVESBIN\@/$relativesbin/;
- $_ =~ s/\@PREFIX\@/$prefix/;
- $_ =~ s/\@INITDDIR\@/$initddir/;
- $_ =~ s/\@SHAREDIR\@/$sharedir/;
- $_ =~ s/\@DOCDIR\@/$docdir/;
- $_ =~ s/\@LOGDIR\@/$logdir/;
- $_ =~ s/\@LOGROTATEDIR\@/$logrotatedir/;
- $_ =~ s/\@SYSLOGFACILITY\@/$syslogfacility/;
- $_ =~ s/\@SYSLOGLEVEL\@/$sysloglevel/;
- $_ =~ s/\@CONFDIR\@/$confdir/;
- $_ =~ s/\@CONFFILE\@/$conffile/;
- $_ =~ s/\@ENABLE_CONTRIB\@/$enable_contrib/;
- $_ =~ s/\@DISABLE_DBUS\@/$disable_dbus/;
- $_ =~ s/\@DISABLE_COMMON\@/$without_common/;
- $_ =~ s/\@DISABLE_CONFIG\@/$without_config/;
- $_ =~ s/\@DISABLE_CMAN\@/$without_cman/;
- $_ =~ s/\@DISABLE_DLM\@/$without_dlm/;
- $_ =~ s/\@DISABLE_GROUP\@/$without_group/;
- $_ =~ s/\@DISABLE_FENCE\@/$without_fence/;
- $_ =~ s/\@DISABLE_RGMANAGER\@/$without_rgmanager/;
- $_ =~ s/\@DISABLE_BINDINGS\@/$without_bindings/;
- $_ =~ s/\@OUTOFTREEBUILD\@/$outoftree/;
-
- print OFILE "$_\n";
-}
-
-close IFILE;
-
-if ((not defined($somajor)) || (not defined($sominor)) || (not defined($release_version))) {
-
- my $current_soname;
- my $current_version;
- if ( -f 'make/official_release_version' ) {
- open OFFICIAL_VERSION, '<', "make/official_release_version";
- while (<OFFICIAL_VERSION>) {
- if ($_ =~ /SONAME/) {
- $current_soname = $_;
- }
- if ($_ =~ /VERSION/) {
- $current_version = $_;
- }
- }
- close OFFICIAL_VERSION;
- }
-
- if ((not defined($somajor)) || (not defined($sominor))) {
- if (not defined($current_soname)) {
- print "ERROR: SONAME not defined in make/official_release_version\n";
- exit 1;
- } else {
- $current_soname =~ s/.*"(.*)"\n/$1/;
- my @release_soname = split /\./, $current_soname;
- $somajor = $release_soname[0];
- $sominor = $release_soname[1];
- }
- }
-
- if (not defined($release_version)) {
- if (not defined($current_version)) {
- $release_version = `date +%s`;
- chomp $release_version;
- } else {
- $release_version = $current_version;
- $release_version =~ s/.*"(.*)"\n/$1/;
- }
- }
-}
-
-print OFILE "ifndef SOMAJOR\n";
-print OFILE "SOMAJOR = $somajor\n";
-print OFILE "endif\n";
-print OFILE "ifndef SOMINOR\n";
-print OFILE "SOMINOR = $sominor\n";
-print OFILE "endif\n";
-print OFILE "RELEASE_VERSION = $release_version\n";
-print OFILE "CFLAGS += -DRELEASE_VERSION=\\\"$release_version\\\"\n";
-
-close OFILE;
-
-open OFILE, ">${objdir}/.configure.sh.tmp" or die "Can't redirect stdout";
-print OFILE "#!/bin/bash\n";
-print OFILE "$0 @invoke \$@\n";
-print OFILE "exit \$?\n";
-close OFILE;
-
-system("mv ${objdir}/.configure.sh.tmp ${objdir}/.configure.sh");
-
-print "Completed Makefile configuration\n\n";
diff --git a/contrib/Makefile b/contrib/Makefile
deleted file mode 100644
index 368e035..0000000
--- a/contrib/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-include ../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-ifdef contrib_code
-SUBDIRS=libaislock
-endif
diff --git a/contrib/libaislock/Makefile b/contrib/libaislock/Makefile
deleted file mode 100644
index 269d845..0000000
--- a/contrib/libaislock/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-TARGET= libaislock
-
-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${dlmincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${dlmlibdir} -ldlm
-LDFLAGS += -lpthread
diff --git a/contrib/libaislock/libaislock.c b/contrib/libaislock/libaislock.c
deleted file mode 100644
index 4de90ba..0000000
--- a/contrib/libaislock/libaislock.c
+++ /dev/null
@@ -1,466 +0,0 @@
-#include <pthread.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-
-#include <linux/types.h>
-#include <linux/dlm.h>
-#define BUILDING_LIBDLM
-#include "libdlm.h"
-#include "libaislock.h"
-#include <linux/dlm_device.h>
-
-enum {
- SA_LCK_GRANT_CB = 1,
- SA_LCK_WAITER_CB = 2,
-};
-
-static struct dlm_ls_info *sa_default_ls = NULL;
-
-static inline int lkmode_ais2dlm(SaLckLockModeT mode)
-{
- switch(mode)
- {
- case SA_LCK_PR_LOCK_MODE:
- return DLM_LOCK_PR;
- case SA_LCK_EX_LOCK_MODE:
- return DLM_LOCK_EX;
- default:
- return -1;
- }
-}
-
-static inline SaLckLockModeT lkmode_dlm2ais(int mode)
-{
- switch(mode)
- {
- case DLM_LOCK_PR:
- return SA_LCK_PR_LOCK_MODE;
- case DLM_LOCK_EX:
- return SA_LCK_EX_LOCK_MODE;
- default:
- return -1;
- }
-}
-
-static inline unsigned long lkflag_ais2dlm(SaLckLockFlagsT flag)
-{
- unsigned long dlm_flag = 0;
-
- if(flag & SA_LCK_LOCK_NO_QUEUE)
- dlm_flag |= DLM_LKF_NOQUEUE;
- if(flag & SA_LCK_LOCK_ORPHAN)
- dlm_flag |= DLM_LKF_ORPHAN;
-
- return dlm_flag;
-}
-
-static inline SaLckLockStatusT lkstatus_dlm2ais(int status)
-{
- switch(status)
- {
- case -ENOMEM:
- return SA_LCK_LOCK_NO_MORE;
- case 0:
- return SA_LCK_LOCK_GRANTED;
- case -EAGAIN:
- return SA_LCK_LOCK_NOT_QUEUED;
- default:
- return -1;
- }
-}
-
-static inline SaErrorT lkerr_dlm2ais(int status)
-{
- switch(status)
- {
- case -EINVAL:
- return SA_ERR_INVALID_PARAM;
- case 0:
- return SA_OK;
- default:
- return -1;
- }
-}
-
-
-SaErrorT
-saLckInitialize(SaLckHandleT *lckHandle, const SaLckCallbacksT *lckCallbacks,
- const SaVersionT *version)
-{
- dlm_lshandle_t ls = NULL;
-
- if (NULL == lckHandle)
- return SA_ERR_INVALID_PARAM;
-
- if (lckCallbacks) {
- lckHandle->callback.saLckLockGrantCallback =
- lckCallbacks->saLckLockGrantCallback;
- lckHandle->callback.saLckLockWaiterCallback =
- lckCallbacks->saLckLockWaiterCallback;
- lckHandle->callback.saLckResourceUnlockCallback =
- lckCallbacks->saLckResourceUnlockCallback;
- } else {
- lckHandle->callback.saLckLockGrantCallback = NULL;
- lckHandle->callback.saLckLockWaiterCallback = NULL;
- lckHandle->callback.saLckResourceUnlockCallback = NULL;
- }
- lckHandle->version.releaseCode = version->releaseCode;
- lckHandle->version.major = version->major;
- lckHandle->version.minor = version->minor;
-
- ls = dlm_create_lockspace("sa_default", 0600);
- if (!ls)
- return SA_ERR_LIBRARY;
-
- sa_default_ls = (struct dlm_ls_info *)ls;
- return SA_OK;
-}
-
-
-SaErrorT
-saLckFinalize(SaLckHandleT *lckHandle)
-{
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- if(!dlm_release_lockspace("sa_default", sa_default_ls, 1)) {
- return SA_OK;
- } else {
- return SA_ERR_LIBRARY;
- }
-}
-
-SaErrorT
-saLckResourceOpen(const SaLckHandleT *lckHandle, const SaNameT *lockName,
- SaLckResourceIdT *resourceId)
-{
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- if (lockName->length <= 31 ) /* OpenDLM only support namelen <= 31*/
- {
- resourceId->name.length = lockName->length;
- strncpy((char *)resourceId->name.value, (char *)lockName->value, lockName->length);
- } else {
- return SA_ERR_NO_MEMORY;
- }
-
- return SA_OK;
-}
-
-
-SaErrorT
-saLckResourceClose(SaLckHandleT *lckHandle, SaLckResourceIdT *resourceId)
-{
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- return SA_OK;
-}
-
-
-SaErrorT
-saLckSelectionObjectGet(const SaLckHandleT *lckHandle,
- SaSelectionObjectT *selectionObject)
-{
- int fd = -1;
-
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- fd = dlm_ls_get_fd(sa_default_ls);
-
- if(!fd)
- return SA_ERR_LIBRARY;
-
- *selectionObject = fd;
-
- return SA_OK;
-}
-
-
-SaErrorT
-saLckDispatch(const SaLckHandleT *lckHandle,
- const SaDispatchFlagsT dispatchFlags)
-{
- int status;
- int fdflags;
- char resultbuf[sizeof(struct dlm_lock_result)];
- struct dlm_lock_result *result = (struct dlm_lock_result *)resultbuf;
- char *fullresult=NULL;
- SaLckLockIdT *lkid;
- SaLckLockModeT lock_mode;
- int fd = -1;
-
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- fd = dlm_ls_get_fd(sa_default_ls);
-
- if(!fd)
- return SA_ERR_LIBRARY;
-
- fdflags = fcntl(fd, F_GETFL, 0);
- fcntl(fd, F_SETFL, fdflags | O_NONBLOCK);
-
- do
- {
-
- /* Just read the header first */
- status = read(fd, result, sizeof(struct dlm_lock_result));
- if (status <= 0)
- break;
-
- if (result->length != status)
- {
- int newstat;
-
- fullresult = malloc(result->length);
- if (!fullresult)
- break;
-
- newstat = read(fd, fullresult, result->length);
-
- /* If it read OK then use the new data. otherwise we can
- still deliver the AST, it just might not have all the
- info in it...hmmm */
- if (newstat == result->length)
- result = (struct dlm_lock_result *)fullresult;
- }
-
- /* Copy lksb to user's buffer - except the LVB ptr */
- memcpy(result->user_lksb, &result->lksb,
- sizeof(struct dlm_lksb) - sizeof(char*));
-
- /* Flip the status. Kernel space likes negative return codes,
- userspace positive ones */
- result->user_lksb->sb_status = -result->user_lksb->sb_status;
-
- /* Need not to care LVB*/
-#ifdef QUERY
- /* Copy optional items */
- if (result->qinfo_offset)
- {
- /* Just need the lockcount written out here */
- struct dlm_queryinfo *qi = (struct dlm_queryinfo *)
- (fullresult+result->qinfo_offset);
- result->user_qinfo->gqi_lockcount = qi->gqi_lockcount;
- }
-
- if (result->qresinfo_offset)
- memcpy(result->user_qinfo->gqi_resinfo,
- fullresult+result->qresinfo_offset,
- sizeof(struct dlm_resinfo));
-
- if (result->qlockinfo_offset)
- memcpy(result->user_qinfo->gqi_lockinfo,
- fullresult+result->qlockinfo_offset,
- sizeof(struct dlm_lockinfo) *
- result->user_qinfo->gqi_lockcount);
-#endif
- /* Call AST */
- lkid = (SaLckLockIdT *)result->user_astparam;
- if (lkid->unlock) {
- /* dispatch unlock ast */
- lkid->unlock = 0;
- lkid->held_mode = 0;
- if(lckHandle->callback.saLckResourceUnlockCallback)
- lckHandle->callback.
- saLckResourceUnlockCallback(
- lkid->args, lkid->resource, lkid,
- SA_LCK_LOCK_RELEASED, SA_OK);
-
- } else if (SA_LCK_GRANT_CB == (int)result->user_astaddr) {
- /* dispatch lock ast */
- if (0 == lkid->lksb.sb_status) {
- lkid->held_mode = lkid->requested_mode;
- lock_mode = lkid->requested_mode;
- } else {
- lock_mode = lkid->held_mode;
- }
-
- if(lckHandle->callback.saLckLockGrantCallback)
- lckHandle->callback.
- saLckLockGrantCallback(
- lkid->args, lkid->resource,
- lkid, lock_mode,
- lkstatus_dlm2ais(
- lkid->lksb.sb_status),
- SA_OK);
- } else if (SA_LCK_WAITER_CB == (int)result->user_astaddr) {
- /* dispatch waiter ast */
- if(lckHandle->callback.saLckLockWaiterCallback)
- lckHandle->callback.
- saLckLockWaiterCallback(
- lkid->args, lkid->resource,
- lkid, lkid->held_mode, result->bast_mode);
- } else {
- return SA_ERR_LIBRARY;
- }
- } while (0 !=status && SA_DISPATCH_ONE != dispatchFlags);
-
- /* EAGAIN is not an error */
- if (status < 0 && errno == EAGAIN)
- status = 0;
-
- fcntl(fd, F_SETFL, fdflags);
- return SA_OK;
-}
-
-SaErrorT
-SaLckResourceLockAsync(const SaLckHandleT *lckHandle, SaInvocationT invocation,
- const SaLckResourceIdT *resourceId, SaLckLockIdT *lockId,
- SaLckLockModeT lockMode, SaLckLockFlagsT lockFlags,
- SaTimeT timeout)
-{
- int ret_val; /* value to be returned from function */
-
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- /*FIXME deal with timeout in lock/lockasync/unlock.
- */
- lockId->resource = (SaLckResourceIdT *)resourceId;
- lockId->requested_mode = lockMode;
- lockId->args = invocation;
-
- ret_val = dlm_ls_lock(sa_default_ls, lkmode_ais2dlm(lockMode),
- &(lockId->lksb), lkflag_ais2dlm(lockFlags),
- (void *)(resourceId->name.value),
- resourceId->name.length, 0, (void *)SA_LCK_GRANT_CB,
- lockId, (void *)SA_LCK_WAITER_CB, NULL);
-
- return lkerr_dlm2ais(ret_val);
-}
-
-SaErrorT
-saLckResourceLock(const SaLckHandleT *lckHandle, SaInvocationT invocation,
- const SaLckResourceIdT *resourceId, SaLckLockIdT *lockId,
- SaLckLockModeT lockMode, SaLckLockFlagsT lockFlags,
- SaTimeT timeout, SaLckLockStatusT *lockStatus)
-
-{
- int ret_val; /* value to be returned from function */
-
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- lockId->resource = (SaLckResourceIdT *)resourceId;
- lockId->requested_mode = lockMode;
- lockId->args = invocation;
-
- ret_val = dlm_ls_lock_wait(sa_default_ls, lkmode_ais2dlm(lockMode),
- &(lockId->lksb), lkflag_ais2dlm(lockFlags),
- (void *)(resourceId->name.value),
- resourceId->name.length, 0, lockId,
- (void *)SA_LCK_WAITER_CB, NULL);
-
- *lockStatus = lkstatus_dlm2ais(lockId->lksb.sb_status);
- lockId->held_mode = lockId->requested_mode;
-
- return lkerr_dlm2ais(ret_val);
-}
-
-SaErrorT
-saLckResourceUnlock(const SaLckHandleT *lckHandle, SaLckLockIdT *lockId,
- SaTimeT timeout)
-{
- int ret_val; /* value to be returned from function */
-
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- ret_val = dlm_ls_unlock_wait(sa_default_ls, lockId->lksb.sb_lkid, 0,
- &(lockId->lksb));
- lockId->held_mode = 0;
-
- return lkerr_dlm2ais(ret_val);
-}
-
-SaErrorT
-saLckResourceUnlockAsync(const SaLckHandleT *lckHandle,
- SaInvocationT invocation, SaLckLockIdT *lockId)
-{
- int ret_val; /* value to be returned from function */
-
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- lockId->unlock = 1;
- lockId->args = invocation;
-
-
- ret_val = dlm_ls_unlock(sa_default_ls, lockId->lksb.sb_lkid, 0, &(lockId->lksb),
- lockId);
-
- return lkerr_dlm2ais(ret_val);
-}
-
-
-SaErrorT
-saLckLockPurge(const SaLckHandleT *lckHandle,
- const SaLckResourceIdT *resourceId)
-{
-#ifdef QUERY
- int ret_val; /* value to be returned from function */
- SaLckLockIdT lockId;
- struct dlm_lksb lksb;
- struct dlm_resinfo resinfo;
- static struct dlm_queryinfo qinfo;
- struct dlm_lockinfo *p;
-
- qinfo.gqi_resinfo = &resinfo;
- qinfo.gqi_lockinfo = malloc(sizeof(struct dlm_lockinfo) * 10);
- qinfo.gqi_locksize = 10;
-
-
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- lockId.resource = (SaLckResourceIdT *)resourceId;
- lockId.requested_mode = DLM_LOCK_NL;
-
- ret_val = dlm_ls_lock_wait(sa_default_ls, DLM_LOCK_NL,
- &(lockId.lksb), DLM_LKF_EXPEDITE,
- (void *)(resourceId->name.value),
- resourceId->name.length, 0, &lockId,
- (void *)SA_LCK_WAITER_CB, NULL);
-
- dlm_ls_query_wait(sa_default_ls, &(lockId.lksb),
- DLM_QUERY_QUEUE_ALL|DLM_QUERY_LOCKS_ORPHAN, &qinfo);
-
- for ( p = qinfo.gqi_lockinfo; 0 != p->lki_lkid; p++ ) {
- lksb.sb_lkid = p->lki_lkid;
- ret_val = dlm_ls_unlock_wait(sa_default_ls, p->lki_lkid, 0,
- &lksb);
- }
-
- ret_val = dlm_ls_unlock_wait(sa_default_ls, lockId.lksb.sb_lkid, 0,
- &(lockId.lksb));
-
- return lkerr_dlm2ais(ret_val);
-#else
- return -1;
-#endif
-}
-
diff --git a/contrib/libaislock/libaislock.h b/contrib/libaislock/libaislock.h
deleted file mode 100644
index 3faeffd..0000000
--- a/contrib/libaislock/libaislock.h
+++ /dev/null
@@ -1,190 +0,0 @@
-typedef char SaInt8T;
-typedef short SaInt16T;
-typedef long SaInt32T;
-typedef long long SaInt64T;
-typedef unsigned char SaUint8T;
-typedef unsigned short SaUint16T;
-typedef unsigned long SaUint32T;
-typedef unsigned long long SaUint64T;
-typedef SaInt64T SaTimeT;
-
-#define SA_MAX_NAME_LENGTH 256
-
-typedef struct {
- SaUint16T length;
- unsigned char value[SA_MAX_NAME_LENGTH];
-} SaNameT;
-
-typedef struct {
- char releaseCode;
- unsigned char major;
- unsigned char minor;
-} SaVersionT;
-
-typedef int SaSelectionObjectT;
-
-typedef void *SaInvocationT;
-
-typedef enum {
- SA_DISPATCH_ONE = 1,
- SA_DISPATCH_ALL = 2,
- SA_DISPATCH_BLOCKING = 3
-} SaDispatchFlagsT;
-
-typedef enum {
- SA_OK = 1,
- SA_ERR_LIBRARY = 2,
- SA_ERR_VERSION = 3,
- SA_ERR_INIT = 4,
- SA_ERR_TIMEOUT = 5,
- SA_ERR_TRY_AGAIN = 6,
- SA_ERR_INVALID_PARAM = 7,
- SA_ERR_NO_MEMORY = 8,
- SA_ERR_BAD_HANDLE = 9,
- SA_ERR_BUSY = 10,
- SA_ERR_ACCESS = 11,
- SA_ERR_NOT_EXIST = 12,
- SA_ERR_NAME_TOO_LONG = 13,
- SA_ERR_EXIST = 14,
- SA_ERR_NO_SPACE = 15,
- SA_ERR_INTERRUPT =16,
- SA_ERR_SYSTEM = 17,
- SA_ERR_NAME_NOT_FOUND = 18,
- SA_ERR_NO_RESOURCES = 19,
- SA_ERR_NOT_SUPPORTED = 20,
- SA_ERR_BAD_OPERATION = 21,
- SA_ERR_FAILED_OPERATION = 22,
- SA_ERR_MESSAGE_ERROR = 23,
- SA_ERR_NO_MESSAGE = 24,
- SA_ERR_QUEUE_FULL = 25,
- SA_ERR_QUEUE_NOT_AVAILABLE = 26,
- SA_ERR_BAD_CHECKPOINT = 27,
- SA_ERR_BAD_FLAGS = 28
-} SaErrorT;
-
-/* Chapter 10 */
-typedef enum {
- SA_LCK_PR_LOCK_MODE = 1,
- SA_LCK_EX_LOCK_MODE = 2
-} SaLckLockModeT;
-
-typedef struct{
- int site;
- int pid;
-} SaLckLockHolderT;
-
-typedef struct {
- SaLckLockHolderT orphan_holder;
- SaNameT name;
-} SaLckResourceIdT;
-
-typedef struct {
- struct dlm_lksb lksb;
- SaLckResourceIdT *resource;
- SaLckLockModeT held_mode;
- SaLckLockModeT requested_mode;
- int unlock;
- SaInvocationT args;
-} SaLckLockIdT;
-
-#define SA_LCK_LOCK_NO_QUEUE 0x1
-#define SA_LCK_LOCK_ORPHAN 0x2
-#define SA_LCK_LOCK_TIMEOUT 0X4
-typedef SaUint32T SaLckLockFlagsT;
-
-typedef enum {
- SA_LCK_LOCK_GRANTED = 1,
- SA_LCK_LOCK_RELEASED = 2,
- SA_LCK_LOCK_DEADLOCK = 3,
- SA_LCK_LOCK_NOT_QUEUED = 4,
- SA_LCK_LOCK_TIMED_OUT = 5,
- SA_LCK_LOCK_ORPHANED = 6,
- SA_LCK_LOCK_NO_MORE = 7
-} SaLckLockStatusT;
-
-typedef void
-(*SaLckLockGrantCallbackT)(SaInvocationT invocation,
- const SaLckResourceIdT *resourceId,
- const SaLckLockIdT *lockId,
- SaLckLockModeT lockMode,
- SaLckLockStatusT lockStatus,
- SaErrorT error);
-
-typedef void
-(*SaLckLockWaiterCallbackT)(SaInvocationT invocation,
- const SaLckResourceIdT *resourceId,
- const SaLckLockIdT *lockId,
- SaLckLockModeT modeHeld,
- SaLckLockModeT modeRequested);
-
-typedef void
-(*SaLckResourceUnlockCallbackT)(SaInvocationT invocation,
- const SaLckResourceIdT *resourceId,
- const SaLckLockIdT *lockId,
- SaLckLockStatusT lockStatus,
- SaErrorT error);
-typedef struct SaLckCallbacks {
- SaLckLockGrantCallbackT saLckLockGrantCallback;
- SaLckLockWaiterCallbackT saLckLockWaiterCallback;
- SaLckResourceUnlockCallbackT saLckResourceUnlockCallback;
-}SaLckCallbacksT;
-
-typedef struct {
- SaLckCallbacksT callback;
- SaVersionT version;
-} SaLckHandleT;
-
- SaErrorT
-saLckInitialize(SaLckHandleT *lckHandle, const SaLckCallbacksT *lckCallbacks,
- const SaVersionT *version);
-
- SaErrorT
-saLckSelectionObjectGet(const SaLckHandleT *lckHandle,
- SaSelectionObjectT *selectionObject);
-
- SaErrorT
-saLckDispatch(const SaLckHandleT *lckHandle,
- const SaDispatchFlagsT dispatchFlags);
-
- SaErrorT
-saLckFinalize(SaLckHandleT *lckHandle);
-
- SaErrorT
-saLckResourceOpen(const SaLckHandleT *lckHandle,
- const SaNameT *lockName,
- SaLckResourceIdT *resourceId);
-
- SaErrorT
-saLckResourceClose(SaLckHandleT *lckHandle, SaLckResourceIdT *resourceId);
-
- SaErrorT
-saLckResourceLock(const SaLckHandleT *lckHandle, SaInvocationT invocation,
- const SaLckResourceIdT *resourceId,
- SaLckLockIdT *lockId,
- SaLckLockModeT lockMode,
- SaLckLockFlagsT lockFlags,
- SaTimeT timeout,
- SaLckLockStatusT *lockStatus);
-
- SaErrorT
-SaLckResourceLockAsync(const SaLckHandleT *lckHandle,
- SaInvocationT invocation,
- const SaLckResourceIdT *resourceId,
- SaLckLockIdT *lockId,
- SaLckLockModeT lockMode,
- SaLckLockFlagsT lockFlags,
- SaTimeT timeout);
-
- SaErrorT
-saLckResourceUnlock(const SaLckHandleT *lckHandle,
- SaLckLockIdT *lockId,
- SaTimeT timeout);
-
- SaErrorT
-saLckResourceUnlockAsync(const SaLckHandleT *lckHandle,
- SaInvocationT invocation,
- SaLckLockIdT *lockId);
-
- SaErrorT
-saLckLockPurge(const SaLckHandleT *lckHandle,
- const SaLckResourceIdT *resourceId);
diff --git a/contrib/libaislock/libaislock.pc.in b/contrib/libaislock/libaislock.pc.in
deleted file mode 100644
index a4804a9..0000000
--- a/contrib/libaislock/libaislock.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: libaislock
-Version: @VERSION@
-Description: libaislock
-Requires:
-Libs: -L${libdir} -laislock
-Cflags: -I${includedir}
diff --git a/dlm/Makefile b/dlm/Makefile
deleted file mode 100644
index 7c8cc33..0000000
--- a/dlm/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS=libdlm libdlmcontrol tool man
diff --git a/dlm/doc/dlm_tool.txt b/dlm/doc/dlm_tool.txt
deleted file mode 100644
index d66cdb0..0000000
--- a/dlm/doc/dlm_tool.txt
+++ /dev/null
@@ -1,167 +0,0 @@
-
-The dlm is configured and controlled from user space through sysfs and a
-couple of ioctl's. A command line program, dlm_tool, can be used to do
-everything manually.
-
-Here are the dlm_tool config/control actions that will be used:
-
-set_local <nodeid> <ipaddr> [<weight>]
-set_node <nodeid> <ipaddr> [<weight>]
-stop <ls_name>
-terminate <ls_name>
-start <ls_name> <event_nr> <type> <nodeid>...
-get_done <ls_name>
-finish <ls_name> <event_nr>
-set_id <ls_name> <id>
-
-For testing and illustration, some actions have been added to dlm_tool to use
-the libdlm API.
-
-create <ls_name>
-release <ls_name>
-lock <ls_name> <res_name> <mode> [<flag>,...]
-unlock <ls_name> <lkid> [<flag>,...]
-convert <ls_name> <lkid> <mode> [<flag>,...]
-
-So, dlm_tool is standing in for what would usually be two different entities.
-The first set of config/control actions would usually be performed by a system
-daemon associated with a cluster membership manager. The second set of libdlm
-actions would usually be performed by an application that wants to use the dlm
-for synchronization.
-
-
-Example
-
-1. There are three machines that we want to use the dlm:
-
-nodea -- 10.0.0.1
-nodeb -- 10.0.0.2
-nodec -- 10.0.0.3
-
-
-2. We'll pick arbitrary integer node ID's for these machines:
-
-nodea -- 1
-nodeb -- 2
-nodec -- 3
-
-
-3. On each node we first need to tell the dlm what the local IP address
-and nodeid are:
-
-nodea> dlm_tool set_local 1 10.0.0.1
-nodeb> dlm_tool set_local 2 10.0.0.2
-nodec> dlm_tool set_local 3 10.0.0.3
-
-
-4. On all nodes we need to set up the nodeid to IP address mappings:
-
-all> dlm_tool set_node 1 10.0.0.1
-all> dlm_tool set_node 2 10.0.0.2
-all> dlm_tool set_node 3 10.0.0.3
-
-
-5. All dlm locking happens within a lockspace; we need to create a test
-lockspace for all the nodes to use. This step would usually be an application
-that wants to use the dlm and creates a lockspace to use.
-
-all> dlm_tool create test
-
-
-6. The lockspace needs to be "started" on all the nodes. The <event_nr>
-should begin at 1 and be incremented for each consecutive start that's done on
-the dlm. The <type> field isn't used by the dlm and can be 0. Finally, a
-list of nodeid's using the lockspace is given.
-
-all> dlm_tool start test 1 0 1 2 3
-
-
-7. The dlm will now start up on all three nodes. Whenever it starts it needs
-to do recovery. Once recovery is done, the event_nr used for the start (1
-above) will be shown as the dlm_tool get_done output. You need to wait for
-this on all nodes (i.e. for all nodes to complete recovery) before moving on
-to the next step.
-
-all> dlm_tool get_done test
-done event_nr 1
-
-
-8. The lockspace finally needs to know that recovery is finished on all nodes.
-The event_nr used for the start is used here.
-
-all> dlm_tool finish test 1
-
-
-9. The lockspace can now be used by the application for locking, or using
-dlm_tool using the libdlm actions above.
-
-all> dlm_tool lock/unlock/convert ...
-
-
-10. Say that nodea fails. Nodeb and nodec need to remove nodea from the
-lockspace and do recovery. The first step is to suspend the dlm operation on
-the remaining nodes:
-
-nodeb,nodec> dlm_tool stop test
-
-
-11. The lockspace then needs to be started again with the new set of lockspace
-members and an incremented event_nr.
-
-nodeb,nodec> dlm_tool start test 2 0 2 3
-
-
-12. We wait for recovery to complete on nodeb and nodec.
-
-nodeb,nodec> dlm_tool get_done test
-done event_nr 2
-
-
-13. Tell the lockspace that recovery is finished on both nodes.
-
-nodeb,nodec> dlm_tool finish test 2
-
-
-14. Nodea comes back and wants to use the dlm again.
-
-nodea> dlm_tool create test
-
-
-15. To add nodea back into the lockspace, first suspend lockspace operations
-on nodeb and nodec.
-
-nodeb,nodec> dlm_tool stop test
-
-
-16. Start the lockspace on all the nodes with an incremented event_nr
-(event_nr can go back to 1 again for nodea).
-
-nodeb,nodec> dlm_tool start test 3 0 1 2 3
-nodea> dlm_tool start test 1 0 1 2 3
-
-
-17. Wait for all nodes to complete recovery.
-
-nodeb,nodec> dlm_tool get_done test
-done event_nr 3
-
-nodea> dlm_tool get_done test
-done event_nr 1
-
-
-18. Tell the lockspace that recovery is finished everywhere.
-
-nodeb,nodec> dlm_tool finish test 3
-nodea> dlm_tool finish test 1
-
-
-
-Notes:
-
-- When you use more than one lockspace on the nodes, you need to use
- dlm_tool set_id on all nodes to assign each lockspace a unique
- integer id. This is done between the create and the first start.
-
-- A node can leave a lockspace using dlm_tool release (the opposite of
- dlm_tool create).
-
diff --git a/dlm/doc/example.c b/dlm/doc/example.c
deleted file mode 100644
index 9f3ea11..0000000
--- a/dlm/doc/example.c
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <signal.h>
-#include <libdlm.h>
-
-/*
- * Simple libdlm locking demo
- *
- * Daniel Phillips, phillips(a)redhat.com
- *
- */
-
-#define error(string, args...) do { printf(string, ##args); exit(1); } while (0)
-
-void my_ast(void *arg)
-{
- printf("ast got arg %p\n", arg);
-}
-
-int main(void)
-{
- int fd, child;
- struct dlm_lksb lksb;
-
- if ((fd = dlm_get_fd()) < 0)
- error("dlm error %i, %s\n", errno, strerror(errno));
-
- switch (child = fork()) {
- case -1:
- error("fork error %i, %s\n", errno, strerror(errno));
- case 0:
- while (1)
- dlm_dispatch(fd);
- }
-
- if (dlm_lock(LKM_PWMODE, &lksb, LKF_NOQUEUE, "foo", 3,
- 0, my_ast, (void *)&fd, NULL, NULL) < 0)
- error("dlm error %i, %s\n", errno, strerror(errno));
- sleep(1);
-
- if (dlm_unlock(lksb.sb_lkid, 0, &lksb, NULL) < 0)
- error("dlm error %i, %s\n", errno, strerror(errno));
- sleep(1);
-
- kill(child, SIGTERM);
- return 0;
-}
-
diff --git a/dlm/doc/libdlm.txt b/dlm/doc/libdlm.txt
deleted file mode 100644
index 18d44f9..0000000
--- a/dlm/doc/libdlm.txt
+++ /dev/null
@@ -1,533 +0,0 @@
-User-space interface to DLM
----------------------------
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdint.h>
-#include <libdlm.h>
-
-cc -D_REENTRANT prog.c -ldlm -lpthread
-
-cc prog.c -ldlm_lt
-
-
-There are basically two interfaces to libdlm. The first is the "dead simple"
-one that has limited functionality and assumes that the application is linked
-with pthreads. The second is the full-featured DLM interface that looks
-identical to the kernel interface.
-
-See CVS dlm/tests/usertest for examples of use of both these APIs.
-
-The simple one
---------------
-This provides two API calls, lock_resource() and unlock_resource(). Both of
-these calls block until the lock operation has completed - using a worker
-thread to deal with the callbacks that come from the kernel.
-
-int lock_resource(const char *resource, int mode, int flags, int *lockid);
-
- This function locks a named (NUL-terminated) resource and returns the
- lockid if successful. The mode may be any of
-
- LKM_NLMODE LKM_CRMODE LKM_CWMODE LKM_PRMODE LKM_PWMODE LKM_EXMODE
-
- Flags may be any combination of
-
- LKF_NOQUEUE - Don't wait if the lock cannot be granted immediately,
- will return EAGAIN if this is so.
-
- LKF_CONVERT - Convert lock to new mode. *lockid must be valid,
- resource name is ignored.
-
- LKF_QUECVT - Add conversion to the back of the convert queue - only
- valid for some convert operations
-
- LKF_PERSISTENT - Don't automatically unlock this lock when the process
- exits (must be root).
-
-
-int unlock_resource(int lockid);
-
- Unlocks the resource.
-
-
-
-The complicated one
--------------------
-This interface is identical to the kernel interface with the exception of
-the lockspace argument. All userland locks sit in the same lockspace by default.
-
-libdlm can be used in pthread or non-pthread applications. For pthread
-applications simply call the following function before doing any lock
-operations. If you're using pthreads, remember to define _REENTRANT at the
-top of the program or using -D_REENTRANT on the compile line.
-
-int dlm_pthread_init()
-
- Creates a thread to receive all lock ASTs. The AST callback function
- for lock operations will be called in the context of this thread.
- If there is a potential for local resource access conflicts you must
- provide your own pthread-based locking in the AST routine.
-
-
-int dlm_pthread_cleanup()
-
- Cleans up the default lockspace threads after use. Normally you
- don't need to call this, but if the locking code is in a
- dynamically loadable shared library this will probably be necessary.
-
-
-For non-pthread based applications the DLM provides a file descriptor
-that the program can feed into poll/select. If activity is detected
-on that FD then a dispatch function should be called:
-
-int dlm_get_fd()
-
- Returns a file-descriptor for the DLM suitable for passing in to
- poll() or select().
-
-int dlm_dispatch(int fd)
-
- Reads from the DLM and calls any AST routines that may be needed.
- This routine runs in the context of the caller so no extra locking
- is needed to protect local resources.
-
-
-int dlm_lock(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- struct dlm_range *range);
-
-
-mode lock mode:
- LKM_NLMODE NULL Lock
- LKM_CRMODE Concurrent read
- LKM_CWMODE Concurrent write
- LKM_PRMODE Protected read
- LKM_PWMODE Protected write
- LKM_EXMODE Exclusive
-
-flags LKF_NOQUEUE Don't queue the lock. If it cannot be
- granted return -EAGAIN
- LKF_CONVERT Convert an existing lock
- LKF_VALBLK Lock has a value block
- LKF_QUECVT Put conversion to the back of the queue
- LKF_EXPEDITE Grant a NL lock immediately regardless of
- other locks on the conversion queue
- LKF_PERSISTENT Specifies a lock that will
- not be unlocked when the process exits.
-
-lksb Lock status block.
- This structure contains the returned lock ID, the actual
- status of the lock operation (all lock ops are asynchronous)
- and the value block if LKF_VALBLK is set.
-
-name Name of the lock. Can be binary, max 64 bytes. Ignored for lock
- conversions.
-
-namelen Length of the above name. Ignored for lock conversions.
-
-parent ID of parent lock or NULL if this is a top-level lock
-
-ast Address of AST routine to be called when the lock operation
- completes. The final completion status of the lock will be
- in the lksb. the AST routine must not be NULL.
-
-astargs Argument to pass to the AST routine (most people pass the lksb
- in here but it can be anything you like.)
-
-bast Blocking AST routine. address of a function to call if this
- lock is blocking another. The function will be called with
- astargs.
-
-range an optional structure of two uint64_t that indicate the range
- of the lock. Locks with overlapping ranges will be granted only
- if the lock modes are compatible. locks with non-overlapping
- ranges (on the same resource) do not conflict. A lock with no
- range is assumed to have a range emcompassing the largest
- possible range. ie. 0-0xFFFFFFFFFFFFFFFF. Note that is is more
- efficient to specify no range than to specify the full range
- above.
-
-
-dlm_lock operations are asynchronous. If the call to dlm_lock returns an error
-then the operation has failed and the AST routine will not be called. If
-dlm_lock returns 0 it is still possible that the lock operation will fail. The
-AST routine will be called when the locking is complete or has failed and the
-status is returned in the lksb.
-
-For conversion operations the name and namelen are ignored and the lock ID in
-the LKSB is used to identify the lock.
-
-If a lock value block is specified then in general, a grant or a conversion to
-an equal-level or higher-level lock mode reads the lock value from the resource
-into the caller's lock value block. When a lock conversion from EX or PW
-to an equal-level or lower-level lock mode occurs, the contents of
-the caller's lock value block are written into the resource.
-
-If the AST routines or parameter are passed to a conversion operation then they
-will overwrite those values that were passed to a previous dlm_lock call.
-
-int dlm_lock_wait(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void *bastarg,
- void (*bastaddr) (void *bastarg),
- struct dlm_range *range);
-
-
-As above except that the call will block until the lock is
-granted or has failed. The return from the function is
-the final status of the lock request (ie that was returned
-in the lksb after the AST routine was called).
-
-
-
-int dlm_unlock(uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb,
- void *astarg)
-
-lkid Lock ID as returned in the lksb
-
-flags flags affecting the unlock operation:
- LKF_CANCEL CANCEL a pending lock or conversion.
- This returns the lock to it's
- previously granted mode (in case of a
- conversion) or unlocks it (in case of a
- waiting lock).
-
- LKF_IVVALBLK Invalidate value block
-
-lksb LKSB to return status and value block information.
-
-astarg New parameter to be passed to the completion AST.
- The completion AST routine is the
- last completion AST routine specified in a dlm_lock call.
- If dlm_lock_wait() was the last routine to issue a lock,
- dlm_unlock_wait() must be used to release the lock. If dlm_lock()
- was the last routine to issue a lock then either dlm_unlock()
- or dlm_unlock_wait() may be called.
-
-Unlocks are also asynchronous. The AST routine is called when the resource is
-successfully unlocked (see below).
-
-
-Extra status returns to the completion AST (apart from those already
-defined in errno.h)
-
-ECANCEL
- A lock conversion was successfully cancelled
-
-EUNLOCK
- An Unlock operation completed successfully
-
-EDEADLOCK
- The lock operation is causing a deadlock and has been cancelled. If this
- was a conversion then the lock is reverted to its previously granted state.
- If it was a new lock then it has not been granted.
- (NB Only conversion deadlocks are currently detected)
-
-int dlm_unlock_wait(uint32_t lkid,
- uint32 flags,
- struct dlm_lksb *lksb)
-
-As above but returns when the unlock operation is complete either because it
-finished or because an error was detected. In the case where
-the unlock operation was succesful no error is returned.
-
-The return value of the function call is the status of issuing
-the unlock operation. The status of the unlock operation itself
-is in the lock status block. Both of these must be checked to
-verify that the unlock has completed succesfully.
-
-Lock Query Operations
----------------------
-int dlm_query(struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo,
- void (*ast_routine(void *astarg)),
- void *astarg);
-
-The operation is asynchronous, the ultimate status and data will be returned into the
-dlm_query_info structure which should be checked when the ast_routine is
-called. The lksb must contain a valid lock ID in sb_lkid which is used to
-identify the resource to be queried, status will be returned in sb_status;
-As with the locking calls an AST woutine will be called when the query completes
-if the call itself returns 0.
-
-int dlm_query_wait(struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo)
-
-Same as dlm_query() except that it waits for the operation to complete.
-When the operation is complete the status of will be in the lksb. Both
-the return value from the function call and the condition code in the
-lksb must be evaluated.
-
-If the provided lock list is too short to hold all the locks, then sb_status
-in the lksb will contain -E2BIG but the list will be filled in as far as possible.
-Either gqi_lockinfo or gqi_resinfo may be NULL if that information is not required.
-
-/* Structures passed into and out of the query */
-
-struct gdlm_lockinfo
-{
- int lki_lkid; /* Lock ID on originating node */
- int lki_parent;
- int lki_node; /* Originating node (not master) */
- int lki_ownpid; /* Owner pid on the originating node */
- uint8 lki_state; /* Queue the lock is on */
- int8 lki_grmode /* Granted mode */
- int8 lki_rqmode; /* Requested mode */
- struct dlm_range lki_grrange /* Granted range, if applicable */
- struct dlm_range lki_rqrange /* Requested range, if applicable */
-};
-
-struct gdlm_resinfo
-{
- int rsi_length;
- int rsi_grantcount; /* No. of nodes on grant queue */
- int rsi_convcount; /* No. of nodes on convert queue */
- int rsi_waitcount; /* No. of nodes on wait queue */
- int rsi_masternode; /* Master for this resource */
- char rsi_name[DLM_RESNAME_MAXLEN]; /* Resource name */
- char rsi_valblk[DLM_LVB_LEN]; /* Master's LVB contents, if applicable */
-};
-
-struct dlm_queryinfo
-{
- struct dlm_resinfo *gqi_resinfo; /* Points to a single resinfo struct */
- struct dlm_lockinfo *gqi_lockinfo; /* This points to an array of structs */
- int gqi_locksize; /* input */
- int gqi_lockcount; /* output */
-};
-
-The query is made up of several blocks of bits as follows:
-
- 9 8 6 5 3 0
-+----------------+---+-------+---+-------+-----------+
-| reserved | Q | query | F | queue | lock mode |
-+----------------+---+-------+---+-------+-----------+
-
-lock mode is a normal DLM lock mode or DLM_LOCK_THIS
-to use the mode of the lock in sb_lkid.
-
-queue is a bitmap of
- DLM_QUERY_QUEUE_WAIT
- DLM_QUERY_QUEUE_CONVERT
- DLM_QUERY_QUEUE_GRANT
-
-or one of the two shorthands:
- DLM_QUERY_QUEUE_GRANTED (for WAIT+GRANT)
- DLM_QUERY_QUEUE_ALL (for all queues)
-
- F is a flag DLM_QUERY_LOCAL
-which specifies that a remote access should not
-happen. Only lock information that can
-be gleaned from the local node will be returned so
-be aware that it may not be complete.
-
-The query is one of the following:
- DLM_QUERY_LOCKS_HIGHER
- DLM_QUERY_LOCKS_LOWER
- DLM_QUERY_LOCKS_EQUAL
- DLM_QUERY_LOCKS_BLOCKING
- DLM_QUERY_LOCKS_NOTBLOCK
- DLM_QUERY_LOCKS_ALL
-
-which specifies which locks to look for by mode,
-either the lockmode is lower, equal or higher
-to the mode at the bottom of the query.
-DLM_QUERY_ALL will return all locks on the
-resource.
-
-DLM_QUERY_LOCKS_BLOCKING returns only locks
-that are blocking the current lock. The lock
-must not be waiting for grant or conversion
-for this to be a valid query, the other flags
-are ignored.
-
-DLM_QUERY_LOCKS_NOTBLOCKING returns only locks
-that are granted but NOT blocking the current lock.
-
-Q specifies which lock queue to compare. By default
-the granted queue is used. If the flags
-DLM_QUERY_RQMODE is set then the requested mode
-will be used instead.
-
-
-The "normal" way to call dlm_query is to put the
-address of the dlm_queryinfo struct into
-lksb.sb_lvbptr and pass the lksb as the AST param,
-that way all the information is available to you
-in the AST routine.
-
-Lockspace Operations
---------------------
-The DLM allows locks to be partitioned into "lockspaces", and these can be
-manipulated by userspace calls. It is possible (though not recommended) for
-an application to have multiple lockspaces open at one time.
-
-All the above calls work on the "default" lockspace, which should be
-fine for most users. The calls below allow you to isolate your
-application from all others running in the cluster. Remember, lockspaces
-are a cluster-wide resource, so if you create a lockspace called "myls" it
-will share locks with a lockspace called "myls" on all nodes.
-
-
-dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode);
-
- This creates a lockspace called <name> and the mode of the file
- user to access it wil be <mode> (subject to umask as usual).
- The lockspace must not already exist on this node, if it does -1
- will be returned and errno will be set to EEXIST. If you really
- want to use this lockspace you can then user dlm_open_lockspace()
- below. The name is the name of a misc device that will be created
- in /dev/misc.
-
- On success a handle to the lockspace is returned, which can be used
- to pass into subsequent dlm_ls_lock/unlock calls. Make no assumptions
- as to the content of this handle as it's content may change in future.
-
- The caller must have CAP_SYSADMIN privileges to do this operation.
-
-
-int dlm_release_lockspace(const char *name, dlm_lshandle_t lockspace, int force)
-
- Deletes a lockspace. If the lockspace still has active locks then -1 will be
- returned and errno set to EBUSY. Both the lockspace handle /and/ the name
- must be specified. This call also closes the lockspace and stops the thread
- associated with the lockspace, if any.
-
- Note that other nodes in the cluster may still have locks open on this
- lockspace.
- This call only removes the lockspace from the current node.
-
- If the force flag is set then the lockspace will be removed even if another
- user on this node has active locks in it. Existing users will NOT
- be notified if you do this, so be careful.
-
-
-dlm_lshandle_t dlm_open_lockspace(const char *name)
-
- Opens an already existing lockspace and returns a handle to it.
-
-
-int dlm_close_lockspace(dlm_lshandle_t lockspace)
-
- Close the lockspace. Any locks held by this process will be freed.
- If a thread is associated with this lockspace then it will be stopped.
-
-
-int dlm_ls_get_fd(dlm_lshandle_t lockspace)
-
- Returns the file descriptor associated with the lockspace so that the
- user call use it as input to poll/select.
-
-
-int dlm_ls_pthread_init(dlm_lshandle_t lockspace)
-
- Initialise threaded environment for this lockspace, similar
- to dlm_pthread_init() above.
-
-
-int dlm_ls_lock(dlm_lshandle_t lockspace,
- int mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*ast) (void *astarg),
- void *astarg,
- void (*bast) (void *astarg),
- struct dlm_range *range)
-
- Same as dlm_lock() above but takes a lockspace argument.
-
-int dlm_ls_lock_wait(dlm_lshandle_t lockspace,
- int mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- void *name,
- unsigned int namelen,
- uint32_t parent,
- void *bastarg,
- void (*bast) (void *bastarg),
- struct dlm_range *range)
-
- Same as dlm_lock_wait() above but takes a lockspace argument.
-
-
-int dlm_ls_unlock(dlm_lshandle_t lockspace,
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb,
- void *astarg)
-
-
- Same as dlm_unlock above but takes a lockspace argument.
-
-int dlm_ls_unlock_wait(dlm_lshandle_t lockspace,
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb)
-
-
- Same as dlm_unlock_wait above but takes a lockspace argument.
-
-
-int dlm_ls_query(dlm_lshandle_t lockspace,
- struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo,
- void (*ast_routine(void *astarg)),
- void *astarg);
-
- Same as dlm_query above but takes a lockspace argument.
-
-int dlm_ls_query_wait(dlm_lshandle_t lockspace,
- struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo)
-
- Same as dlm_query_wait above but takes a lockspace argument.
-
-
-One further point about lockspace operations is that there is no locking
-on the creating/destruction of lockspaces in the library so it is up to the
-application to only call dlm_*_lockspace when it is sure that
-no other locking operations are likely to be happening within that process.
-
-Libraries
----------
-There are two DLM libraries, one that uses pthreads (libdlm) to deliver ASTs
-and a light one one that doesn't (libdlm_lt).
-
-The "light" library contains only the following calls.
-
-- dlm_lock
-- dlm_unlock
-- dlm_query
-- dlm_get_fd
-- dlm_dispatch
-- dlm_ls_lock
-- dlm_ls_unlock
-- dlm_ls_query
-- dlm_ls_get_fd
-- dlm_create_lockspace
-- dlm_open_lockspace
-- dlm_release_lockspace
-- dlm_close_lockspace
-
-Note that libdlm (the pthreads one) also contains the non-threaded calls
-so you can choose at runtime if you need to.
diff --git a/dlm/doc/user-dlm-overview.txt b/dlm/doc/user-dlm-overview.txt
deleted file mode 100644
index bda3aea..0000000
--- a/dlm/doc/user-dlm-overview.txt
+++ /dev/null
@@ -1,325 +0,0 @@
-
-There are five ways to request a dlm lock (and five corresponding ways to
-unlock).
-
-- lock_resource
-- dlm_lock
-- dlm_ls_lock
-- dlm_lock_wait
-- dlm_ls_lock_wait
-
-- unlock_resource
-- dlm_unlock
-- dlm_ls_unlock
-- dlm_unlock_wait
-- dlm_ls_unlock_wait
-
-There is also a set of "administrative" functions that are used along with
-some of the lock/unlock requests. Which are used depends on which locking
-method is used or whether the application is threaded.
-
-- dlm_pthread_init
-- dlm_ls_pthread_init
-- dlm_pthread_cleanup
-- dlm_get_fd
-- dlm_ls_get_fd
-- dlm_dispatch
-- dlm_create_lockspace
-- dlm_open_lockspace
-- dlm_release_lockspace
-- dlm_close_lockspace
-
-
-Overview of lock request methods
---------------------------------
-
-- synchronous, default lockspace
- use dlm_pthread_init/dlm_pthread_cleanup if app is threaded
- use dlm_get_fd/dlm_dispatch if app is not threaded
- use unlock_resource to unlock
-
-int lock_resource(
- const char *resource,
- uint32_t mode,
- uint32_t flags,
- uint32_t *lkid);
-
-
-- asynchronous, default lockspace
- use dlm_pthread_init/dlm_pthread_cleanup if app is threaded
- use dlm_get_fd/dlm_dispatch if app is not threaded
- use dlm_unlock/dlm_unlock_wait to unlock
-
-int dlm_lock(
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*ast) (void *astarg),
- void *astarg,
- void (*bast) (void *astarg),
- struct dlm_range *range);
-
-
-- synchronous, default lockspace
- use dlm_pthread_init/dlm_pthread_cleanup if app is threaded
- use dlm_get_fd/dlm_dispatch if app is not threaded
- use dlm_unlock/dlm_unlock_wait to unlock
-
-int dlm_lock_wait(
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- void *name,
- unsigned int namelen,
- uint32_t parent,
- void *bastarg,
- void (*bast) (void *bastarg),
- struct dlm_range *range);
-
-
-- asynchronous, any lockspace
- use dlm_ls_pthread_init/dlm_pthread_cleanup if app is threaded
- use dlm_ls_get_fd/dlm_dispatch if app is not threaded
- use dlm_create_lockspace/dlm_open_lockspace to start
- use dlm_release_lockspace/dlm_close_lockspace to finish
- use dlm_ls_unlock/dlm_ls_unlock_wait to unlock
-
-int dlm_ls_lock(
- dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*ast) (void *astarg),
- void *astarg,
- void (*bast) (void *astarg),
- struct dlm_range *range);
-
-
-- synchronous, any lockspace
- use dlm_ls_pthread_init/dlm_pthread_cleanup if app is threaded
- use dlm_ls_get_fd/dlm_dispatch if app is not threaded
- use dlm_create_lockspace/dlm_open_lockspace to start
- use dlm_release_lockspace/dlm_close_lockspace to finish
- use dlm_ls_unlock/dlm_ls_unlock_wait to unlock
-
-int dlm_ls_lock_wait(
- dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- void *name,
- unsigned int namelen,
- uint32_t parent,
- void *bastarg,
- void (*bast) (void *bastarg),
- struct dlm_range *range);
-
-
-
-Corresponding unlock requests
------------------------------
-
-int unlock_resource(
- uint32_t lkid);
-
-int dlm_unlock(
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb,
- void *astarg);
-
-int dlm_unlock_wait(
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb);
-
-int dlm_ls_unlock(
- dlm_lshandle_t lockspace,
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb,
- void *astarg);
-
-int dlm_ls_unlock_wait(
- dlm_lshandle_t lockspace,
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb);
-
-
-
-Common to all of the above
---------------------------
-
-#define DLM_RESNAME_MAXLEN (64)
-#define DLM_LVB_LEN (32)
-
-#define LKM_NLMODE 0 /* null lock */
-#define LKM_CRMODE 1 /* concurrent read */
-#define LKM_CWMODE 2 /* concurrent write */
-#define LKM_PRMODE 3 /* protected read */
-#define LKM_PWMODE 4 /* protected write */
-#define LKM_EXMODE 5 /* exclusive */
-
-#define LKF_NOQUEUE (0x00000001)
-#define LKF_CANCEL (0x00000002)
-#define LKF_CONVERT (0x00000004)
-#define LKF_VALBLK (0x00000008)
-#define LKF_QUECVT (0x00000010)
-#define LKF_IVVALBLK (0x00000020)
-#define LKF_CONVDEADLK (0x00000040)
-#define LKF_PERSISTENT (0x00000080)
-#define LKF_NODLCKWT (0x00000100)
-#define LKF_NODLCKBLK (0x00000200)
-#define LKF_EXPEDITE (0x00000400)
-#define LKF_NOQUEUEBAST (0x00000800)
-#define LKF_HEADQUE (0x00001000)
-#define LKF_NOORDER (0x00002000)
-
-#define ECANCEL (0x10001)
-#define EUNLOCK (0x10002)
-#define EINPROG (0x10003)
-
-struct dlm_lksb {
- int sb_status;
- uint32_t sb_lkid;
- char sb_flags;
- char *sb_lvbptr;
-};
-
-struct dlm_range {
- uint64_t ra_start;
- uint64_t ra_end;
-};
-
-
-
-
-Overview of administrative functions
-------------------------------------
-
-- dlm_pthread_init
-- dlm_ls_pthread_init
-- dlm_pthread_cleanup
-- dlm_get_fd
-- dlm_ls_get_fd
-- dlm_dispatch
-- dlm_create_lockspace
-- dlm_open_lockspace
-- dlm_release_lockspace
-- dlm_close_lockspace
-
-
-typedef void * dlm_lshandle_t;
-
-dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode);
-
-int dlm_release_lockspace(const char *name, dlm_lshandle_t ls, int force);
-
-dlm_lshandle_t dlm_open_lockspace(const char *name);
-
-int dlm_close_lockspace(dlm_lshandle_t ls);
-
-int dlm_pthread_init();
-
-int dlm_ls_pthread_init(dlm_lshandle_t lockspace);
-
-int dlm_pthread_cleanup();
-
-int dlm_get_fd();
-
-int dlm_ls_get_fd(dlm_lshandle_t ls);
-
-int dlm_dispatch(int fd);
-
-
-
-Query functions
----------------
-
-Query functions follow the same pattern as the lock and unlock functions.
-
-int dlm_query(
- struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo,
- void (*astaddr) (void *astarg),
- void *astarg);
-
-int dlm_query_wait(
- struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo);
-
-int dlm_ls_query(
- dlm_lshandle_t lockspace,
- struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo,
- void (*astaddr) (void *astarg),
- void *astarg);
-
-int dlm_ls_query_wait(
- dlm_lshandle_t lockspace,
- struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo);
-
-#define DLM_LOCK_THIS 0x0007
-#define DLM_QUERY_MODE_MASK 0x0007
-
-#define DLM_QUERY_QUEUE_WAIT 0x0008
-#define DLM_QUERY_QUEUE_CONVERT 0x0010
-#define DLM_QUERY_QUEUE_GRANT 0x0020
-#define DLM_QUERY_QUEUE_GRANTED 0x0030
-#define DLM_QUERY_QUEUE_ALL 0x0038
-
-#define DLM_QUERY_LOCKS_HIGHER 0x0100
-#define DLM_QUERY_LOCKS_LOWER 0x0200
-#define DLM_QUERY_LOCKS_EQUAL 0x0300
-#define DLM_QUERY_LOCKS_BLOCKING 0x0400
-#define DLM_QUERY_LOCKS_NOTBLOCK 0x0500
-#define DLM_QUERY_LOCKS_ALL 0x0600
-#define DLM_QUERY_MASK 0x0F00
-
-#define DLM_QUERY_GRMODE 0x0000
-#define DLM_QUERY_RQMODE 0x1000
-
-struct dlm_lockinfo {
- int lki_lkid;
- int lki_mstlkid;
- int lki_parent;
- int lki_node;
- int lki_ownpid;
- uint8_t lki_state;
- uint8_t lki_grmode;
- uint8_t lki_rqmode;
- struct dlm_range lki_grrange;
- struct dlm_range lki_rqrange;
-};
-
-struct dlm_resinfo {
- int rsi_length;
- int rsi_grantcount;
- int rsi_convcount;
- int rsi_waitcount;
- int rsi_masternode;
- char rsi_name[DLM_RESNAME_MAXLEN];
- char rsi_valblk[DLM_LVB_LEN];
-};
-
-struct dlm_queryinfo {
- struct dlm_resinfo *gqi_resinfo;
- struct dlm_lockinfo *gqi_lockinfo;
- int gqi_locksize;
- int gqi_lockcount;
-};
-
-
-
diff --git a/dlm/libdlm/51-dlm.rules b/dlm/libdlm/51-dlm.rules
deleted file mode 100644
index 0f22134..0000000
--- a/dlm/libdlm/51-dlm.rules
+++ /dev/null
@@ -1,2 +0,0 @@
-KERNEL=="dlm-control|dlm-monitor|dlm_default", MODE="0666", SYMLINK+="misc/%k"
-KERNEL=="dlm_*", MODE="0660", SYMLINK+="misc/%k"
diff --git a/dlm/libdlm/Makefile b/dlm/libdlm/Makefile
deleted file mode 100644
index dfbfaa5..0000000
--- a/dlm/libdlm/Makefile
+++ /dev/null
@@ -1,81 +0,0 @@
-TARGET= libdlm
-
-LIBDIRT=$(TARGET).a \
- $(TARGET)_lt.a \
- $(TARGET).so.${SOMAJOR}.${SOMINOR} \
- $(TARGET)_lt.so.${SOMAJOR}.${SOMINOR}
-
-LIBSYMT=$(TARGET).so \
- $(TARGET)_lt.so \
- $(TARGET).so.$(SOMAJOR) \
- $(TARGET)_lt.so.$(SOMAJOR)
-
-INCDIRT=$(TARGET).h
-
-UDEVT=51-dlm.rules
-
-PKGCONF=$(TARGET).pc $(TARGET)_lt.pc
-
-include ../../make/defines.mk
-
-SHAREDLIB=$(TARGET).so.${SOMAJOR}.${SOMINOR} $(TARGET)_lt.so.${SOMAJOR}.${SOMINOR}
-STATICLIB=$(TARGET).a $(TARGET)_lt.a
-
-all: $(STATICLIB) $(SHAREDLIB) $(PKGCONF)
-
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-CFLAGS += -fPIC
-CFLAGS += -I$(S)
-CFLAGS += -I${incdir}
-CFLAGS += -I$(KERNEL_SRC)/include
-
-REENT_CFLAGS += -D_REENTRANT
-
-LDFLAGS += -L${libdir}
-
-PTHREAD_LDFLAGS += -lpthread
-
-$(TARGET).a: $(TARGET).o
- ${AR} cru $@ $^
- ${RANLIB} $@
-
-$(TARGET)_lt.a: $(TARGET)_lt.o
- ${AR} cru $@ $^
- ${RANLIB} $@
-
-$(TARGET).so.${SOMAJOR}.${SOMINOR}: $(TARGET).o
- $(CC) -shared -o $@ -Wl,-soname=$(TARGET).so.$(SOMAJOR) $< $(PTHREAD_LDFLAGS) $(LDFLAGS)
- ln -sf $(TARGET).so.$(SOMAJOR).$(SOMINOR) $(TARGET).so
- ln -sf $(TARGET).so.$(SOMAJOR).$(SOMINOR) $(TARGET).so.$(SOMAJOR)
-
-$(TARGET)_lt.so.${SOMAJOR}.${SOMINOR}: $(TARGET)_lt.o
- $(CC) -shared -o $@ -Wl,-soname=$(TARGET)_lt.so.$(SOMAJOR) $< $(LDFLAGS)
- ln -sf $(TARGET)_lt.so.$(SOMAJOR).$(SOMINOR) $(TARGET)_lt.so
- ln -sf $(TARGET)_lt.so.$(SOMAJOR).$(SOMINOR) $(TARGET)_lt.so.$(SOMAJOR)
-
-$(TARGET).pc: $(S)/$(TARGET).pc.in
- cat $(S)/$(TARGET).pc.in | \
- sed \
- -e 's#@PREFIX@#${prefix}#g' \
- -e 's#@LIBDIR@#${libdir}#g' \
- -e 's#@INCDIR@#${incdir}#g' \
- -e 's#@VERSION@#${RELEASE_VERSION}#g' \
- > $@
-
-$(TARGET)_lt.pc: $(S)/$(TARGET)_lt.pc.in
- cat $(S)/$(TARGET)_lt.pc.in | \
- sed \
- -e 's#@PREFIX@#${prefix}#g' \
- -e 's#@LIBDIR@#${libdir}#g' \
- -e 's#@INCDIR@#${incdir}#g' \
- -e 's#@VERSION@#${RELEASE_VERSION}#g' \
- > $@
-
-clean: generalclean
-
--include $(TARGET).d
--include $(TARGET)_lt.d
diff --git a/dlm/libdlm/libdlm.c b/dlm/libdlm/libdlm.c
deleted file mode 100644
index 3c3a31a..0000000
--- a/dlm/libdlm/libdlm.c
+++ /dev/null
@@ -1,1485 +0,0 @@
-#ifdef _REENTRANT
-#include <pthread.h>
-#endif
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <linux/major.h>
-#ifdef HAVE_SELINUX
-#include <selinux/selinux.h>
-#endif
-#include <linux/types.h>
-#include <linux/dlm.h>
-#define BUILDING_LIBDLM
-#include "libdlm.h"
-#include <linux/dlm_device.h>
-
-#define DEV_PREFIX "/dev/"
-#define DLM_PREFIX "dlm_"
-#define DLM_MISC_PREFIX DEV_PREFIX DLM_PREFIX
-#define DLM_CONTROL_NAME "dlm-control"
-#define DLM_CONTROL_PATH DEV_PREFIX DLM_CONTROL_NAME
-#define DEFAULT_LOCKSPACE "default"
-
-/*
- * V5 of the dlm_device.h kernel/user interface structs
- */
-
-struct dlm_lock_params_v5 {
- __u8 mode;
- __u8 namelen;
- __u16 flags;
- __u32 lkid;
- __u32 parent;
- void *castparam;
- void *castaddr;
- void *bastparam;
- void *bastaddr;
- struct dlm_lksb *lksb;
- char lvb[DLM_USER_LVB_LEN];
- char name[0];
-};
-
-struct dlm_write_request_v5 {
- __u32 version[3];
- __u8 cmd;
- __u8 is64bit;
- __u8 unused[2];
-
- union {
- struct dlm_lock_params_v5 lock;
- struct dlm_lspace_params lspace;
- } i;
-};
-
-struct dlm_lock_result_v5 {
- __u32 length;
- void *user_astaddr;
- void *user_astparam;
- struct dlm_lksb *user_lksb;
- struct dlm_lksb lksb;
- __u8 bast_mode;
- __u8 unused[3];
- /* Offsets may be zero if no data is present */
- __u32 lvb_offset;
-};
-
-
-/*
- * One of these per lockspace in use by the application
- */
-
-struct dlm_ls_info {
- int fd;
-#ifdef _REENTRANT
- pthread_t tid;
-#else
- int tid;
-#endif
-};
-
-/*
- * The default lockspace.
- * I've resisted putting locking around this as the user should be
- * "sensible" and only do lockspace operations either in the
- * main thread or ... carefully...
- */
-
-static struct dlm_ls_info *default_ls = NULL;
-static int control_fd = -1;
-static struct dlm_device_version kernel_version;
-static int kernel_version_detected = 0;
-
-
-static int release_lockspace(uint32_t minor, uint32_t flags);
-
-
-static void ls_dev_name(const char *lsname, char *devname, int devlen)
-{
- snprintf(devname, devlen, DLM_MISC_PREFIX "%s", lsname);
-}
-
-static void dummy_ast_routine(void *arg)
-{
-}
-
-#ifdef _REENTRANT
-/* Used for the synchronous and "simplified, synchronous" API routines */
-struct lock_wait
-{
- pthread_cond_t cond;
- pthread_mutex_t mutex;
- struct dlm_lksb lksb;
-};
-
-static void sync_ast_routine(void *arg)
-{
- struct lock_wait *lwait = arg;
-
- pthread_mutex_lock(&lwait->mutex);
- pthread_cond_signal(&lwait->cond);
- pthread_mutex_unlock(&lwait->mutex);
-}
-
-/* lock_resource & unlock_resource
- * are the simplified, synchronous API.
- * Aways uses the default lockspace.
- */
-int lock_resource(const char *resource, int mode, int flags, int *lockid)
-{
- int status;
- struct lock_wait lwait;
-
- if (default_ls == NULL)
- {
- if (dlm_pthread_init())
- {
- return -1;
- }
- }
-
- if (!lockid)
- {
- errno = EINVAL;
- return -1;
- }
-
- /* Conversions need the lockid in the LKSB */
- if (flags & LKF_CONVERT)
- lwait.lksb.sb_lkid = *lockid;
-
- pthread_cond_init(&lwait.cond, NULL);
- pthread_mutex_init(&lwait.mutex, NULL);
- pthread_mutex_lock(&lwait.mutex);
-
- status = dlm_lock(mode,
- &lwait.lksb,
- flags,
- resource,
- strlen(resource),
- 0,
- sync_ast_routine,
- &lwait,
- NULL,
- NULL);
- if (status)
- return status;
-
- /* Wait for it to complete */
- pthread_cond_wait(&lwait.cond, &lwait.mutex);
- pthread_mutex_unlock(&lwait.mutex);
-
- *lockid = lwait.lksb.sb_lkid;
-
- errno = lwait.lksb.sb_status;
- if (lwait.lksb.sb_status)
- return -1;
- else
- return 0;
-}
-
-
-int unlock_resource(int lockid)
-{
- int status;
- struct lock_wait lwait;
-
- if (default_ls == NULL)
- {
- errno = -ENOTCONN;
- return -1;
- }
-
- pthread_cond_init(&lwait.cond, NULL);
- pthread_mutex_init(&lwait.mutex, NULL);
- pthread_mutex_lock(&lwait.mutex);
-
- status = dlm_unlock(lockid, 0, &lwait.lksb, &lwait);
-
- if (status)
- return status;
-
- /* Wait for it to complete */
- pthread_cond_wait(&lwait.cond, &lwait.mutex);
- pthread_mutex_unlock(&lwait.mutex);
-
- errno = lwait.lksb.sb_status;
- if (lwait.lksb.sb_status != DLM_EUNLOCK)
- return -1;
- else
- return 0;
-}
-
-/* Tidy up threads after a lockspace is closed */
-static int ls_pthread_cleanup(struct dlm_ls_info *lsinfo)
-{
- int status = 0;
- int fd;
-
- /* Must close the fd after the thread has finished */
- fd = lsinfo->fd;
- if (lsinfo->tid)
- {
- status = pthread_cancel(lsinfo->tid);
- if (!status)
- pthread_join(lsinfo->tid, NULL);
- }
- if (!status)
- {
- free(lsinfo);
- close(fd);
- }
-
- return status;
-}
-
-/* Cleanup default lockspace */
-int dlm_pthread_cleanup(void)
-{
- struct dlm_ls_info *lsinfo = default_ls;
-
- /* Protect users from their own stupidity */
- if (!lsinfo)
- return 0;
-
- default_ls = NULL;
-
- return ls_pthread_cleanup(lsinfo);
-}
-#else
-
-/* Non-pthread version of cleanup */
-static int ls_pthread_cleanup(struct dlm_ls_info *lsinfo)
-{
- close(lsinfo->fd);
- free(lsinfo);
- return 0;
-}
-#endif
-
-
-static void set_version_v5(struct dlm_write_request_v5 *req)
-{
- req->version[0] = kernel_version.version[0];
- req->version[1] = kernel_version.version[1];
- req->version[2] = kernel_version.version[2];
- if (sizeof(long) == sizeof(long long))
- req->is64bit = 1;
- else
- req->is64bit = 0;
-}
-
-static void set_version_v6(struct dlm_write_request *req)
-{
- req->version[0] = kernel_version.version[0];
- req->version[1] = kernel_version.version[1];
- req->version[2] = kernel_version.version[2];
- if (sizeof(long) == sizeof(long long))
- req->is64bit = 1;
- else
- req->is64bit = 0;
-}
-
-static int open_default_lockspace(void)
-{
- if (!default_ls) {
- dlm_lshandle_t ls;
-
- /* This isn't the race it looks, create_lockspace will
- * do the right thing if the lockspace has already been
- * created.
- */
-
- ls = dlm_open_lockspace(DEFAULT_LOCKSPACE);
- if (!ls)
- ls = dlm_create_lockspace(DEFAULT_LOCKSPACE, 0600);
- if (!ls)
- return -1;
-
- default_ls = (struct dlm_ls_info *)ls;
- }
- return 0;
-}
-
-static void detect_kernel_version(void)
-{
- struct dlm_device_version v;
- int rv;
-
- rv = read(control_fd, &v, sizeof(struct dlm_device_version));
- if (rv < 0) {
- kernel_version.version[0] = 5;
- kernel_version.version[1] = 0;
- kernel_version.version[2] = 0;
- } else {
- kernel_version.version[0] = v.version[0];
- kernel_version.version[1] = v.version[1];
- kernel_version.version[2] = v.version[2];
- }
-
- kernel_version_detected = 1;
-}
-
-static int find_control_minor(int *minor)
-{
- FILE *f;
- char name[256];
- int found = 0, m = 0;
-
- f = fopen("/proc/misc", "r");
- if (!f)
- return -1;
-
- while (!feof(f)) {
- if (fscanf(f, "%d %s", &m, name) != 2)
- continue;
- if (strcmp(name, DLM_CONTROL_NAME))
- continue;
- found = 1;
- break;
- }
- fclose(f);
-
- if (found) {
- *minor = m;
- return 0;
- }
- return -1;
-}
-
-static int open_control_device(void)
-{
- struct stat st;
- int i, rv, minor, found = 0;
-
- if (control_fd > -1)
- goto out;
-
- rv = find_control_minor(&minor);
- if (rv < 0)
- return -1;
-
- /* wait for udev to create the device */
-
- for (i = 0; i < 10; i++) {
- if (stat(DLM_CONTROL_PATH, &st) == 0 &&
- minor(st.st_rdev) == minor) {
- found = 1;
- break;
- }
- sleep(1);
- continue;
- }
-
- if (!found)
- return -1;
-
- control_fd = open(DLM_CONTROL_PATH, O_RDWR);
- if (control_fd == -1)
- return -1;
-
- out:
- fcntl(control_fd, F_SETFD, 1);
-
- if (!kernel_version_detected)
- detect_kernel_version();
- return 0;
-}
-
-/* the max number of characters in a sysfs device name, not including \0 */
-#define MAX_SYSFS_NAME 19
-
-static int find_udev_device(const char *lockspace, int minor, char *udev_path)
-{
- char basename[PATH_MAX];
- char tmp_path[PATH_MAX];
- DIR *d;
- struct dirent *de;
- struct stat st;
- size_t basename_len;
- int i;
-
- ls_dev_name(lockspace, udev_path, PATH_MAX);
- snprintf(basename, PATH_MAX, DLM_PREFIX "%s", lockspace);
- basename_len = strlen(basename);
-
- for (i = 0; i < 10; i++) {
-
- /* look for a device with the full name */
-
- if (stat(udev_path, &st) == 0 && minor(st.st_rdev) == minor)
- return 0;
-
- if (basename_len < MAX_SYSFS_NAME) {
- sleep(1);
- continue;
- }
-
- /* look for a device with a truncated name */
-
- d = opendir(DEV_PREFIX);
- while ((de = readdir(d))) {
- if (de->d_name[0] == '.')
- continue;
- if (strlen(de->d_name) < MAX_SYSFS_NAME)
- continue;
- if (strncmp(de->d_name, basename, MAX_SYSFS_NAME))
- continue;
- snprintf(tmp_path, PATH_MAX, DEV_PREFIX "%s",
- de->d_name);
- if (stat(tmp_path, &st))
- continue;
- if (minor(st.st_rdev) != minor)
- continue;
-
- /* truncated name */
- strncpy(udev_path, tmp_path, PATH_MAX);
- closedir(d);
- return 0;
- }
- closedir(d);
- sleep(1);
- }
-
- return -1;
-}
-
-/*
- * do_dlm_dispatch()
- * Read an ast from the kernel.
- */
-
-static int do_dlm_dispatch_v5(int fd)
-{
- char resultbuf[sizeof(struct dlm_lock_result_v5) + DLM_USER_LVB_LEN];
- struct dlm_lock_result_v5 *result = (struct dlm_lock_result_v5 *)resultbuf;
- char *fullresult = NULL;
- int status;
- void (*astaddr)(void *astarg);
-
- status = read(fd, result, sizeof(resultbuf));
- if (status <= 0)
- return -1;
-
- /* This shouldn't happen any more, can probably be removed */
-
- if (result->length != status) {
- int newstat;
-
- fullresult = malloc(result->length);
- if (!fullresult)
- return -1;
-
- newstat = read(fd, (struct dlm_lock_result_v5 *)fullresult,
- result->length);
-
- /* If it read OK then use the new data. otherwise we can
- still deliver the AST, it just might not have all the
- info in it...hmmm */
-
- if (newstat == result->length)
- result = (struct dlm_lock_result_v5 *)fullresult;
- } else {
- fullresult = resultbuf;
- }
-
-
- /* Copy lksb to user's buffer - except the LVB ptr */
- memcpy(result->user_lksb, &result->lksb,
- sizeof(struct dlm_lksb) - sizeof(char*));
-
- /* Flip the status. Kernel space likes negative return codes,
- userspace positive ones */
- result->user_lksb->sb_status = -result->user_lksb->sb_status;
-
- /* Copy optional items */
- if (result->lvb_offset)
- memcpy(result->user_lksb->sb_lvbptr,
- fullresult + result->lvb_offset, DLM_LVB_LEN);
-
- /* Call AST */
- if (result->user_astaddr) {
- astaddr = result->user_astaddr;
- astaddr(result->user_astparam);
- }
-
- if (fullresult != resultbuf)
- free(fullresult);
-
- return 0;
-}
-
-static int do_dlm_dispatch_v6(int fd)
-{
- char resultbuf[sizeof(struct dlm_lock_result) + DLM_USER_LVB_LEN];
- struct dlm_lock_result *result = (struct dlm_lock_result *)resultbuf;
- int status;
- void (*astaddr)(void *astarg);
-
- status = read(fd, result, sizeof(resultbuf));
- if (status <= 0)
- return -1;
-
- /* Copy lksb to user's buffer - except the LVB ptr */
- memcpy(result->user_lksb, &result->lksb,
- sizeof(struct dlm_lksb) - sizeof(char*));
-
- /* Copy lvb to user's buffer */
- if (result->lvb_offset)
- memcpy(result->user_lksb->sb_lvbptr,
- (char *)result + result->lvb_offset, DLM_LVB_LEN);
-
- result->user_lksb->sb_status = -result->user_lksb->sb_status;
-
- if (result->user_astaddr) {
- astaddr = result->user_astaddr;
- astaddr(result->user_astparam);
- }
-
- return 0;
-}
-
-static int do_dlm_dispatch(int fd)
-{
- if (kernel_version.version[0] == 5)
- return do_dlm_dispatch_v5(fd);
- else
- return do_dlm_dispatch_v6(fd);
-}
-
-
-/*
- * sync_write()
- * Helper routine which supports the synchronous DLM calls. This
- * writes a parameter block down to the DLM and waits for the
- * operation to complete. This hides the different completion mechanism
- * used when called from the main thread or the DLM 'AST' thread.
- */
-
-#ifdef _REENTRANT
-
-static int sync_write_v5(struct dlm_ls_info *lsinfo,
- struct dlm_write_request_v5 *req, int len)
-{
- struct lock_wait lwait;
- int status;
-
- if (pthread_self() == lsinfo->tid) {
- /* This is the DLM worker thread, don't use lwait to sync */
- req->i.lock.castaddr = dummy_ast_routine;
- req->i.lock.castparam = NULL;
-
- status = write(lsinfo->fd, req, len);
- if (status < 0)
- return -1;
-
- while (req->i.lock.lksb->sb_status == EINPROG) {
- do_dlm_dispatch_v5(lsinfo->fd);
- }
- } else {
- pthread_cond_init(&lwait.cond, NULL);
- pthread_mutex_init(&lwait.mutex, NULL);
- pthread_mutex_lock(&lwait.mutex);
-
- req->i.lock.castaddr = sync_ast_routine;
- req->i.lock.castparam = &lwait;
-
- status = write(lsinfo->fd, req, len);
- if (status < 0)
- return -1;
-
- pthread_cond_wait(&lwait.cond, &lwait.mutex);
- pthread_mutex_unlock(&lwait.mutex);
- }
-
- return status; /* lock status is in the lksb */
-}
-
-static int sync_write_v6(struct dlm_ls_info *lsinfo,
- struct dlm_write_request *req, int len)
-{
- struct lock_wait lwait;
- int status;
-
- if (pthread_self() == lsinfo->tid) {
- /* This is the DLM worker thread, don't use lwait to sync */
- req->i.lock.castaddr = dummy_ast_routine;
- req->i.lock.castparam = NULL;
-
- status = write(lsinfo->fd, req, len);
- if (status < 0)
- return -1;
-
- while (req->i.lock.lksb->sb_status == EINPROG) {
- do_dlm_dispatch_v6(lsinfo->fd);
- }
- } else {
- pthread_cond_init(&lwait.cond, NULL);
- pthread_mutex_init(&lwait.mutex, NULL);
- pthread_mutex_lock(&lwait.mutex);
-
- req->i.lock.castaddr = sync_ast_routine;
- req->i.lock.castparam = &lwait;
-
- status = write(lsinfo->fd, req, len);
- if (status < 0)
- return -1;
-
- pthread_cond_wait(&lwait.cond, &lwait.mutex);
- pthread_mutex_unlock(&lwait.mutex);
- }
-
- return status; /* lock status is in the lksb */
-}
-
-#else /* _REENTRANT */
-
-static int sync_write_v5(struct dlm_ls_info *lsinfo,
- struct dlm_write_request_v5 *req, int len)
-{
- int status;
-
- req->i.lock.castaddr = dummy_ast_routine;
- req->i.lock.castparam = NULL;
-
- status = write(lsinfo->fd, req, len);
- if (status < 0)
- return -1;
-
- while (req->i.lock.lksb->sb_status == EINPROG) {
- do_dlm_dispatch_v5(lsinfo->fd);
- }
-
- errno = req->i.lock.lksb->sb_status;
- if (errno && errno != EUNLOCK)
- return -1;
- return 0;
-}
-
-static int sync_write_v6(struct dlm_ls_info *lsinfo,
- struct dlm_write_request *req, int len)
-{
- int status;
-
- req->i.lock.castaddr = dummy_ast_routine;
- req->i.lock.castparam = NULL;
-
- status = write(lsinfo->fd, req, len);
- if (status < 0)
- return -1;
-
- while (req->i.lock.lksb->sb_status == EINPROG) {
- do_dlm_dispatch_v6(lsinfo->fd);
- }
-
- errno = req->i.lock.lksb->sb_status;
- if (errno && errno != EUNLOCK)
- return -1;
- return 0;
-}
-
-#endif /* _REENTRANT */
-
-
-/*
- * Lock
- * All the ways to request/convert a lock
- */
-
-static int ls_lock_v5(dlm_lshandle_t ls,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg))
-{
- char parambuf[sizeof(struct dlm_write_request_v5) + DLM_RESNAME_MAXLEN];
- struct dlm_write_request_v5 *req = (struct dlm_write_request_v5 *)parambuf;
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
- int status;
- int len;
-
- memset(req, 0, sizeof(*req));
- set_version_v5(req);
-
- req->cmd = DLM_USER_LOCK;
- req->i.lock.mode = mode;
- req->i.lock.flags = (flags & ~LKF_WAIT);
- req->i.lock.lkid = lksb->sb_lkid;
- req->i.lock.parent = parent;
- req->i.lock.lksb = lksb;
- req->i.lock.castaddr = astaddr;
- req->i.lock.bastaddr = bastaddr;
- req->i.lock.castparam = astarg; /* same comp and blocking ast arg */
- req->i.lock.bastparam = astarg;
-
- if (flags & LKF_CONVERT) {
- req->i.lock.namelen = 0;
- } else {
- if (namelen > DLM_RESNAME_MAXLEN) {
- errno = EINVAL;
- return -1;
- }
- req->i.lock.namelen = namelen;
- memcpy(req->i.lock.name, name, namelen);
- }
-
- if (flags & LKF_VALBLK) {
- memcpy(req->i.lock.lvb, lksb->sb_lvbptr, DLM_LVB_LEN);
- }
-
- len = sizeof(struct dlm_write_request_v5) + namelen;
- lksb->sb_status = EINPROG;
-
- if (flags & LKF_WAIT)
- status = sync_write_v5(lsinfo, req, len);
- else
- status = write(lsinfo->fd, req, len);
-
- if (status < 0)
- return -1;
-
- /*
- * the lock id is the return value from the write on the device
- */
-
- if (status > 0)
- lksb->sb_lkid = status;
- return 0;
-}
-
-static int ls_lock_v6(dlm_lshandle_t ls,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- uint64_t *xid,
- uint64_t *timeout)
-{
- char parambuf[sizeof(struct dlm_write_request) + DLM_RESNAME_MAXLEN];
- struct dlm_write_request *req = (struct dlm_write_request *)parambuf;
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
- int status;
- int len;
-
- memset(req, 0, sizeof(*req));
- set_version_v6(req);
-
- req->cmd = DLM_USER_LOCK;
- req->i.lock.mode = mode;
- req->i.lock.flags = (flags & ~LKF_WAIT);
- req->i.lock.lkid = lksb->sb_lkid;
- req->i.lock.parent = parent;
- req->i.lock.lksb = lksb;
- req->i.lock.castaddr = astaddr;
- req->i.lock.bastaddr = bastaddr;
- req->i.lock.castparam = astarg; /* same comp and blocking ast arg */
- req->i.lock.bastparam = astarg;
-
- if (xid)
- req->i.lock.xid = *xid;
- if (timeout)
- req->i.lock.timeout = *timeout;
-
- if (flags & LKF_CONVERT) {
- req->i.lock.namelen = 0;
- } else {
- if (namelen > DLM_RESNAME_MAXLEN) {
- errno = EINVAL;
- return -1;
- }
- req->i.lock.namelen = namelen;
- memcpy(req->i.lock.name, name, namelen);
- }
-
- if (flags & LKF_VALBLK) {
- memcpy(req->i.lock.lvb, lksb->sb_lvbptr, DLM_LVB_LEN);
- }
-
- len = sizeof(struct dlm_write_request) + namelen;
- lksb->sb_status = EINPROG;
-
- if (flags & LKF_WAIT)
- status = sync_write_v6(lsinfo, req, len);
- else
- status = write(lsinfo->fd, req, len);
-
- if (status < 0)
- return -1;
-
- /*
- * the lock id is the return value from the write on the device
- */
-
- if (status > 0)
- lksb->sb_lkid = status;
- return 0;
-}
-
-static int ls_lock(dlm_lshandle_t ls,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- void *range)
-{
- /* no support for range locks */
- if (range) {
- errno = ENOSYS;
- return -1;
- }
-
- if (flags & LKF_VALBLK && !lksb->sb_lvbptr) {
- errno = EINVAL;
- return -1;
- }
-
- if (kernel_version.version[0] == 5)
- return ls_lock_v5(ls, mode, lksb, flags, name, namelen, parent,
- astaddr, astarg, bastaddr);
- else
- return ls_lock_v6(ls, mode, lksb, flags, name, namelen, parent,
- astaddr, astarg, bastaddr, NULL, NULL);
-}
-
-/*
- * Extended async locking in own lockspace
- */
-int dlm_ls_lockx(dlm_lshandle_t ls,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- uint64_t *xid,
- uint64_t *timeout)
-{
- if (kernel_version.version[0] < 6) {
- errno = ENOSYS;
- return -1;
- }
-
- return ls_lock_v6(ls, mode, lksb, flags, name, namelen, parent,
- astaddr, astarg, bastaddr, xid, timeout);
-}
-
-/*
- * Async locking in own lockspace
- */
-int dlm_ls_lock(dlm_lshandle_t ls,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- void *range)
-{
- return ls_lock(ls, mode, lksb, flags, name, namelen, parent,
- astaddr, astarg, bastaddr, range);
-}
-
-/*
- * Sync locking in own lockspace
- */
-int dlm_ls_lock_wait(dlm_lshandle_t ls,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void *bastarg,
- void (*bastaddr) (void *bastarg),
- void *range)
-{
- return ls_lock(ls, mode, lksb, flags | LKF_WAIT, name, namelen, parent,
- NULL, bastarg, bastaddr, range);
-}
-
-/*
- * Async locking in the default lockspace
- */
-int dlm_lock(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- void *range)
-{
- if (open_default_lockspace())
- return -1;
-
- return ls_lock(default_ls, mode, lksb, flags, name, namelen, parent,
- astaddr, astarg, bastaddr, range);
-}
-
-/*
- * Sync locking in the default lockspace
- */
-int dlm_lock_wait(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void *bastarg,
- void (*bastaddr) (void *bastarg),
- void *range)
-{
- if (open_default_lockspace())
- return -1;
-
- return ls_lock(default_ls, mode, lksb, flags | LKF_WAIT, name, namelen,
- parent, NULL, bastarg, bastaddr, range);
-}
-
-
-/*
- * Unlock
- * All the ways to unlock/cancel a lock
- */
-
-static int ls_unlock_v5(struct dlm_ls_info *lsinfo, uint32_t lkid,
- uint32_t flags, struct dlm_lksb *lksb, void *astarg)
-{
- struct dlm_write_request_v5 req;
-
- set_version_v5(&req);
- req.cmd = DLM_USER_UNLOCK;
- req.i.lock.lkid = lkid;
- req.i.lock.flags = (flags & ~LKF_WAIT);
- req.i.lock.lksb = lksb;
- req.i.lock.castparam = astarg;
- /* DLM_USER_UNLOCK will default to existing completion AST */
- req.i.lock.castaddr = 0;
- lksb->sb_status = EINPROG;
-
- if (flags & LKF_WAIT)
- return sync_write_v5(lsinfo, &req, sizeof(req));
- else
- return write(lsinfo->fd, &req, sizeof(req));
-}
-
-static int ls_unlock_v6(struct dlm_ls_info *lsinfo, uint32_t lkid,
- uint32_t flags, struct dlm_lksb *lksb, void *astarg)
-{
- struct dlm_write_request req;
-
- set_version_v6(&req);
- req.cmd = DLM_USER_UNLOCK;
- req.i.lock.lkid = lkid;
- req.i.lock.flags = (flags & ~LKF_WAIT);
- req.i.lock.lksb = lksb;
- req.i.lock.namelen = 0;
- req.i.lock.castparam = astarg;
- /* DLM_USER_UNLOCK will default to existing completion AST */
- req.i.lock.castaddr = 0;
- lksb->sb_status = EINPROG;
-
- if (flags & LKF_WAIT)
- return sync_write_v6(lsinfo, &req, sizeof(req));
- else
- return write(lsinfo->fd, &req, sizeof(req));
-}
-
-int dlm_ls_unlock(dlm_lshandle_t ls, uint32_t lkid, uint32_t flags,
- struct dlm_lksb *lksb, void *astarg)
-{
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
- int status;
-
- if (ls == NULL) {
- errno = ENOTCONN;
- return -1;
- }
-
- if (!lkid) {
- errno = EINVAL;
- return -1;
- }
-
- if (kernel_version.version[0] == 5)
- status = ls_unlock_v5(lsinfo, lkid, flags, lksb, astarg);
- else
- status = ls_unlock_v6(lsinfo, lkid, flags, lksb, astarg);
-
- if (status < 0)
- return -1;
- return 0;
-}
-
-int dlm_ls_unlock_wait(dlm_lshandle_t ls, uint32_t lkid, uint32_t flags,
- struct dlm_lksb *lksb)
-{
- return dlm_ls_unlock(ls, lkid, flags | LKF_WAIT, lksb, NULL);
-}
-
-int dlm_unlock_wait(uint32_t lkid, uint32_t flags, struct dlm_lksb *lksb)
-{
- return dlm_ls_unlock_wait(default_ls, lkid, flags | LKF_WAIT, lksb);
-}
-
-int dlm_unlock(uint32_t lkid, uint32_t flags, struct dlm_lksb *lksb,
- void *astarg)
-{
- return dlm_ls_unlock(default_ls, lkid, flags, lksb, astarg);
-}
-
-int dlm_ls_deadlock_cancel(dlm_lshandle_t ls, uint32_t lkid, uint32_t flags)
-{
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
- struct dlm_write_request req;
-
- if (kernel_version.version[0] < 6) {
- errno = ENOSYS;
- return -1;
- }
-
- if (ls == NULL) {
- errno = ENOTCONN;
- return -1;
- }
-
- if (!lkid) {
- errno = EINVAL;
- return -1;
- }
-
- set_version_v6(&req);
- req.cmd = DLM_USER_DEADLOCK;
- req.i.lock.lkid = lkid;
- req.i.lock.flags = flags;
-
- return write(lsinfo->fd, &req, sizeof(req));
-}
-
-
-/*
- * Purge
- * Clear away orphan locks
- */
-
-int dlm_ls_purge(dlm_lshandle_t ls, int nodeid, int pid)
-{
- struct dlm_write_request req;
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
- int status;
-
- if (kernel_version.version[0] < 6) {
- errno = ENOSYS;
- return -1;
- }
-
- if (ls == NULL) {
- errno = ENOTCONN;
- return -1;
- }
-
- set_version_v6(&req);
- req.cmd = DLM_USER_PURGE;
- req.i.purge.nodeid = nodeid;
- req.i.purge.pid = pid;
-
- status = write(lsinfo->fd, &req, sizeof(req));
-
- if (status < 0)
- return -1;
- return 0;
-}
-
-
-/* These two routines for for users that want to
- * do their own fd handling.
- * This allows a non-threaded app to use the DLM.
- */
-int dlm_get_fd(void)
-{
- if (default_ls)
- {
- return default_ls->fd;
- }
- else
- {
- if (open_default_lockspace())
- return -1;
- else
- return default_ls->fd;
- }
-}
-
-int dlm_dispatch(int fd)
-{
- int status;
- int fdflags;
-
- fdflags = fcntl(fd, F_GETFL, 0);
- fcntl(fd, F_SETFL, fdflags | O_NONBLOCK);
- do
- {
- status = do_dlm_dispatch(fd);
- } while (status == 0);
-
- /* EAGAIN is not an error */
- if (status < 0 && errno == EAGAIN)
- status = 0;
-
- fcntl(fd, F_SETFL, fdflags);
- return status;
-}
-
-/* Converts a lockspace handle into a file descriptor */
-int dlm_ls_get_fd(dlm_lshandle_t lockspace)
-{
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)lockspace;
-
- return lsinfo->fd;
-}
-
-#ifdef _REENTRANT
-static void *dlm_recv_thread(void *lsinfo)
-{
- struct dlm_ls_info *lsi = lsinfo;
-
- for (;;)
- do_dlm_dispatch(lsi->fd);
-
- return NULL;
-}
-
-/* Multi-threaded callers normally use this */
-int dlm_pthread_init(void)
-{
- if (open_default_lockspace())
- return -1;
-
- if (default_ls->tid)
- {
- errno = EEXIST;
- return -1;
- }
-
- if (pthread_create(&default_ls->tid, NULL, dlm_recv_thread, default_ls))
- {
- int saved_errno = errno;
- close(default_ls->fd);
- free(default_ls);
- default_ls = NULL;
- errno = saved_errno;
- return -1;
- }
- return 0;
-}
-
-/* And same, for those with their own lockspace */
-int dlm_ls_pthread_init(dlm_lshandle_t ls)
-{
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
-
- if (lsinfo->tid)
- {
- errno = EEXIST;
- return -1;
- }
-
- return pthread_create(&lsinfo->tid, NULL, dlm_recv_thread, (void *)ls);
-}
-#endif
-
-/*
- * Lockspace manipulation functions
- * Privileged users (checked by the kernel) can create/release lockspaces
- */
-
-static int create_lockspace_v5(const char *name, uint32_t flags)
-{
- char reqbuf[sizeof(struct dlm_write_request_v5) + DLM_LOCKSPACE_LEN];
- struct dlm_write_request_v5 *req = (struct dlm_write_request_v5 *)reqbuf;
- int namelen = strlen(name);
- int minor;
-
- memset(reqbuf, 0, sizeof(reqbuf));
- set_version_v5(req);
-
- req->cmd = DLM_USER_CREATE_LOCKSPACE;
- req->i.lspace.flags = flags;
-
- if (namelen > DLM_LOCKSPACE_LEN) {
- errno = EINVAL;
- return -1;
- }
- memcpy(req->i.lspace.name, name, namelen);
-
- minor = write(control_fd, req, sizeof(*req) + namelen);
-
- return minor;
-}
-
-static int create_lockspace_v6(const char *name, uint32_t flags)
-{
- char reqbuf[sizeof(struct dlm_write_request) + DLM_LOCKSPACE_LEN];
- struct dlm_write_request *req = (struct dlm_write_request *)reqbuf;
- int namelen = strlen(name);
- int minor;
-
- memset(reqbuf, 0, sizeof(reqbuf));
- set_version_v6(req);
-
- req->cmd = DLM_USER_CREATE_LOCKSPACE;
- req->i.lspace.flags = flags;
-
- if (namelen > DLM_LOCKSPACE_LEN) {
- errno = EINVAL;
- return -1;
- }
- memcpy(req->i.lspace.name, name, namelen);
-
- minor = write(control_fd, req, sizeof(*req) + namelen);
-
- return minor;
-}
-
-static dlm_lshandle_t create_lockspace(const char *name, mode_t mode,
- uint32_t flags)
-{
- char dev_path[PATH_MAX];
- char udev_path[PATH_MAX];
- struct dlm_ls_info *newls;
- int error, saved_errno, minor;
-
- /* We use the control device for creating lockspaces. */
- if (open_control_device())
- return NULL;
-
- newls = malloc(sizeof(struct dlm_ls_info));
- if (!newls)
- return NULL;
-
- ls_dev_name(name, dev_path, sizeof(dev_path));
-
- if (kernel_version.version[0] == 5)
- minor = create_lockspace_v5(name, flags);
- else
- minor = create_lockspace_v6(name, flags);
-
- if (minor < 0)
- goto fail;
-
- /* Wait for udev to create the device; the device it creates may
- have a truncated name due to the sysfs device name limit. */
-
- error = find_udev_device(name, minor, udev_path);
- if (error)
- goto fail;
-
- /* If the symlink already exists, find_udev_device() will return
- it and we'll skip this. */
-
- if (strcmp(dev_path, udev_path)) {
- error = symlink(udev_path, dev_path);
- if (error)
- goto fail;
- }
-
- /* Open it and return the struct as a handle */
-
- newls->fd = open(dev_path, O_RDWR);
- if (newls->fd == -1)
- goto fail;
- if (mode)
- fchmod(newls->fd, mode);
- newls->tid = 0;
- fcntl(newls->fd, F_SETFD, 1);
- return (dlm_lshandle_t)newls;
-
- fail:
- saved_errno = errno;
- free(newls);
- errno = saved_errno;
- return NULL;
-}
-
-dlm_lshandle_t dlm_new_lockspace(const char *name, mode_t mode, uint32_t flags)
-{
- return create_lockspace(name, mode, flags);
-}
-
-dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode)
-{
- return create_lockspace(name, mode, 0);
-}
-
-static int release_lockspace_v5(uint32_t minor, uint32_t flags)
-{
- struct dlm_write_request_v5 req;
-
- set_version_v5(&req);
- req.cmd = DLM_USER_REMOVE_LOCKSPACE;
- req.i.lspace.minor = minor;
- req.i.lspace.flags = flags;
-
- return write(control_fd, &req, sizeof(req));
-}
-
-static int release_lockspace_v6(uint32_t minor, uint32_t flags)
-{
- struct dlm_write_request req;
-
- set_version_v6(&req);
- req.cmd = DLM_USER_REMOVE_LOCKSPACE;
- req.i.lspace.minor = minor;
- req.i.lspace.flags = flags;
-
- return write(control_fd, &req, sizeof(req));
-}
-
-static int release_lockspace(uint32_t minor, uint32_t flags)
-{
- if (kernel_version.version[0] == 5)
- return release_lockspace_v5(minor, flags);
- else
- return release_lockspace_v6(minor, flags);
-}
-
-int dlm_release_lockspace(const char *name, dlm_lshandle_t ls, int force)
-{
- char dev_path[PATH_MAX];
- struct stat st;
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
- uint32_t flags = 0;
- int fd, is_symlink = 0;
-
- ls_dev_name(name, dev_path, sizeof(dev_path));
- if (!lstat(dev_path, &st) && S_ISLNK(st.st_mode))
- is_symlink = 1;
-
- /* We need the minor number */
- if (fstat(lsinfo->fd, &st))
- return -1;
-
- /* Close the lockspace first if it's in use */
- ls_pthread_cleanup(lsinfo);
-
- if (open_control_device())
- return -1;
-
- if (force)
- flags = DLM_USER_LSFLG_FORCEFREE;
-
- release_lockspace(minor(st.st_rdev), flags);
-
- if (!is_symlink)
- return 0;
-
- /* The following open is used to detect if our release was the last.
- It will fail if our release was the last, because either:
- . udev has already removed the truncated sysfs device name (ENOENT)
- . the misc device has been deregistered in the kernel (ENODEV)
- (the deregister completes before release returns)
-
- So, if the open fails, we know that our release was the last,
- udev will be removing the device with the truncated name (if it
- hasn't already), and we should remove the symlink. */
-
- fd = open(dev_path, O_RDWR);
- if (fd < 0)
- unlink(dev_path);
- else
- close(fd); /* our release was not the last */
-
- return 0;
-}
-
-/*
- * Normal users just open/close lockspaces
- */
-
-dlm_lshandle_t dlm_open_lockspace(const char *name)
-{
- char dev_name[PATH_MAX];
- struct dlm_ls_info *newls;
- int saved_errno;
-
- /* Need to detect kernel version */
- if (open_control_device())
- return NULL;
-
- newls = malloc(sizeof(struct dlm_ls_info));
- if (!newls)
- return NULL;
-
- newls->tid = 0;
- ls_dev_name(name, dev_name, sizeof(dev_name));
-
- newls->fd = open(dev_name, O_RDWR);
- saved_errno = errno;
-
- if (newls->fd == -1) {
- free(newls);
- errno = saved_errno;
- return NULL;
- }
- fcntl(newls->fd, F_SETFD, 1);
- return (dlm_lshandle_t)newls;
-}
-
-int dlm_close_lockspace(dlm_lshandle_t ls)
-{
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
-
- ls_pthread_cleanup(lsinfo);
- return 0;
-}
-
-int dlm_kernel_version(uint32_t *major, uint32_t *minor, uint32_t *patch)
-{
- if (open_control_device())
- return -1;
- *major = kernel_version.version[0];
- *minor = kernel_version.version[1];
- *patch = kernel_version.version[2];
- return 0;
-}
-
-void dlm_library_version(uint32_t *major, uint32_t *minor, uint32_t *patch)
-{
- *major = DLM_DEVICE_VERSION_MAJOR;
- *minor = DLM_DEVICE_VERSION_MINOR;
- *patch = DLM_DEVICE_VERSION_PATCH;
-}
-
diff --git a/dlm/libdlm/libdlm.h b/dlm/libdlm/libdlm.h
deleted file mode 100644
index 17a552c..0000000
--- a/dlm/libdlm/libdlm.h
+++ /dev/null
@@ -1,275 +0,0 @@
-#ifndef __LIBDLM_H
-#define __LIBDLM_H
-
-/*
- * Typedefs for things that are compatible with the kernel but replicated here
- * so that users only need the libdlm include file. libdlm itself needs the
- * full kernel file so shouldn't use these.
- */
-
-#define DLM_LVB_LEN 32
-
-#ifndef BUILDING_LIBDLM
-
-/*
- * These two lengths are copied from linux/dlmconstants.h
- * They are the max length of a lockspace name and the max length of a
- * resource name.
- */
-
-#define DLM_LOCKSPACE_LEN 64
-#define DLM_RESNAME_MAXLEN 64
-
-struct dlm_lksb {
- int sb_status;
- uint32_t sb_lkid;
- char sb_flags;
- char *sb_lvbptr;
-};
-
-/* lksb flags */
-#define DLM_SBF_DEMOTED 0x01
-#define DLM_SBF_VALNOTVALID 0x02
-#define DLM_SBF_ALTMODE 0x04
-
-/* dlm_new_lockspace flags */
-#define DLM_LSFL_NODIR 0x00000001
-#define DLM_LSFL_TIMEWARN 0x00000002
-#define DLM_LSFL_FS 0x00000004
-#define DLM_LSFL_NEWEXCL 0x00000008
-
-#endif
-
-
-#if 0
-/* Dummy definition to keep linkages */
-struct dlm_queryinfo;
-#endif
-
-extern int dlm_kernel_version(uint32_t *maj, uint32_t *min, uint32_t *patch);
-extern void dlm_library_version(uint32_t *maj, uint32_t *min, uint32_t *patch);
-
-
-/*
- * Using the default lockspace
- *
- * lock_resource() - simple sync request or convert (requires pthreads)
- * unlock_resource() - simple sync unlock (requires pthreads)
- * dlm_lock() - async request or convert
- * dlm_unlock() - async unlock or cancel
- * dlm_lock_wait() - sync request or convert
- * dlm_unlock_wait() - sync unlock or cancel
- */
-
-#ifdef _REENTRANT
-extern int lock_resource(const char *resource, int mode, int flags, int *lockid);
-extern int unlock_resource(int lockid);
-#endif
-
-extern int dlm_lock(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unusued */
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- void *range); /* unused */
-
-extern int dlm_unlock(uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb,
- void *astarg);
-
-extern int dlm_lock_wait(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- void *bastarg,
- void (*bastaddr) (void *bastarg),
- void *range); /* unused */
-
-extern int dlm_unlock_wait(uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb);
-
-
-/*
- * These two are for users that want to do their own FD handling
- *
- * dlm_get_fd() - returns fd for the default lockspace for polling and dispatch
- * dlm_dispatch() - dispatches pending asts and basts
- */
-
-extern int dlm_get_fd(void);
-extern int dlm_dispatch(int fd);
-
-
-/*
- * Creating your own lockspace
- *
- * dlm_create_lockspace() - create and open a lockspace and return a handle
- * to it. Privileges are required to create/release.
- * dlm_new_lockspace() - same as create but allows flags
- * dlm_open_lockspace() - simply returns a handle for an existing lockspace and
- * may be called by ordinary users.
- * dlm_release_lockspace()
- * dlm_close_lockspace()
- * dlm_ls_get_fd()
- *
- * NOTE: that if you dlm_create_lockspace() then dlm_open_lockspace() you will
- * have two open files on the same device. Hardly a major problem but I thought
- * it worth pointing out.
- */
-
-typedef void *dlm_lshandle_t;
-
-extern dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode);
-extern int dlm_release_lockspace(const char *name, dlm_lshandle_t ls,
- int force);
-extern dlm_lshandle_t dlm_open_lockspace(const char *name);
-extern int dlm_close_lockspace(dlm_lshandle_t ls);
-extern int dlm_ls_get_fd(dlm_lshandle_t ls);
-extern dlm_lshandle_t dlm_new_lockspace(const char *name, mode_t mode,
- uint32_t flags);
-
-
-/*
- * Using your own lockspace
- *
- * dlm_ls_lock()
- * dlm_ls_lockx()
- * dlm_ls_unlock()
- * dlm_ls_lock_wait()
- * dlm_ls_unlock_wait()
- * dlm_ls_deadlock_cancel()
- * dlm_ls_purge()
- */
-
-extern int dlm_ls_lock(dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- void *range); /* unused */
-
-extern int dlm_ls_lockx(dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- uint64_t *xid,
- uint64_t *timeout);
-
-extern int dlm_ls_unlock(dlm_lshandle_t lockspace,
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb,
- void *astarg);
-
-extern int dlm_ls_lock_wait(dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- void *bastarg,
- void (*bastaddr) (void *bastarg),
- void *range); /* unused */
-
-extern int dlm_ls_unlock_wait(dlm_lshandle_t lockspace,
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb);
-
-extern int dlm_ls_deadlock_cancel(dlm_lshandle_t ls,
- uint32_t lkid,
- uint32_t flags);
-
-extern int dlm_ls_purge(dlm_lshandle_t lockspace,
- int nodeid,
- int pid);
-
-
-/*
- * For threaded applications
- *
- * dlm_pthread_init()
- * dlm_ls_pthread_init() - call this before any locking operations and the ASTs
- * will be delivered in their own thread.
- * dlm_pthread_cleanup() - call the cleanup routine at application exit
- * (optional) or, if the locking functions are in a
- * shared library that is to be unloaded.
- *
- * dlm_close/release_lockspace() will tidy the threads for a non-default
- * lockspace
- */
-
-#ifdef _REENTRANT
-extern int dlm_pthread_init(void);
-extern int dlm_ls_pthread_init(dlm_lshandle_t lockspace);
-extern int dlm_pthread_cleanup(void);
-#endif
-
-
-/*
- * Lock modes
- */
-
-#define LKM_NLMODE 0 /* null lock */
-#define LKM_CRMODE 1 /* concurrent read */
-#define LKM_CWMODE 2 /* concurrent write */
-#define LKM_PRMODE 3 /* protected read */
-#define LKM_PWMODE 4 /* protected write */
-#define LKM_EXMODE 5 /* exclusive */
-
-
-/*
- * Locking flags - these match the ones in dlm.h
- */
-
-#define LKF_NOQUEUE 0x00000001
-#define LKF_CANCEL 0x00000002
-#define LKF_CONVERT 0x00000004
-#define LKF_VALBLK 0x00000008
-#define LKF_QUECVT 0x00000010
-#define LKF_IVVALBLK 0x00000020
-#define LKF_CONVDEADLK 0x00000040
-#define LKF_PERSISTENT 0x00000080
-#define LKF_NODLCKWT 0x00000100
-#define LKF_NODLCKBLK 0x00000200
-#define LKF_EXPEDITE 0x00000400
-#define LKF_NOQUEUEBAST 0x00000800
-#define LKF_HEADQUE 0x00001000
-#define LKF_NOORDER 0x00002000
-#define LKF_ORPHAN 0x00004000
-#define LKF_ALTPR 0x00008000
-#define LKF_ALTCW 0x00010000
-#define LKF_FORCEUNLOCK 0x00020000
-#define LKF_TIMEOUT 0x00040000
-#define LKF_WAIT 0x80000000 /* Userspace only, for sync API calls */
-
-/*
- * Extra return codes used by the DLM
- */
-
-#define ECANCEL 0x10001
-#define EUNLOCK 0x10002
-#define EINPROG 0x10003 /* lock operation is in progress */
-
-#endif
-
diff --git a/dlm/libdlm/libdlm.pc.in b/dlm/libdlm/libdlm.pc.in
deleted file mode 100644
index afd3a34..0000000
--- a/dlm/libdlm/libdlm.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: libdlm
-Version: @VERSION@
-Description: Cluster Distributed Lock Manager library
-Requires:
-Libs: -L${libdir} -ldlm -lpthread
-Cflags: -I${includedir}
diff --git a/dlm/libdlm/libdlm_internal.h b/dlm/libdlm/libdlm_internal.h
deleted file mode 100644
index c8b270e..0000000
--- a/dlm/libdlm/libdlm_internal.h
+++ /dev/null
@@ -1,9 +0,0 @@
-
-/* Needed before we include the kernel libdlm header */
-#define __user
-typedef uint8_t __u8;
-typedef uint16_t __u16;
-typedef uint32_t __u32;
-#define BUILDING_LIBDLM
-
-
diff --git a/dlm/libdlm/libdlm_lt.pc.in b/dlm/libdlm/libdlm_lt.pc.in
deleted file mode 100644
index d116715..0000000
--- a/dlm/libdlm/libdlm_lt.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: libdlm_lt
-Version: @VERSION@
-Description: Cluster Distributed Lock Manager non-threaded library
-Requires:
-Libs: -L${libdir} -ldlm_lt
-Cflags: -I${includedir}
diff --git a/dlm/libdlmcontrol/Makefile b/dlm/libdlmcontrol/Makefile
deleted file mode 100644
index e2c320c..0000000
--- a/dlm/libdlmcontrol/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-TARGET= libdlmcontrol
-
-OBJS= main.o
-
-SOMINOR=1
-
-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$(S)/../../group/dlm_controld
-CFLAGS += -I${incdir}
-CFLAGS += -I$(KERNEL_SRC)/include
diff --git a/dlm/libdlmcontrol/libdlmcontrol.h b/dlm/libdlmcontrol/libdlmcontrol.h
deleted file mode 100644
index 64a3814..0000000
--- a/dlm/libdlmcontrol/libdlmcontrol.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef _LIBDLMCONTROL_H_
-#define _LIBDLMCONTROL_H_
-
-#define DLMC_DUMP_SIZE (1024 * 1024)
-
-#define DLMC_NF_MEMBER 0x00000001 /* node is member in cg */
-#define DLMC_NF_START 0x00000002 /* start message recvd for cg */
-#define DLMC_NF_DISALLOWED 0x00000004 /* node disallowed in cg */
-#define DLMC_NF_CHECK_FENCING 0x00000008
-#define DLMC_NF_CHECK_QUORUM 0x00000010
-#define DLMC_NF_CHECK_FS 0x00000020
-
-struct dlmc_node {
- int nodeid;
- uint32_t flags;
- uint32_t added_seq;
- uint32_t removed_seq;
- int failed_reason;
-};
-
-struct dlmc_change {
- int member_count;
- int joined_count;
- int remove_count;
- int failed_count;
- int wait_condition; /* 0 no, 1 fencing, 2 quorum, 3 fs */
- int wait_messages; /* 0 no, 1 yes */
- uint32_t seq;
- uint32_t combined_seq;
-};
-
-#define DLMC_LF_JOINING 0x00000001
-#define DLMC_LF_LEAVING 0x00000002
-#define DLMC_LF_KERNEL_STOPPED 0x00000004
-#define DLMC_LF_FS_REGISTERED 0x00000008
-#define DLMC_LF_NEED_PLOCKS 0x00000010
-#define DLMC_LF_SAVE_PLOCKS 0x00000020
-
-struct dlmc_lockspace {
- int group_mode;
- struct dlmc_change cg_prev; /* completed change (started_change) */
- struct dlmc_change cg_next; /* in-progress change (changes list) */
- uint32_t flags;
- uint32_t global_id;
- char name[DLM_LOCKSPACE_LEN+1];
-};
-
-/* dlmc_lockspace_nodes() types
-
- MEMBERS: members in completed (prev) change,
- zero if there's no completed (prev) change
- NEXT: members in in-progress (next) change,
- zero if there's no in-progress (next) change
- ALL: NEXT + nonmembers if there's an in-progress (next) change,
- MEMBERS + nonmembers if there's no in-progress (next) change, but
- there is a completed (prev) change
- nonmembers if there's no in-progress (next) or completed (prev)
- change (possible?)
-
- dlmc_node_info() returns info for in-progress (next) change, if one exists,
- otherwise it returns info for completed (prev) change.
-*/
-
-#define DLMC_NODES_ALL 1
-#define DLMC_NODES_MEMBERS 2
-#define DLMC_NODES_NEXT 3
-
-int dlmc_dump_debug(char *buf);
-int dlmc_dump_log_plock(char *buf);
-int dlmc_dump_plocks(char *name, char *buf);
-int dlmc_lockspace_info(char *lsname, struct dlmc_lockspace *ls);
-int dlmc_node_info(char *lsname, int nodeid, struct dlmc_node *node);
-int dlmc_lockspaces(int max, int *count, struct dlmc_lockspace *lss);
-int dlmc_lockspace_nodes(char *lsname, int type, int max, int *count,
- struct dlmc_node *nodes);
-
-#define DLMC_RESULT_REGISTER 1
-#define DLMC_RESULT_NOTIFIED 2
-
-int dlmc_fs_connect(void);
-void dlmc_fs_disconnect(int fd);
-int dlmc_fs_register(int fd, char *name);
-int dlmc_fs_unregister(int fd, char *name);
-int dlmc_fs_notified(int fd, char *name, int nodeid);
-int dlmc_fs_result(int fd, char *name, int *type, int *nodeid, int *result);
-
-int dlmc_deadlock_check(char *name);
-
-#endif
-
diff --git a/dlm/libdlmcontrol/libdlmcontrol.pc.in b/dlm/libdlmcontrol/libdlmcontrol.pc.in
deleted file mode 100644
index db7dfa9..0000000
--- a/dlm/libdlmcontrol/libdlmcontrol.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: libdlmcontrol
-Version: @VERSION@
-Description: DLM control library
-Requires:
-Libs: -L${libdir} -ldlmcontrol
-Cflags: -I${includedir}
diff --git a/dlm/libdlmcontrol/main.c b/dlm/libdlmcontrol/main.c
deleted file mode 100644
index 5a203a1..0000000
--- a/dlm/libdlmcontrol/main.c
+++ /dev/null
@@ -1,419 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <linux/dlmconstants.h>
-#include "dlm_controld.h"
-#include "libdlmcontrol.h"
-
-static int do_read(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- while (off < count) {
- rv = read(fd, (char *)buf + off, count - off);
- if (rv == 0)
- return -1;
- if (rv == -1 && errno == EINTR)
- continue;
- if (rv == -1)
- return -1;
- off += rv;
- }
- return 0;
-}
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, (char *)buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0) {
- return rv;
- }
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-static int do_connect(const char *sock_path)
-{
- struct sockaddr_un sun;
- socklen_t addrlen;
- int rv, fd;
-
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (fd < 0)
- goto out;
-
- memset(&sun, 0, sizeof(sun));
- sun.sun_family = AF_UNIX;
- strcpy(&sun.sun_path[1], sock_path);
- addrlen = sizeof(sa_family_t) + strlen(sun.sun_path+1) + 1;
-
- rv = connect(fd, (struct sockaddr *) &sun, addrlen);
- if (rv < 0) {
- close(fd);
- fd = rv;
- }
- out:
- return fd;
-}
-
-static void init_header(struct dlmc_header *h, int cmd, char *name,
- int extra_len)
-{
- memset(h, 0, sizeof(struct dlmc_header));
-
- h->magic = DLMC_MAGIC;
- h->version = DLMC_VERSION;
- h->len = sizeof(struct dlmc_header) + extra_len;
- h->command = cmd;
-
- if (name)
- strncpy(h->name, name, DLM_LOCKSPACE_LEN);
-}
-
-static int do_dump(int cmd, char *name, char *buf)
-{
- struct dlmc_header h, *rh;
- char *reply;
- int reply_len;
- int fd, rv;
-
- init_header(&h, cmd, name, 0);
-
- reply_len = sizeof(struct dlmc_header) + DLMC_DUMP_SIZE;
- reply = malloc(reply_len);
- if (!reply) {
- rv = -1;
- goto out;
- }
- memset(reply, 0, reply_len);
-
- fd = do_connect(DLMC_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- /* won't always get back the full reply_len */
- do_read(fd, reply, reply_len);
-
- rh = (struct dlmc_header *)reply;
- rv = rh->data;
- if (rv < 0)
- goto out_close;
-
- memcpy(buf, (char *)reply + sizeof(struct dlmc_header),
- DLMC_DUMP_SIZE);
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int dlmc_dump_debug(char *buf)
-{
- return do_dump(DLMC_CMD_DUMP_DEBUG, NULL, buf);
-}
-
-int dlmc_dump_log_plock(char *buf)
-{
- return do_dump(DLMC_CMD_DUMP_LOG_PLOCK, NULL, buf);
-}
-
-int dlmc_dump_plocks(char *name, char *buf)
-{
- return do_dump(DLMC_CMD_DUMP_PLOCKS, name, buf);
-}
-
-int dlmc_node_info(char *name, int nodeid, struct dlmc_node *node)
-{
- struct dlmc_header h, *rh;
- char reply[sizeof(struct dlmc_header) + sizeof(struct dlmc_node)];
- int fd, rv;
-
- init_header(&h, DLMC_CMD_NODE_INFO, name, 0);
- h.data = nodeid;
-
- memset(reply, 0, sizeof(reply));
-
- fd = do_connect(DLMC_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- rv = do_read(fd, reply, sizeof(reply));
- if (rv < 0)
- goto out_close;
-
- rh = (struct dlmc_header *)reply;
- rv = rh->data;
- if (rv < 0)
- goto out_close;
-
- memcpy(node, (char *)reply + sizeof(struct dlmc_header),
- sizeof(struct dlmc_node));
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int dlmc_lockspace_info(char *name, struct dlmc_lockspace *lockspace)
-{
- struct dlmc_header h, *rh;
- char reply[sizeof(struct dlmc_header) + sizeof(struct dlmc_lockspace)];
- int fd, rv;
-
- init_header(&h, DLMC_CMD_LOCKSPACE_INFO, name, 0);
-
- memset(reply, 0, sizeof(reply));
-
- fd = do_connect(DLMC_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- rv = do_read(fd, reply, sizeof(reply));
- if (rv < 0)
- goto out_close;
-
- rh = (struct dlmc_header *)reply;
- rv = rh->data;
- if (rv < 0)
- goto out_close;
-
- memcpy(lockspace, (char *)reply + sizeof(struct dlmc_header),
- sizeof(struct dlmc_lockspace));
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int dlmc_lockspaces(int max, int *count, struct dlmc_lockspace *lss)
-{
- struct dlmc_header h, *rh;
- char *reply;
- int reply_len;
- int fd, rv, result, ls_count;
-
- init_header(&h, DLMC_CMD_LOCKSPACES, NULL, 0);
- h.data = max;
-
- reply_len = sizeof(struct dlmc_header) +
- (max * sizeof(struct dlmc_lockspace));
- reply = malloc(reply_len);
- if (!reply) {
- rv = -1;
- goto out;
- }
- memset(reply, 0, reply_len);
-
- fd = do_connect(DLMC_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- /* won't usually get back the full reply_len */
- do_read(fd, reply, reply_len);
-
- rh = (struct dlmc_header *)reply;
- result = rh->data;
- if (result < 0 && result != -E2BIG) {
- rv = result;
- goto out_close;
- }
-
- if (result == -E2BIG) {
- *count = -E2BIG;
- ls_count = max;
- } else {
- *count = result;
- ls_count = result;
- }
- rv = 0;
-
- memcpy(lss, (char *)reply + sizeof(struct dlmc_header),
- ls_count * sizeof(struct dlmc_lockspace));
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int dlmc_lockspace_nodes(char *name, int type, int max, int *count,
- struct dlmc_node *nodes)
-{
- struct dlmc_header h, *rh;
- char *reply;
- int reply_len;
- int fd, rv, result, node_count;
-
- init_header(&h, DLMC_CMD_LOCKSPACE_NODES, name, 0);
- h.option = type;
- h.data = max;
-
- reply_len = sizeof(struct dlmc_header) +
- (max * sizeof(struct dlmc_node));
- reply = malloc(reply_len);
- if (!reply) {
- rv = -1;
- goto out;
- }
- memset(reply, 0, reply_len);
-
- fd = do_connect(DLMC_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- /* won't usually get back the full reply_len */
- do_read(fd, reply, reply_len);
-
- rh = (struct dlmc_header *)reply;
- result = rh->data;
- if (result < 0 && result != -E2BIG) {
- rv = result;
- goto out_close;
- }
-
- if (result == -E2BIG) {
- *count = -E2BIG;
- node_count = max;
- } else {
- *count = result;
- node_count = result;
- }
- rv = 0;
-
- memcpy(nodes, (char *)reply + sizeof(struct dlmc_header),
- node_count * sizeof(struct dlmc_node));
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int dlmc_fs_connect(void)
-{
- return do_connect(DLMC_SOCK_PATH);
-}
-
-void dlmc_fs_disconnect(int fd)
-{
- close(fd);
-}
-
-int dlmc_fs_register(int fd, char *name)
-{
- struct dlmc_header h;
-
- init_header(&h, DLMC_CMD_FS_REGISTER, name, 0);
-
- return do_write(fd, &h, sizeof(h));
-}
-
-int dlmc_fs_unregister(int fd, char *name)
-{
- struct dlmc_header h;
-
- init_header(&h, DLMC_CMD_FS_UNREGISTER, name, 0);
-
- return do_write(fd, &h, sizeof(h));
-}
-
-int dlmc_fs_notified(int fd, char *name, int nodeid)
-{
- struct dlmc_header h;
-
- init_header(&h, DLMC_CMD_FS_NOTIFIED, name, 0);
- h.data = nodeid;
-
- return do_write(fd, &h, sizeof(h));
-}
-
-int dlmc_fs_result(int fd, char *name, int *type, int *nodeid, int *result)
-{
- struct dlmc_header h;
- int rv;
-
- rv = do_read(fd, &h, sizeof(h));
- if (rv < 0)
- goto out;
-
- strncpy(name, h.name, DLM_LOCKSPACE_LEN);
- *nodeid = h.option;
- *result = h.data;
-
- switch (h.command) {
- case DLMC_CMD_FS_REGISTER:
- *type = DLMC_RESULT_REGISTER;
- break;
- case DLMC_CMD_FS_NOTIFIED:
- *type = DLMC_RESULT_NOTIFIED;
- break;
- default:
- *type = 0;
- }
- out:
- return rv;
-}
-
-int dlmc_deadlock_check(char *name)
-{
- struct dlmc_header h;
- int fd, rv;
-
- init_header(&h, DLMC_CMD_DEADLOCK_CHECK, name, 0);
-
- fd = do_connect(DLMC_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- close(fd);
- out:
- return rv;
-}
-
diff --git a/dlm/man/Makefile b/dlm/man/Makefile
deleted file mode 100644
index 7cc2886..0000000
--- a/dlm/man/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-MANTARGET= \
- dlm_cleanup.3 \
- dlm_close_lockspace.3 \
- dlm_create_lockspace.3 \
- dlm_dispatch.3 \
- dlm_get_fd.3 \
- dlm_lock.3 \
- dlm_lock_wait.3 \
- dlm_ls_lock.3 \
- dlm_ls_lockx.3 \
- dlm_ls_lock_wait.3 \
- dlm_ls_pthread_init.3 \
- dlm_ls_unlock.3 \
- dlm_ls_unlock_wait.3 \
- dlm_new_lockspace.3 \
- dlm_open_lockspace.3 \
- dlm_pthread_init.3 \
- dlm_release_lockspace.3 \
- dlm_unlock.3 \
- dlm_unlock_wait.3 \
- libdlm.3 \
- dlm_tool.8
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-all:
-
-clean:
diff --git a/dlm/man/dlm_cleanup.3 b/dlm/man/dlm_cleanup.3
deleted file mode 100644
index db4a9cf..0000000
--- a/dlm/man/dlm_cleanup.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/libdlm.3
diff --git a/dlm/man/dlm_close_lockspace.3 b/dlm/man/dlm_close_lockspace.3
deleted file mode 100644
index e5db408..0000000
--- a/dlm/man/dlm_close_lockspace.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_create_lockspace.3
diff --git a/dlm/man/dlm_create_lockspace.3 b/dlm/man/dlm_create_lockspace.3
deleted file mode 100644
index 3879e85..0000000
--- a/dlm/man/dlm_create_lockspace.3
+++ /dev/null
@@ -1,94 +0,0 @@
-.TH DLM_CREATE_LOCKSPACE 3 "July 5, 2007" "libdlm functions"
-.SH NAME
-dlm_create_lockspace, dlm_open_lockspace, dlm_close_lockspace, dlm_release_lockspace \- manipulate DLM lockspaces
-.SH SYNOPSIS
-.nf
- #include <libdlm.h>
-
-dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode);
-dlm_lshandle_t dlm_new_lockspace(const char *name, mode_t mode,
- uint32_t flags);
-dlm_lshandle_t dlm_open_lockspace(const char *name);
-int dlm_close_lockspace(dlm_lshandle_t ls);
-int dlm_release_lockspace(const char *name, dlm_lshandle_t ls,
- int force);
-
-.fi
-.SH DESCRIPTION
-The DLM allows locks to be partitioned into "lockspaces", and these can be manipulated by userspace calls. It is possible (though not recommended) for an application to have multiple lockspaces open at one time.
-
-Many of the DLM calls work on the "default" lockspace, which should be fine for most users. The calls with _ls_ in them allow you to isolate your application from all others running in the cluster. Remember, lockspaces are a cluster-wide resource, so if you create a lockspace called "myls" it will share locks with a lockspace called "myls" on all nodes. These calls allow users to create & remove lockspaces, and users to connect to existing lockspace to store their locks there.
-.PP
-.SS
-dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode);
-.br
-This creates a lockspace called <name> and the mode of the file user to access it will be <mode> (subject to umask as usual). The lockspace must not already exist on this node, if it does -1 will be returned and errno will be set to EEXIST. If you really want to use this lockspace you can then use dlm_open_lockspace() below. The name is the name of a misc device that will be created in /dev/misc.
-.br
-On success a handle to the lockspace is returned, which can be used to pass into subsequent dlm_ls_lock/unlock calls. Make no assumptions as to the content of this handle as it's content may change in future.
-.br
-The caller must have CAP_SYSADMIN privileges to do this operation.
-.PP
-Return codes:
-0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following:
-.nf
-EINVAL An invalid parameter was passed to the call
-ENOMEM A (kernel) memory allocation failed
-EEXIST The lockspace already exists
-EPERM Process does not have capability to create lockspaces
-ENOSYS A fatal error occurred initializing the DLM
-Any error returned by the open() system call
-.fi
-.SS
-int dlm_new_lockspace(const char *name, mode_t mode, uint32_t flags)
-.PP
-Performs the same function as
-.B dlm_create_lockspace()
-above, but passes some creation flags to the call that affect the lockspace being created. Currently supported flags are:
-.nf
-DLM_LSFL_NODIR the lockspace should not use a resource directory
-DLM_LSFL_TIMEWARN the dlm should emit warnings over netlink when locks
- have been waiting too long; required for deadlock
- detection
-.fi
-.SS
-int dlm_release_lockspace(const char *name, dlm_lshandle_t ls, int force)
-.PP
-Deletes a lockspace. If the lockspace still has active locks then -1 will be returned and errno set to EBUSY. Both the lockspace handle /and/ the name must be specified. This call also closes the lockspace and stops the thread associated with the lockspace, if any.
-.br
-Note that other nodes in the cluster may still have locks open on this lockspace. This call only removes the lockspace from the current node. If the force flag is set then the lockspace will be removed even if another user on this node has active locks in it. Existing users will NOT be notified if you do this, so be careful.
-.br
-The caller must have CAP_SYSADMIN privileges to do this operation.
-.PP
-Return codes:
-0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following:
-.nf
-EINVAL An invalid parameter was passed to the call
-EPERM Process does not have capability to release lockspaces
-EBUSY The lockspace could not be freed because it still
- contains locks and force was not set.
-.fi
-
-.SS
-dlm_lshandle_t dlm_open_lockspace(const char *name)
-.PP
-Opens an already existing lockspace and returns a handle to it.
-.PP
-Return codes:
-0 is returned if the call completed successfully. If not, -1 is returned and errno is set to an error returned by the open() system call
-.SS
-int dlm_close_lockspace(dlm_lshandle_t ls)
-.br
-Close the lockspace. Any locks held by this process will be freed. If a thread is associated with this lockspace then it will be stopped.
-.PP
-Return codes:
-0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following:
-.nf
-EINVAL lockspace was not a valid lockspace handle
-.fi
-
-
-.SH SEE ALSO
-
-.BR libdlm (3),
-.BR dlm_unlock (3),
-.BR dlm_lock (3),
diff --git a/dlm/man/dlm_dispatch.3 b/dlm/man/dlm_dispatch.3
deleted file mode 100644
index db4a9cf..0000000
--- a/dlm/man/dlm_dispatch.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/libdlm.3
diff --git a/dlm/man/dlm_get_fd.3 b/dlm/man/dlm_get_fd.3
deleted file mode 100644
index db4a9cf..0000000
--- a/dlm/man/dlm_get_fd.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/libdlm.3
diff --git a/dlm/man/dlm_lock.3 b/dlm/man/dlm_lock.3
deleted file mode 100644
index 3c5f8b5..0000000
--- a/dlm/man/dlm_lock.3
+++ /dev/null
@@ -1,239 +0,0 @@
-.TH DLM_LOCK 3 "July 5, 2007" "libdlm functions"
-.SH NAME
-dlm_lock \- acquire or convert a DLM lock
-.SH SYNOPSIS
-.nf
- #include <libdlm.h>
-
-int dlm_lock(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- void *range); /* unused */
-
-int dlm_lock_wait(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- void *bastarg,
- void (*bastaddr) (void *bastarg),
- void *range); /* unused */
-
-int dlm_ls_lock(dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- void *range); /* unused */
-
-int dlm_ls_lock_wait(dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unusued */
- void *bastarg,
- void (*bastaddr) (void *bastarg),
- void *range); /* unused */
-
-int dlm_ls_lockx(dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- uint64_t *xid,
- uint64_t *timeout);
-
-
-
-.fi
-.SH DESCRIPTION
-dlm_lock and its variants acquire and convert locks in the DLM.
-.PP
-dlm_lock() operations are asynchronous. If the call to dlm_lock returns an error then the operation has failed and the AST routine will not be called. If dlm_lock returns 0 it is still possible that the lock operation will fail. The AST routine will be called when the locking is complete or has failed and the status is returned in the lksb.
-.B dlm_lock_wait()
-will wait until the lock operation has completed and returns the final completion status.
-.B dlm_ls_lock()
-is the same as
-.B dlm_lock()
-but takes a lockspace argument. This lockspace must have been previously opened by
-.B dlm_lockspace_open() or
-.B dlm_lockspace_create().
-.PP
-For conversion operations the name and namelen are ignored and the lock ID in the LKSB is used to identify the lock to be converted.
-.PP
-If a lock value block is specified then in general, a grant or a conversion to an equal-level or higher-level lock mode reads the lock value from the resource into the caller's lock value block. When a lock conversion from EX or PW to an equal-level or lower-level lock mode occurs, the contents of the caller's lock value block are written into the resource. If the LVB is invalidated the lksb.sb_flags member will be set to DLM_SBF_VALNOTVALID. Lock values blocks are always 32 bytes long.
-.PP
-If the AST routines or parameter are passed to a conversion operation then they will overwrite those values that were passed to a previous dlm_lock call.
-.PP
-.B mode
-Lock mode to acquire or convert to.
-.nf
- LKM_NLMODE NULL Lock
- LKM_CRMODE Concurrent read
- LKM_CWMODE Concurrent write
- LKM_PRMODE Protected read
- LKM_PWMODE Protected write
- LKM_EXMODE Exclusive
-.fi
-.PP
-.B flags
-Affect the operation of the lock call:
-.nf
- LKF_NOQUEUE Don't queue the lock. If it cannot be granted return
- -EAGAIN
- LKF_CONVERT Convert an existing lock
- LKF_VALBLK Lock has a value block
- LKF_QUECVT Put conversion to the back of the queue
- LKF_EXPEDITE Grant a NL lock immediately regardless of other locks
- on the conversion queue
- LKF_PERSISTENT Specifies a lock that will not be unlocked when the
- process exits; it will become an orphan lock.
- LKF_CONVDEADLK Enable internal conversion deadlock resolution where
- the lock's granted mode may be set to NL and
- DLM_SBF_DEMOTED is returned in lksb.sb_flags.
- LKF_NODLCKWT Do not consider this lock when trying to detect
- deadlock conditions.
- LKF_NODLCKBLK Not implemented
- LKF_NOQUEUEBAST Send blocking ASTs even for NOQUEUE operations
- LKF_HEADQUE Add locks to the head of the convert or waiting queue
- LKF_NOORDER Avoid the VMS rules on grant order
- LKF_ALTPR If the requested mode can't be granted (generally CW),
- try to grant in PR and return DLM_SBF_ALTMODE.
- LKF_ALTCW If the requested mode can't be granted (generally PR),
- try to grant in CW and return DLM_SBF_ALTMODE.
- LKF_TIMEOUT The lock will time out per the timeout arg.
-
-.fi
-.PP
-.B lksb
-Lock Status block
-.br
-This structure contains the returned lock ID, the actual
-status of the lock operation (all lock ops are asynchronous)
-and the value block if LKF_VALBLK is set.
-.PP
-.B name
-.br
-Name of the lock. Can be binary, max 64 bytes. Ignored for lock
-conversions. (Should be a string to work with debugging tools.)
-.PP
-.B namelen
-.br
-Length of the above name. Ignored for lock conversions.
-.PP
-.B parent
-.br
-ID of parent lock or NULL if this is a top-level lock. This is currently unused.
-.PP
-.B ast
-.br
-Address of AST routine to be called when the lock operation
-completes. The final completion status of the lock will be
-in the lksb. the AST routine must not be NULL.
-.PP
-.B astargs
-.br
-Argument to pass to the AST routine (most people pass the lksb
-in here but it can be anything you like.)
-.PP
-.B bast
-.br
-Blocking AST routine. address of a function to call if this
-lock is blocking another. The function will be called with
-astargs.
-.PP
-.B range
-.br
-This is unused.
-.PP
-.B xid
-.br
-Optional transaction ID for deadlock detection.
-.PP
-.B timeout
-.br
-Timeout in centiseconds. If it takes longer than this to acquire the lock
-(usually because it is already blocked by another lock), then the AST
-will trigger with ETIMEDOUT as the status. If the lock operation is a conversion
-then the lock will remain at its current status. If this is a new lock then
-the lock will not exist and any LKB in the lksb will be invalid. This is
-ignored without the LKF_TIMEOUT flag.
-.PP
-.SS Return values
-0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following:
-.PP
-.nf
-EINVAL An invalid parameter was passed to the call (eg bad lock
- mode or flag)
-ENOMEM A (kernel) memory allocation failed
-EAGAIN LKF_NOQUEUE was requested and the lock could not be
- granted
-EBUSY The lock is currently being locked or converted
-EFAULT The userland buffer could not be read/written by the
- kernel (this indicates a library problem)
-EDEADLOCK The lock operation is causing a deadlock and has been
- cancelled. If this was a conversion then the lock is
- reverted to its previously granted state. If it was a
- new lock then it has not been granted. (NB Only
- conversion deadlocks are currently detected)
-.PP
-If an error is returned in the AST, then lksb.sb_status is set to the one of the above values instead of zero.
-.SS Structures
-.nf
-struct dlm_lksb {
- int sb_status; /* Final status of lock operation */
- uint32_t sb_lkid; /* ID of lock. Returned from dlm_lock()
- on first use. Used as input to
- dlm_lock() for a conversion operation */
- char sb_flags; /* Completion flags, see above */
- char sb_lvbptr; /* Optional pointer to lock value block */
-};
-
-.fi
-.SH EXAMPLE
-.nf
-int status;
-struct dlm_lksb lksb;
-
-status = dlm_lock_wait(LKM_EXMODE,
- &lksb,
- LKF_NOQUEUE,
- "MyLock",
- strlen("MyLock"),
- 0, // Parent,
- NULL, // bast arg
- NULL, // bast routine,
- NULL); // Range
-
-if (status == 0)
- dlm_unlock_wait(lksb.sb_lkid, 0, &lksb);
-
-.fi
-
-.SH SEE ALSO
-
-.BR libdlm (3),
-.BR dlm_unlock (3),
-.BR dlm_open_lockspace (3),
-.BR dlm_create_lockspace (3),
-.BR dlm_close_lockspace (3),
-.BR dlm_release_lockspace (3)
diff --git a/dlm/man/dlm_lock_wait.3 b/dlm/man/dlm_lock_wait.3
deleted file mode 100644
index a99225c..0000000
--- a/dlm/man/dlm_lock_wait.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_lock.3
diff --git a/dlm/man/dlm_ls_lock.3 b/dlm/man/dlm_ls_lock.3
deleted file mode 100644
index a99225c..0000000
--- a/dlm/man/dlm_ls_lock.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_lock.3
diff --git a/dlm/man/dlm_ls_lock_wait.3 b/dlm/man/dlm_ls_lock_wait.3
deleted file mode 100644
index a99225c..0000000
--- a/dlm/man/dlm_ls_lock_wait.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_lock.3
diff --git a/dlm/man/dlm_ls_lockx.3 b/dlm/man/dlm_ls_lockx.3
deleted file mode 100644
index a99225c..0000000
--- a/dlm/man/dlm_ls_lockx.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_lock.3
diff --git a/dlm/man/dlm_ls_pthread_init.3 b/dlm/man/dlm_ls_pthread_init.3
deleted file mode 100644
index db4a9cf..0000000
--- a/dlm/man/dlm_ls_pthread_init.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/libdlm.3
diff --git a/dlm/man/dlm_ls_unlock.3 b/dlm/man/dlm_ls_unlock.3
deleted file mode 100644
index 91babd2..0000000
--- a/dlm/man/dlm_ls_unlock.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_unlock.3
diff --git a/dlm/man/dlm_ls_unlock_wait.3 b/dlm/man/dlm_ls_unlock_wait.3
deleted file mode 100644
index 91babd2..0000000
--- a/dlm/man/dlm_ls_unlock_wait.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_unlock.3
diff --git a/dlm/man/dlm_new_lockspace.3 b/dlm/man/dlm_new_lockspace.3
deleted file mode 100644
index e5db408..0000000
--- a/dlm/man/dlm_new_lockspace.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_create_lockspace.3
diff --git a/dlm/man/dlm_open_lockspace.3 b/dlm/man/dlm_open_lockspace.3
deleted file mode 100644
index e5db408..0000000
--- a/dlm/man/dlm_open_lockspace.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_create_lockspace.3
diff --git a/dlm/man/dlm_pthread_init.3 b/dlm/man/dlm_pthread_init.3
deleted file mode 100644
index db4a9cf..0000000
--- a/dlm/man/dlm_pthread_init.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/libdlm.3
diff --git a/dlm/man/dlm_release_lockspace.3 b/dlm/man/dlm_release_lockspace.3
deleted file mode 100644
index e5db408..0000000
--- a/dlm/man/dlm_release_lockspace.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_create_lockspace.3
diff --git a/dlm/man/dlm_tool.8 b/dlm/man/dlm_tool.8
deleted file mode 100644
index df9aa64..0000000
--- a/dlm/man/dlm_tool.8
+++ /dev/null
@@ -1,98 +0,0 @@
-.TH DLM_TOOL 8 2009-01-20 cluster cluster
-
-.SH NAME
-dlm_tool \- a utility for the dlm and dlm_controld daemon
-
-.SH SYNOPSIS
-.B dlm_tool
-[COMMAND] [OPTIONS]
-[
-.I name
-]
-
-.SH DESCRIPTION
-.TP
-.B ls
-Display internal dlm_controld state about lockspaces.
-
-.TP
-.B dump
-Dump dlm_controld debug buffer.
-
-.TP
-.B log_plock
-Dump dlm_controld plock debug buffer.
-
-.TP
-.BI plocks " name"
-Dump posix locks from dlm_controld for the lockspace.
-
-.TP
-.BI lockdump " name"
-Minimal display of locks from the lockspace.
-
-.TP
-.BI lockdebug " name"
-Extended display of locks from the lockspace.
-
-.TP
-.BI join " name"
-Join a lockspace.
-
-.TP
-.BI leave " name"
-Leave a lockspace.
-
-.TP
-.BI deadlock_check " name"
-Start a deadlock detection cycle for the lockspace.
-
-.SH OPTIONS
-.TP
-.B \-n
-Show all node information in ls.
-
-.TP
-.BI \-d " num"
-Resource directory enabled (1) or disabled (0) during join. Default 0.
-
-.TP
-.BI \-e " num"
-Exclusive create off/on (0/1) in join. Default 0.
-
-.TP
-.BI \-f " num"
-FS memory allocation off/on (0/1) in join. Default 0.
-
-.TP
-.BI \-m " mode"
-The permission mode (in octal) of the lockspace device created by join.
-Default 0600.
-
-.TP
-.B \-M
-Dump MSTCPY locks in addition to locks held by local processes.
-
-.TP
-.B \-s
-Summary following lockdebug output (experimental, format may change).
-
-.TP
-.B \-v
-Verbose lockdebug output.
-
-.TP
-.B \-w
-Wide lockdebug output.
-
-.TP
-.B \-h
-Print a help message describing available options, then exit.
-
-.TP
-.B \-V
-Print program version information, then exit.
-
-.SH SEE ALSO
-.BR dlm_controld (8)
-
diff --git a/dlm/man/dlm_unlock.3 b/dlm/man/dlm_unlock.3
deleted file mode 100644
index 9023139..0000000
--- a/dlm/man/dlm_unlock.3
+++ /dev/null
@@ -1,94 +0,0 @@
-.TH DLM_UNLOCK 3 "July 5, 2007" "libdlm functions"
-.SH NAME
-dlm_unlock \- unlock a DLM lock
-.SH SYNOPSIS
-.nf
-#include <libdlm.h>
-
-int dlm_unlock(uint32_t lkid,
- uint32_t flags, struct dlm_lksb *lksb, void *astarg);
-
-int dlm_unlock_wait(uint32_t lkid,
- uint32_t flags, struct dlm_lksb *lksb);
-
-.fi
-.SH DESCRIPTION
-.B dlm_unlock()
-unlocks a lock previously acquired by dlm_lock and its variants.
-.PP
-Unless
-.B dlm_unlock_wait()
-is used unlocks are also asynchronous. The AST routine is called when the resource is successfully unlocked (see below).
-.PP
-.B lkid
-Lock ID as returned in the lksb
-.PP
-.B flags
-flags affecting the unlock operation:
-.nf
- LKF_CANCEL Cancel a pending lock or conversion.
- This returns the lock to it's previously
- granted mode (in case of a conversion) or
- unlocks it (in case of a waiting lock).
- LKF_IVVALBLK Invalidate value block
- LKF_FORCEUNLOCK Unlock the lock even if it's waiting.
-.fi
-.PP
-.B lksb
-LKSB to return status and value block information.
-.PP
-.B astarg
-New parameter to be passed to the completion AST.
-The completion AST routine is the
-last completion AST routine specified in a dlm_lock call.
-If dlm_lock_wait() was the last routine to issue a lock,
-dlm_unlock_wait() must be used to release the lock. If dlm_lock()
-was the last routine to issue a lock then either dlm_unlock()
-or dlm_unlock_wait() may be called.
-.PP
-
-.SS Return values
-0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following:
-.PP
-.nf
-EINVAL An invalid parameter was passed to the call (eg bad
- lock mode or flag)
-EINPROGRESS The lock is already being unlocked
-EBUSY The lock is currently being locked or converted
-ENOTEMPTY An attempt to made to unlock a parent lock that still has
- child locks.
-ECANCEL A lock conversion was successfully cancelled
-EUNLOCK An unlock operation completed successfully
- (sb_status only)
-EFAULT The userland buffer could not be read/written by the
- kernel
-.fi
-If an error is returned in the AST, then lksb.sb_status is set to the one of the above numbers instead of zero.
-.SH EXAMPLE
-.nf
-int status;
-struct dlm_lksb lksb;
-
-status = dlm_lock_wait(LKM_EXMODE,
- &lksb,
- LKF_NOQUEUE,
- "MyLock",
- strlen("MyLock"),
- 0, // Parent,
- NULL, // bast arg
- NULL, // bast routine,
- NULL); // Range
-
-if (status == 0)
- dlm_unlock_wait(lksb.sb_lkid, 0, &lksb);
-
-.fi
-
-.SH SEE ALSO
-
-.BR libdlm (3),
-.BR dlm_lock (3),
-.BR dlm_open_lockspace (3),
-.BR dlm_create_lockspace (3),
-.BR dlm_close_lockspace (3),
-.BR dlm_release_lockspace (3)
diff --git a/dlm/man/dlm_unlock_wait.3 b/dlm/man/dlm_unlock_wait.3
deleted file mode 100644
index 91babd2..0000000
--- a/dlm/man/dlm_unlock_wait.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_unlock.3
diff --git a/dlm/man/libdlm.3 b/dlm/man/libdlm.3
deleted file mode 100644
index a020560..0000000
--- a/dlm/man/libdlm.3
+++ /dev/null
@@ -1,105 +0,0 @@
-.TH LIBDLM 3 "July 5, 2007" "libdlm functions"
-.SH NAME
-libdlm \- dlm_get_fd, dlm_dispatch, dlm_pthread_init, dlm_ls_pthread_init, dlm_cleanup
-.SH SYNOPSIS
-.nf
-#include <libdlm.h>
-.nf
-int dlm_pthread_init();
-int dlm_ls_pthread_init(dlm_lshandle_t lockspace);
-int dlm_pthread_cleanup();
-int dlm_get_fd(void);
-int dlm_dispatch(int fd);
-
-link with -ldlm
-.fi
-.SH DESCRIPTION
-libdlm provides the programmatic userspace interface to the Distributed Lock manager. It provides all the calls you need to manipulate locks & lockspaces
-.br
-libdlm can be used in pthread or non-pthread applications. For pthread applications simply call the following function before doing any lock operations. If you're using pthreads, remember to define _REENTRANT at the top of the program or using -D_REENTRANT on the compile line.
-.br
-pthreads is the normal way of using the DLM. This way you simply initialize the DLM's thread and all the AST routines will be delivered in that thread. You just call the dlm_lock() etc routines in the main line of your program.
-.br
-If you don't want to use pthreads or you want to handle the dlm callback ASTs yourself then you can get an FD handle to the DLM device and call
-.B dlm_dispatch()
-on it whenever it becomes active. That was ASTs will be delivered in the context of the thread/process that called
-.B dlm_dispatch().
-
-
-.SS int dlm_pthread_init()
-.br
-Creates a thread to receive all lock ASTs. The AST callback function for lock operations will be called in the context of this thread. If there is a potential for local resource access conflicts you must provide your own pthread-based locking in the AST routine.
-.PP
-.SS int dlm_ls_pthread_init(dlm_lshandle_t lockspace)
-.br
-As dlm_pthread_init but initializes a thread for the specified lockspace.
-.PP
-.SS int dlm_pthread_cleanup()
-.br
-Cleans up the default lockspace threads after use. Normally you don't need to call this, but if the locking code is in a dynamically loadable shared library this will probably be necessary.
-.br
-For non-pthread based applications the DLM provides a file descriptor that the program can feed into poll/select. If activity is detected on that FD then a dispatch function should be called:
-.PP
-.SS int dlm_get_fd()
-Returns a file-descriptor for the DLM suitable for passing in to poll() or select().
-.PP
-.SS int dlm_dispatch(int fd)
-.br
-Reads from the DLM and calls any AST routines that may be needed. This routine runs in the context of the caller so no extra locking is needed to protect local resources.
-.PP
-
-
-.SH libdlm_lt
-There also exists a "light" version of the libdlm library called libdlm_lt. This is provided for those applications that do not want to use pthread functions. If you use this library it is important that your application is NOT compiled with -D_REENTRANT or linked with libpthread.
-
-.SH EXAMPLES
-
-Create a lockspace and start a thread to deliver its callbacks:
-.nf
-dlm_lshandle_t ls;
-
-ls = dlm_create_lockspace("myLS", 0660);
-dlm_ls_pthread_init(ls);
-
- ...
-
-status = dlm_ls_lock(ls,
- ... );
-
-
-.fi
-.PP
- Using poll(2) to wait for and dispatch ASTs
-.nf
-
-
-static int poll_for_ast(dlm_lshandle_t ls)
-{
- struct pollfd pfd;
-
- pfd.fd = dlm_ls_get_fd(ls);
- pfd.events = POLLIN;
- while (!ast_called)
- {
- if (poll(&pfd, 1, 0) < 0)
- {
- perror("poll");
- return -1;
- }
- dlm_dispatch(dlm_ls_get_fd(ls));
- }
- ast_called = 0;
- return 0;
-}
-.fi
-
-
-.SH SEE ALSO
-
-.BR libdlm (3),
-.BR dlm_lock (3),
-.BR dlm_unlock (3),
-.BR dlm_open_lockspace (3),
-.BR dlm_create_lockspace (3),
-.BR dlm_close_lockspace (3),
-.BR dlm_release_lockspace (3)
diff --git a/dlm/tests/Makefile b/dlm/tests/Makefile
deleted file mode 100644
index 28685d2..0000000
--- a/dlm/tests/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS=usertest
diff --git a/dlm/tests/usertest/Makefile b/dlm/tests/usertest/Makefile
deleted file mode 100644
index 5e070f7..0000000
--- a/dlm/tests/usertest/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-TARGETS= dlmtest asttest lstest pingtest lvb \
- dlmtest2 flood alternate-lvb joinleave threads
-
-all: depends ${TARGETS}
-
-include ../../../make/defines.mk
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-
-CFLAGS += -D_REENTRANT
-CFLAGS += -I${dlmincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${dlmlibdir} -ldlm -lpthread
-LDFLAGS += -L${libdir}
-
-depends:
- $(MAKE) -C ../../libdlm all
-
-%: %.o
- $(CC) -o $@ $^ $(LDFLAGS)
-
-clean: generalclean
diff --git a/dlm/tests/usertest/alternate-lvb.c b/dlm/tests/usertest/alternate-lvb.c
deleted file mode 100644
index 80c3ef6..0000000
--- a/dlm/tests/usertest/alternate-lvb.c
+++ /dev/null
@@ -1,165 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/time.h>
-#include <syslog.h>
-#include <asm/types.h>
-#include <sys/socket.h>
-#include <sys/poll.h>
-#include <sys/un.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/errno.h>
-
-#include "libdlm.h"
-
-#define die(fmt, args...) \
-do \
-{ \
- fprintf(stderr, "%s: ", prog_name); \
- fprintf(stderr, fmt, ##args); \
- exit(EXIT_FAILURE); \
-} \
-while (0)
-
-static char *prog_name;
-static dlm_lshandle_t *dh;
-static int verbose;
-
-static struct dlm_lksb lksb;
-static char lvb[32];
-
-int main(int argc, char *argv[])
-{
- unsigned long long offset;
- unsigned long long num, last_num = 0;
- unsigned int id, clients, sleeptime = 0;
- unsigned long long skip = 0;
- char *name;
- int rv;
-
- prog_name = argv[0];
- verbose = 0;
-
- if (argc < 5)
- die("name offset id clients [sleep]\n");
-
- name = argv[1];
- offset = atoll(argv[2]);
- id = atoi(argv[3]);
- clients = atoi(argv[4]);
-
- if (argc > 5)
- sleeptime = atoi(argv[5]);
-
- printf("Joining \"alternate\" lockspace...\n");
-
- dh = dlm_create_lockspace("alternate", 0600);
- if (!dh) {
- printf("dlm_create_lockspace error %p %d\n",dh, errno);
- return -ENOTCONN;
- }
-
- rv = dlm_ls_pthread_init(dh);
- if (rv < 0) {
- printf("dlm_ls_pthread_init error %d %d\n", rv, errno);
- dlm_release_lockspace("alternate", dh, 1);
- return rv;
- }
-
- memset(&lksb, 0, sizeof(lksb));
- memset(&lvb, 0, sizeof(lvb));
- lksb.sb_lvbptr = lvb;
-
- if (verbose)
- printf("request NL\n");
-
- rv = dlm_ls_lock_wait(dh, LKM_NLMODE, &lksb, LKF_VALBLK,
- name, strlen(name), 0, NULL, NULL, NULL);
-
- while (1) {
- if (verbose)
- printf("convert NL->PR\n");
-
- rv = dlm_ls_lock_wait(dh, LKM_PRMODE, &lksb,
- LKF_VALBLK | LKF_CONVERT,
- name, strlen(name),
- 0, NULL, NULL, NULL);
- if (rv)
- printf("lock1 error: %d %d\n", rv, lksb.sb_status);
-
- memcpy(&num, &lvb, sizeof(num));
-
- if (verbose)
- printf("read lvb %llu\n", num);
-
- /* it's our turn */
- if (num % clients == id) {
- if (last_num && last_num + clients != num + 1)
- die("bad: num %llu last_num %llu\n",
- num, last_num);
-
- if (verbose)
- printf("convert PR->EX\n");
-
- rv = dlm_ls_lock_wait(dh, LKM_EXMODE, &lksb,
- LKF_VALBLK | LKF_CONVERT,
- name, strlen(name),
- 0, NULL, NULL, NULL);
- if (rv)
- printf("lock2 error: %d %d\n", rv,
- lksb.sb_status);
-
- memcpy(&num, &lvb, sizeof(num));
- if (num % clients != id)
- die("bad2: num %llu\n", num);
-
- num++;
-
- memcpy(&lvb, &num, sizeof(num));
- printf("%llu %llu\n", num, skip);
-
- if (verbose)
- printf("convert EX->NL\n");
-
- rv = dlm_ls_lock_wait(dh, LKM_NLMODE, &lksb,
- LKF_VALBLK | LKF_CONVERT,
- name, strlen(name),
- 0, NULL, NULL, NULL);
- if (rv)
- printf("lock3 error: %d %d\n", rv,
- lksb.sb_status);
-
- last_num = num;
- skip = 0;
- } else {
- skip++;
-
- if (verbose)
- printf("convert PR->NL, skip %llu\n", skip);
-
- rv = dlm_ls_lock_wait(dh, LKM_NLMODE, &lksb,
- LKF_VALBLK | LKF_CONVERT,
- name, strlen(name),
- 0, NULL, NULL, NULL);
- if (rv)
- printf("lock4 error: %d %d\n", rv,
- lksb.sb_status);
- }
-
- if (sleeptime)
- usleep(sleeptime);
- }
-
- dlm_ls_unlock_wait(dh, lksb.sb_lkid, 0, &lksb);
- dlm_release_lockspace("alternate", dh, 1);
-
- exit(EXIT_SUCCESS);
-}
-
diff --git a/dlm/tests/usertest/asttest.c b/dlm/tests/usertest/asttest.c
deleted file mode 100644
index 224df4c..0000000
--- a/dlm/tests/usertest/asttest.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* Test program for userland DLM interface w/ AST */
-/* NOTE: This is not much of a program and it fails in all
- sorts of ways. But it /does/ illustrate the full dlm_lock
- call and ASTs. It doesn /not/ show how you should use the
- FD parts fo the API!
-*/
-
-#ifdef _REENTRANT
-#include <pthread.h>
-#endif
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/poll.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <unistd.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "libdlm.h"
-
-static struct dlm_lksb lksb;
-static int use_threads = 0;
-static int quiet = 0;
-
-/* Used by the pthread test */
-static pthread_cond_t cond;
-static pthread_mutex_t mutex;
-
-/* Used by the poll() test */
-static int ast_called = 0;
-
-static int modetonum(char *modestr)
-{
- int mode = LKM_EXMODE;
-
- if (strncasecmp(modestr, "NL", 2) == 0) mode = LKM_NLMODE;
- if (strncasecmp(modestr, "CR", 2) == 0) mode = LKM_CRMODE;
- if (strncasecmp(modestr, "CW", 2) == 0) mode = LKM_CWMODE;
- if (strncasecmp(modestr, "PR", 2) == 0) mode = LKM_PRMODE;
- if (strncasecmp(modestr, "PW", 2) == 0) mode = LKM_PWMODE;
- if (strncasecmp(modestr, "EX", 2) == 0) mode = LKM_EXMODE;
-
- return mode;
-}
-
-static const char *numtomode(int mode)
-{
- switch (mode)
- {
- case LKM_NLMODE: return "NL";
- case LKM_CRMODE: return "CR";
- case LKM_CWMODE: return "CW";
- case LKM_PRMODE: return "PR";
- case LKM_PWMODE: return "PW";
- case LKM_EXMODE: return "EX";
- default: return "??";
- }
-}
-
-static void usage(char *prog, FILE *file)
-{
- fprintf(file, "Usage:\n");
- fprintf(file, "%s [mcnpquhV] <lockname>\n", prog);
- fprintf(file, "\n");
- fprintf(file, " -V Show version of dlmtest\n");
- fprintf(file, " -h Show this help information\n");
- fprintf(file, " -m <mode> lock mode (default EX)\n");
- fprintf(file, " -c <mode> mode to convert to (default none)\n");
- fprintf(file, " -n don't block\n");
- fprintf(file, " -p Use pthreads\n");
- fprintf(file, " -u Don't unlock\n");
- fprintf(file, " -C Crash after lock\n");
- fprintf(file, " -q Quiet\n");
- fprintf(file, " -u Don't unlock explicitly\n");
- fprintf(file, "\n");
-
-}
-
-static void ast_routine(void *arg)
-{
- struct dlm_lksb *alksb = arg;
-
- if (!quiet)
- printf("ast called, status = %d, lkid=%x\n", alksb->sb_status, alksb->sb_lkid);
-
- /* Wake the main thread */
- if (use_threads)
- {
- pthread_mutex_lock(&mutex);
- pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
- }
- else
- {
- ast_called = 1;
- }
-}
-
-static void bast_routine(void *arg)
-{
- struct dlm_lksb *blksb = arg;
-
- if (!quiet)
- printf("\nblocking ast called, status = %d, lkid=%x\n", blksb->sb_status, blksb->sb_lkid);
-}
-
-/* Using poll(2) to wait for and dispatch ASTs */
-static int poll_for_ast(void)
-{
- struct pollfd pfd;
-
- pfd.fd = dlm_get_fd();
- pfd.events = POLLIN;
- while (!ast_called)
- {
- if (poll(&pfd, 1, 0) < 0)
- {
- perror("poll");
- return -1;
- }
- dlm_dispatch(pfd.fd);
- }
- ast_called = 0;
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- const char *resource = "LOCK-NAME";
- int flags = 0;
- int delay = 0;
- int status;
- int mode = LKM_EXMODE;
- int convmode = -1;
- int do_unlock = 1;
- int do_crash = 0;
- signed char opt;
-
- /* Deal with command-line arguments */
- opterr = 0;
- optind = 0;
- while ((opt=getopt(argc,argv,"?m:nqupc:d:CvV")) != EOF)
- {
- switch(opt)
- {
- case 'h':
- usage(argv[0], stdout);
- exit(0);
-
- case '?':
- usage(argv[0], stderr);
- exit(0);
-
- case 'm':
- mode = modetonum(optarg);
- break;
-
- case 'c':
- convmode = modetonum(optarg);
- break;
-
- case 'p':
- use_threads++;
- break;
-
- case 'n':
- flags |= LKF_NOQUEUE;
- break;
-
- case 'q':
- quiet = 1;
- break;
-
- case 'u':
- do_unlock = 0;
- break;
-
- case 'C':
- do_crash = 1;
- break;
-
- case 'd':
- delay = atoi(optarg);
- break;
-
- case 'V':
- printf("\nasttest version 0.1\n\n");
- exit(1);
- break;
- }
- }
-
- if (argv[optind])
- resource = argv[optind];
-
- if (!quiet)
- fprintf(stderr, "locking %s %s %s...", resource,
- numtomode(mode),
- (flags&LKF_NOQUEUE?"(NOQUEUE)":""));
-
- fflush(stderr);
-
- if (use_threads)
- {
- pthread_cond_init(&cond, NULL);
- pthread_mutex_init(&mutex, NULL);
- pthread_mutex_lock(&mutex);
-
- dlm_pthread_init();
- }
-
- status = dlm_lock(mode,
- &lksb,
- flags,
- resource,
- strlen(resource),
- 0, // Parent,
- ast_routine,
- &lksb,
- bast_routine,
- NULL); // Range
- if (status == -1)
- {
- if (!quiet) fprintf(stderr, "\n");
- perror("lock");
-
- return -1;
- }
- printf("(lkid=%x)", lksb.sb_lkid);
-
- if (do_crash)
- *(int *)0 = 0xdeadbeef;
-
- /* Wait */
- if (use_threads)
- pthread_cond_wait(&cond, &mutex);
- else
- poll_for_ast();
-
- if (delay)
- sleep(delay);
-
- if (!quiet)
- {
- fprintf(stderr, "unlocking %s...", resource);
- fflush(stderr);
- }
-
- if (do_unlock)
- {
- status = dlm_unlock(lksb.sb_lkid,
- 0, // flags
- &lksb,
- &lksb); // AST args
- if (status == -1)
- {
- if (!quiet) fprintf(stderr, "\n");
- perror("unlock");
- return -1;
- }
-
- /* Wait */
- if (use_threads)
- pthread_cond_wait(&cond, &mutex);
- else
- poll_for_ast();
- }
-
- return 0;
-}
-
diff --git a/dlm/tests/usertest/dlmtest.c b/dlm/tests/usertest/dlmtest.c
deleted file mode 100644
index dc54c2e..0000000
--- a/dlm/tests/usertest/dlmtest.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/* Test program for userland DLM interface */
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <unistd.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "libdlm.h"
-
-static int modetonum(char *modestr)
-{
- int mode = LKM_EXMODE;
-
- if (strncasecmp(modestr, "NL", 2) == 0) mode = LKM_NLMODE;
- if (strncasecmp(modestr, "CR", 2) == 0) mode = LKM_CRMODE;
- if (strncasecmp(modestr, "CW", 2) == 0) mode = LKM_CWMODE;
- if (strncasecmp(modestr, "PR", 2) == 0) mode = LKM_PRMODE;
- if (strncasecmp(modestr, "PW", 2) == 0) mode = LKM_PWMODE;
- if (strncasecmp(modestr, "EX", 2) == 0) mode = LKM_EXMODE;
-
- return mode;
-}
-
-static const char *numtomode(int mode)
-{
- switch (mode)
- {
- case LKM_NLMODE: return "NL";
- case LKM_CRMODE: return "CR";
- case LKM_CWMODE: return "CW";
- case LKM_PRMODE: return "PR";
- case LKM_PWMODE: return "PW";
- case LKM_EXMODE: return "EX";
- default: return "??";
- }
-}
-
-static void usage(char *prog, FILE *file)
-{
- fprintf(file, "Usage:\n");
- fprintf(file, "%s [hmcnQpequdV] <lockname>\n", prog);
- fprintf(file, "\n");
- fprintf(file, " -V Show version of dlmtest\n");
- fprintf(file, " -h Show this help information\n");
- fprintf(file, " -m <mode> lock mode (default EX)\n");
- fprintf(file, " -c <mode> mode to convert to (default none)\n");
- fprintf(file, " -n don't block\n");
- fprintf(file, " -Q query the lock\n");
- fprintf(file, " -p Persistent lock\n");
- fprintf(file, " -e Expedite conversion\n");
- fprintf(file, " -q Quiet\n");
- fprintf(file, " -u Don't unlock explicitly\n");
- fprintf(file, " -d <secs> Time to hold the lock for\n");
- fprintf(file, "\n");
-
-}
-
-#ifdef QUERY
-static void query_ast_routine(void *arg)
-{
- struct dlm_lksb *lksb = arg;
- struct dlm_queryinfo *qi = (struct dlm_queryinfo *)lksb->sb_lvbptr;
- int i;
-
- qi->gqi_resinfo->rsi_name[qi->gqi_resinfo->rsi_length] = '\0';
- /* Dump resource info */
- printf("lockinfo: status = %d\n", lksb->sb_status);
- printf("lockinfo: resource = '%s'\n", qi->gqi_resinfo->rsi_name);
- printf("lockinfo: grantcount = %d\n", qi->gqi_resinfo->rsi_grantcount);
- printf("lockinfo: convcount = %d\n", qi->gqi_resinfo->rsi_convcount);
- printf("lockinfo: waitcount = %d\n", qi->gqi_resinfo->rsi_waitcount);
- printf("lockinfo: masternode = %d\n", qi->gqi_resinfo->rsi_masternode);
-
- /* Dump all the locks */
- for (i = 0; i < qi->gqi_lockcount; i++)
- {
- struct dlm_lockinfo *li = &qi->gqi_lockinfo[i];
-
- printf("lockinfo: lock: lkid = %x\n", li->lki_lkid);
- printf("lockinfo: lock: master lkid = %x\n", li->lki_mstlkid);
- printf("lockinfo: lock: parent lkid = %x\n", li->lki_parent);
- printf("lockinfo: lock: node = %d\n", li->lki_node);
- printf("lockinfo: lock: pid = %d\n", li->lki_ownpid);
- printf("lockinfo: lock: state = %d\n", li->lki_state);
- printf("lockinfo: lock: grmode = %d\n", li->lki_grmode);
- printf("lockinfo: lock: rqmode = %d\n", li->lki_rqmode);
- printf("\n");
- }
-
- if (qi->gqi_lockinfo)
- free(qi->gqi_lockinfo);
-}
-
-static struct dlm_queryinfo qinfo;
-static struct dlm_resinfo resinfo;
-#define MAX_QUERY_LOCKS 10
-
-
-static int query_lock(int lockid)
-{
- int status;
-struct dlm_lksb tmplksb;
- lksb.sb_lkid = lockid;
- qinfo.gqi_resinfo = &resinfo;
- qinfo.gqi_lockinfo = malloc(sizeof(struct dlm_lockinfo) * MAX_QUERY_LOCKS);
- qinfo.gqi_locksize = MAX_QUERY_LOCKS;
- lksb.sb_lvbptr = (char *)&qinfo;
-
- status = dlm_query(&tmplksb,
- DLM_QUERY_QUEUE_ALL | DLM_QUERY_LOCKS_ALL,
- &qinfo,
- query_ast_routine,
- &tmplksb);
- if (status)
- perror("Query failed");
- else
- sleep(1); /* Just to allow the result to come back. There isn't
- a synchronous version of this call */
- return status;
-}
-#endif
-
-
-int main(int argc, char *argv[])
-{
- const char *resource = "LOCK-NAME";
- int flags = 0;
- int status;
- int delay = 5;
- int mode = LKM_EXMODE;
- int convmode = -1;
- int lockid;
- int quiet = 0;
- int do_unlock = 1;
- int do_query = 0;
- int do_expedite = 0;
- signed char opt;
-
- /* Deal with command-line arguments */
- opterr = 0;
- optind = 0;
- while ((opt=getopt(argc,argv,"?m:nquQepd:c:vV")) != EOF)
- {
- switch(opt)
- {
- case 'h':
- usage(argv[0], stdout);
- exit(0);
-
- case '?':
- usage(argv[0], stderr);
- exit(0);
-
- case 'm':
- mode = modetonum(optarg);
- break;
-
- case 'c':
- convmode = modetonum(optarg);
- break;
-
- case 'e':
- do_expedite = 1;
- break;
-
- case 'p':
- flags |= LKF_PERSISTENT;
- break;
-
- case 'n':
- flags |= LKF_NOQUEUE;
- break;
-
- case 'd':
- delay = atoi(optarg);
- break;
-
- case 'q':
- quiet = 1;
- break;
-
- case 'u':
- do_unlock = 0;
- break;
-
- case 'Q':
- do_query = 1;
- break;
-
- case 'V':
- printf("\ndlmtest version 0.3\n\n");
- exit(1);
- break;
- }
- }
-
- if (argv[optind])
- resource = argv[optind];
-
- if (!quiet)
- fprintf(stderr, "locking %s %s %s...", resource,
- numtomode(mode),
- (flags&LKF_NOQUEUE?"(NOQUEUE)":""));
-
- fflush(stderr);
-
- status = lock_resource(resource, mode, flags, &lockid);
- if (status == -1)
- {
- if (!quiet) fprintf(stderr, "\n");
- perror("lock");
-
- return -1;
- }
- if (lockid == 0)
- {
- fprintf(stderr, "error: got lockid of zero\n");
- return 0;
- }
-
- if (!quiet) fprintf(stderr, "done (lkid = %x)\n", lockid);
-
- if (!do_unlock) return 0;
-
-#ifdef QUERY
- if (do_query) query_lock(lockid);
-#endif
-
- sleep(delay);
-
- if (convmode != -1)
- {
- if (do_expedite)
- flags |= LKF_EXPEDITE;
-
- if (!quiet)
- {
- fprintf(stderr, "converting %s to %s...", resource, numtomode(convmode));
- fflush(stderr);
- }
-
- status = lock_resource(resource, convmode, flags | LKF_CONVERT, &lockid);
- if (status == -1)
- {
- if (!quiet) fprintf(stderr, "\n");
- perror("convert");
- return -1;
- }
- if (!quiet) fprintf(stderr, "done\n");
- }
-
- sleep(delay);
-
- if (!quiet)
- {
- fprintf(stderr, "unlocking %s...", resource);
- fflush(stderr);
- }
-
- status = unlock_resource(lockid);
- if (status == -1)
- {
- if (!quiet) fprintf(stderr, "\n");
- perror("unlock");
- return -1;
- }
-
- if (!quiet) fprintf(stderr, "done\n");
-
- /* For some reason, calling this IMMEDIATELY before
- exitting, causes a thread hang. either don't call it at
- all or do something in afterwards before calling exit
- */
- dlm_pthread_cleanup();
- return 0;
-}
-
diff --git a/dlm/tests/usertest/dlmtest2.c b/dlm/tests/usertest/dlmtest2.c
deleted file mode 100644
index 4444132..0000000
--- a/dlm/tests/usertest/dlmtest2.c
+++ /dev/null
@@ -1,1454 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-#include <signal.h>
-#include <syslog.h>
-#include <sys/time.h>
-#include <asm/types.h>
-#include <sys/socket.h>
-#include <sys/poll.h>
-#include <sys/un.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/errno.h>
-
-#include "libdlm.h"
-
-#define MAX_CLIENTS 4
-#define MAX_LOCKS 16
-#define MAX_RESOURCES 16
-
-static dlm_lshandle_t *dh;
-static int libdlm_fd;
-static int timewarn = 0;
-static uint64_t timeout = 0;
-static int noqueue = 1;
-static int persistent = 0;
-static int ignore_bast = 0;
-static int quiet = 1;
-static int verbose = 0;
-static int bast_cb;
-static int maxn = MAX_LOCKS;
-static int maxr = MAX_RESOURCES;
-static int iterations;
-static int minhold = 0;
-static int stress_stop = 0;
-static int stress_delay = 0;
-static int stress_lock_only = 0;
-static int openclose_ls = 0;
-static uint64_t our_xid;
-static char cmd[32];
-
-static unsigned int sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain, sts_other, sts_zero;
-static unsigned int bast_unlock, bast_skip;
-
-
-#define log_print(fmt, args...) \
-do { \
- if (!quiet) \
- printf(fmt , ##args); \
-} while (0)
-
-#define log_op(fmt, args...) \
-do { \
- if (!quiet) \
- printf(fmt , ##args); \
-} while (0)
-
-#define log_ast(fmt, args...) \
-do { \
- if (verbose) \
- printf(fmt , ##args); \
-} while (0)
-
-#define log_bast(fmt, args...) \
-do { \
- if (verbose > 1) \
- printf(fmt , ##args); \
-} while (0)
-
-#define log_verbose(fmt, args...) \
-do { \
- if (verbose > 2) \
- printf(fmt , ##args); \
-} while (0)
-
-struct client {
- int fd;
- char type[32];
-};
-
-static int client_size = MAX_CLIENTS;
-static struct client client[MAX_CLIENTS];
-static struct pollfd pollfd[MAX_CLIENTS];
-
-enum {
- Op_lock = 1,
- Op_unlock,
- Op_unlockf,
- Op_cancel,
-};
-
-struct lk {
- int id;
- int rqmode;
- int grmode;
- int wait_ast;
- int lastop;
- int last_status;
- int bast;
- int minhold;
- struct dlm_lksb lksb;
- struct timeval begin;
- struct timeval acquired;
-};
-
-struct lk *locks;
-
-static void unlock(int i);
-static void unlockf(int i);
-
-
-static int rand_int(int a, int b)
-{
- return a + (int) (((float)(b - a + 1)) * random() / (RAND_MAX+1.0));
-}
-
-static const char *status_str(int status)
-{
- static char sts_str[8];
-
- switch (status) {
- case 0:
- return "0 ";
- case EUNLOCK:
- return "EUNLOCK";
- case ECANCEL:
- return "ECANCEL";
- case EAGAIN:
- return "EAGAIN ";
- case EBUSY:
- return "EBUSY ";
- case ETIMEDOUT:
- return "ETIMEDO";
- case EDEADLK:
- return "EDEADLK";
- default:
- snprintf(sts_str, 8, "%8x", status);
- return sts_str;
- }
-}
-
-static const char *op_str(int op)
-{
- switch (op) {
- case Op_lock:
- return "lock";
- case Op_unlock:
- return "unlock";
- case Op_unlockf:
- return "unlockf";
- case Op_cancel:
- return "cancel";
- default:
- return "unknown";
- }
-}
-
-static struct lk *get_lock(int i)
-{
- if (i < 0)
- return NULL;
- if (i >= maxn)
- return NULL;
- return &locks[i];
-}
-
-static int all_unlocks_done(void)
-{
- struct lk *lk;
- int i;
-
- for (i = 0; i < maxn; i++) {
- lk = get_lock(i);
- if (lk->grmode == -1 && !lk->wait_ast)
- continue;
- return 0;
- }
- return 1;
-}
-
-static void dump(void)
-{
- struct timeval now;
- struct lk *lk;
- int i;
-
- gettimeofday(&now, NULL);
-
- for (i = 0; i < maxn; i++) {
- lk = get_lock(i);
- printf("x %2d lkid %08x gr %2d rq %2d wait_ast %d last op %s \t%s %us\n",
- i,
- lk->lksb.sb_lkid,
- lk->grmode,
- lk->rqmode,
- lk->wait_ast,
- op_str(lk->lastop),
- status_str(lk->last_status),
- lk->wait_ast ? (unsigned int)(now.tv_sec - lk->begin.tv_sec) : 0);
- }
-}
-
-static void bastfn(void *arg)
-{
- struct lk *lk = arg;
- lk->bast = 1;
- bast_cb = 1;
-}
-
-static void do_bast(struct lk *lk)
-{
- int skip = 0;
-
- if (lk->lastop == Op_unlock || lk->lastop == Op_unlockf) {
- skip = 1;
- }
- if (!lk->lksb.sb_lkid) {
- skip = 1;
- }
-
- if (skip) {
- bast_skip++;
- log_bast(" bast: skip %3d\t%x\n", lk->id, lk->lksb.sb_lkid);
- } else {
- bast_unlock++;
- log_bast(" bast: unlockf %3d\t%x\n", lk->id, lk->lksb.sb_lkid);
- unlockf(lk->id);
- }
- lk->bast = 0;
-}
-
-static void do_bast_unlocks(void)
-{
- struct lk *lk;
- int i;
-
- for (i = 0; i < maxn; i++) {
- lk = get_lock(i);
- if (lk->bast)
- do_bast(lk);
- }
- bast_cb = 0;
-}
-
-static void process_libdlm(void)
-{
- dlm_dispatch(libdlm_fd);
- if (bast_cb && !ignore_bast)
- do_bast_unlocks();
-}
-
-static void astfn(void *arg)
-{
- struct lk *lk = arg;
- int i = lk->id;
-
- if (!lk->wait_ast) {
- printf(" ast: %s %3d\t%x: !wait_ast gr %d rq %d last op %s %s\n",
- status_str(lk->lksb.sb_status), i, lk->lksb.sb_lkid,
- lk->grmode, lk->rqmode,
- op_str(lk->lastop), status_str(lk->last_status));
- }
-
- log_ast(" ast: %s %3d\t%x\n",
- status_str(lk->lksb.sb_status), i, lk->lksb.sb_lkid);
-
- lk->last_status = lk->lksb.sb_status;
-
- if (lk->lksb.sb_status == EUNLOCK) {
- sts_eunlock++;
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- lk->grmode = -1;
- lk->wait_ast = 0;
-
- } else if (lk->lksb.sb_status == ECANCEL) {
- sts_ecancel++;
- if (lk->grmode == -1) {
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- lk->wait_ast = 0;
- } else {
- if (lk->lastop != Op_unlock && lk->lastop != Op_unlockf)
- lk->wait_ast = 0;
- }
-
- } else if (lk->lksb.sb_status == ETIMEDOUT) {
- sts_etimedout++;
- if (lk->grmode == -1) {
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- lk->wait_ast = 0;
- } else {
- if (lk->lastop != Op_unlock && lk->lastop != Op_unlockf)
- lk->wait_ast = 0;
- }
-
- } else if (lk->lksb.sb_status == EDEADLK) {
- sts_edeadlk++;
- if (lk->grmode == -1) {
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- lk->wait_ast = 0;
- } else {
- if (lk->lastop != Op_unlock && lk->lastop != Op_unlockf)
- lk->wait_ast = 0;
- }
-
- } else if (lk->lksb.sb_status == EAGAIN) {
- sts_eagain++;
- if (lk->grmode == -1) {
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- lk->wait_ast = 0;
- } else {
- if (lk->lastop != Op_unlockf)
- lk->wait_ast = 0;
- }
-
- } else {
- if (lk->lksb.sb_status != 0) {
- sts_other++;
- printf("BAD ast: %d %3d\t%x: gr %d rq %d last op %s %s\n",
- lk->lksb.sb_status, i, lk->lksb.sb_lkid,
- lk->grmode, lk->rqmode, op_str(lk->lastop),
- status_str(lk->last_status));
- stress_stop = 1;
- return;
- }
-
- sts_zero++;
-
- if (lk->lastop != Op_unlockf)
- lk->wait_ast = 0;
-
- lk->grmode = lk->rqmode;
-
- if (minhold) {
- gettimeofday(&lk->acquired, NULL);
- lk->minhold = minhold;
- }
- }
-
- lk->rqmode = -1;
-}
-
-/* EBUSY from dlm_ls_lockx() is expected sometimes, e.g. lock, cancel, lock;
- the first lock is successful and the app gets the status back,
- and issues the second lock before the reply for the overlapping
- cancel (which did nothing) has been received in the dlm. */
-
-static void lock(int i, int mode)
-{
- char name[DLM_RESNAME_MAXLEN];
- struct lk *lk;
- int flags = 0;
- int rv;
- uint64_t *timeout_arg = NULL;
-
- lk = get_lock(i);
- if (!lk)
- return;
-
- if (noqueue)
- flags |= LKF_NOQUEUE;
- if (persistent)
- flags |= LKF_PERSISTENT;
- if (timeout) {
- flags |= LKF_TIMEOUT;
- timeout_arg = &timeout;
- }
-
- if (lk->lksb.sb_lkid)
- flags |= LKF_CONVERT;
-
- memset(name, 0, sizeof(name));
- snprintf(name, sizeof(name), "test%d", (i % maxr));
-
- log_verbose("lock: %d grmode %d rqmode %d flags %x lkid %x %s\n",
- i, lk->grmode, mode, flags, lk->lksb.sb_lkid, name);
-
-#if 0
- rv = dlm_ls_lock(dh, mode, &lk->lksb, flags, name, strlen(name), 0,
- astfn, (void *) lk, bastfn, NULL);
-#else
- rv = dlm_ls_lockx(dh, mode, &lk->lksb, flags, name, strlen(name), 0,
- astfn, (void *) lk, bastfn, &our_xid, timeout_arg);
-#endif
- if (!rv) {
- lk->wait_ast = 1;
- lk->rqmode = mode;
- gettimeofday(&lk->begin, NULL);
- } else if (rv == -1 && errno == EBUSY) {
- printf(" : lock %3d\t%x: EBUSY gr %d rq %d wait_ast %d\n",
- i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode, lk->wait_ast);
- } else {
- printf(" : lock %3d\t%x: errno %d rv %d gr %d rq %d wait_ast %d\n",
- i, lk->lksb.sb_lkid, errno, rv, lk->grmode, lk->rqmode, lk->wait_ast);
- stress_stop = 1;
- }
-
- log_verbose("lock: %d rv %d sb_lkid %x sb_status %x\n",
- i, rv, lk->lksb.sb_lkid, lk->lksb.sb_status);
-
- lk->lastop = Op_lock;
-}
-
-static void lock_sync(int i, int mode)
-{
- char name[DLM_RESNAME_MAXLEN];
- int flags = 0;
- int rv;
- struct lk *lk;
-
- lk = get_lock(i);
- if (!lk)
- return;
-
- if (noqueue)
- flags |= LKF_NOQUEUE;
- if (persistent)
- flags |= LKF_PERSISTENT;
-
- if (lk->lksb.sb_lkid)
- flags |= LKF_CONVERT;
-
- memset(name, 0, sizeof(name));
- snprintf(name, sizeof(name), "test%d", (i % maxr));
-
- log_verbose("lock_sync: %d rqmode %d flags %x lkid %x %s\n",
- i, mode, flags, lk->lksb.sb_lkid, name);
-
- rv = dlm_ls_lock_wait(dh, mode, &lk->lksb, flags,
- name, strlen(name), 0, (void *) lk,
- bastfn, NULL);
-
- log_verbose("lock_sync: %d rv %d sb_lkid %x sb_status %x\n",
- i, rv, lk->lksb.sb_lkid, lk->lksb.sb_status);
-
- if (!rv) {
- lk->grmode = mode;
- lk->rqmode = -1;
- } else if (rv == EAGAIN) {
- if (lk->grmode == -1)
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- } else {
- printf("unknown rv %d\n", rv);
- exit(-1);
- }
-}
-
-static void lock_all(int mode)
-{
- int i;
-
- for (i = 0; i < maxn; i++)
- lock(i, mode);
-}
-
-static const char *uflags(uint32_t flags)
-{
- if (flags == LKF_FORCEUNLOCK)
- return "FORCEUNLOCK";
- if (flags == LKF_CANCEL)
- return "CANCEL";
- return "0";
-}
-
-/* ENOENT is expected from dlm_ls_unlock() sometimes because we'll
- try to do an unlockf during an outstanding op that will free
- the lock itself */
-
-static void _unlock(int i, uint32_t flags)
-{
- struct lk *lk;
- uint32_t lkid;
- int rv;
-
- lk = get_lock(i);
- if (!lk)
- return;
-
- lkid = lk->lksb.sb_lkid;
- if (!lkid)
- return;
-
- log_verbose("unlock: %d lkid %x flags %x\n", i, lkid, flags);
-
- rv = dlm_ls_unlock(dh, lkid, flags, &lk->lksb, lk);
- if (!rv) {
- lk->wait_ast = 1;
- gettimeofday(&lk->begin, NULL);
- } else if (rv == -1 && errno == EBUSY) {
- printf(" : unlock %3d\t%x: EBUSY flags %s gr %d rq %d wait_ast %d\n",
- i, lk->lksb.sb_lkid, uflags(flags), lk->grmode, lk->rqmode, lk->wait_ast);
- } else if (rv == -1 && errno == ENOENT) {
- printf(" : unlock %3d\t%x: ENOENT flags %s gr %d rq %d wait_ast %d\n",
- i, lk->lksb.sb_lkid, uflags(flags), lk->grmode, lk->rqmode, lk->wait_ast);
- } else {
- printf(" : unlock %3d\t%x: errno %d flags %s rv %d gr %d rq %d wait_ast %d\n",
- i, lk->lksb.sb_lkid, errno, uflags(flags), rv, lk->grmode, lk->rqmode, lk->wait_ast);
- }
-}
-
-static void unlock(int i)
-{
- struct lk *lk = get_lock(i);
-
- if (minhold) {
- struct timeval now;
-
- if (lk->wait_ast)
- return;
-
- gettimeofday(&now, NULL);
- if (lk->acquired.tv_sec + lk->minhold > now.tv_sec) {
- printf(" : unlock %3d\t%x: gr %d rq %d held %u of %u s\n",
- i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode,
- (unsigned int)(now.tv_sec - lk->acquired.tv_sec), lk->minhold);
- return;
- }
- }
-
- _unlock(i, 0);
- lk->rqmode = -1;
- lk->lastop = Op_unlock;
-}
-
-static void unlockf(int i)
-{
- struct lk *lk = get_lock(i);
-
- if (minhold) {
- struct timeval now;
-
- if (lk->wait_ast)
- return;
-
- gettimeofday(&now, NULL);
- if (lk->acquired.tv_sec + lk->minhold > now.tv_sec) {
- printf(" : unlockf %3d\t%x: gr %d rq %d held %u of %u s\n",
- i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode,
- (unsigned int)(now.tv_sec - lk->acquired.tv_sec), lk->minhold);
- return;
- }
- }
-
- _unlock(i, LKF_FORCEUNLOCK);
- lk->rqmode = -1;
- lk->lastop = Op_unlockf;
-}
-
-static void cancel(int i)
-{
- struct lk *lk = get_lock(i);
- _unlock(i, LKF_CANCEL);
- lk->lastop = Op_cancel;
-}
-
-static void canceld(int i, uint32_t lkid)
-{
- int rv;
-
- rv = dlm_ls_deadlock_cancel(dh, lkid, 0);
-
- printf("canceld %x: %d %d\n", lkid, rv, errno);
-}
-
-static void unlock_sync(int i)
-{
- uint32_t lkid;
- int rv;
- struct lk *lk;
-
- lk = get_lock(i);
- if (!lk)
- return;
-
- lkid = lk->lksb.sb_lkid;
- if (!lkid) {
- log_print("unlock %d skip zero lkid\n", i);
- return;
- }
-
- log_verbose("unlock_sync: %d lkid %x\n", i, lkid);
-
- rv = dlm_ls_unlock_wait(dh, lkid, 0, &lk->lksb);
-
- log_verbose("unlock_sync: %d rv %d sb_status %x\n", i, rv,
- lk->lksb.sb_status);
-
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- lk->grmode = -1;
- lk->rqmode = -1;
-}
-
-static void unlock_all(void)
-{
- struct lk *lk;
- int i;
-
- for (i = 0; i < maxn; i++) {
- lk = get_lock(i);
- unlock(i);
- }
-}
-
-static void purge(int nodeid, int pid)
-{
- struct lk *lk;
- int i, rv;
-
- rv = dlm_ls_purge(dh, nodeid, pid);
- if (rv) {
- printf("dlm_ls_purge %d %d error %d\n", nodeid, pid, rv);
- return;
- }
-
- for (i = 0; i < maxn; i++) {
- lk = get_lock(i);
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- lk->grmode = -1;
- lk->wait_ast = 0;
- }
-}
-
-static void purgetest(int nodeid, int pid)
-{
- struct lk *lk;
- int i, mid = maxn / 2;
-
- printf("lock %d to %d\n", 0, mid-1);
- for (i = 0; i < mid; i++)
- lock(i, 3);
-
- while (1) {
- process_libdlm();
- for (i = 0; i < mid; i++) {
- lk = get_lock(i);
- if (!lk->wait_ast)
- continue;
- break;
- }
- if (i == mid)
- break;
- }
-
- for (i = mid; i < maxn; i++)
- lock(i, 3);
- for (i = 0; i < mid; i++)
- unlock(i);
- /* usleep(10000); */
- purge(nodeid, pid);
-}
-
-static void tstress_unlocks(void)
-{
- struct lk *lk;
- struct timeval now;
- int i;
-
- for (i = 0; i < maxn; i++) {
- lk = get_lock(i);
- if (!lk)
- continue;
- if (lk->wait_ast)
- continue;
- if (lk->grmode < 0)
- continue;
-
- /* if we've held the lock for minhold seconds, then unlock */
-
- gettimeofday(&now, NULL);
-
- if (now.tv_sec >= lk->acquired.tv_sec + minhold) {
- printf(" : unlock %3d\t%x: gr %d rq %d held %u of %u s\n",
- i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode,
- (unsigned int)(now.tv_sec - lk->acquired.tv_sec), minhold);
-
- _unlock(i, 0);
- lk->rqmode = -1;
- lk->lastop = Op_unlock;
- }
-
- }
-}
-
-static void tstress(int num)
-{
- unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops;
- int i;
- struct lk *lk;
-
- n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0;
- sts_eunlock = sts_ecancel = sts_etimedout = sts_edeadlk = sts_eagain = sts_other = sts_zero = 0;
- bast_unlock = bast_skip = 0;
-
- noqueue = 0;
- ignore_bast = 1;
- quiet = 0;
-
- if (!timeout)
- timeout = 4;
- if (!minhold)
- minhold = 5;
-
- while (!stress_stop) {
- if (stress_delay)
- usleep(stress_delay);
-
- process_libdlm();
-
- tstress_unlocks();
-
- if (++n == num) {
- if (all_unlocks_done())
- break;
- else
- continue;
- }
-
- i = rand_int(0, maxn-1);
- lk = get_lock(i);
- if (!lk)
- continue;
-
- if (lk->wait_ast || lk->grmode > -1)
- continue;
-
- lock(i, rand_int(0, 5));
- lock_ops++;
- printf("%8x: lock %3d\t%x\n", n, i, lk->lksb.sb_lkid);
- }
-
- printf("ops: skip %d lock %d unlock %d unlockf %d cancel %d\n",
- skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops);
- printf("bast: unlock %u skip %u\n", bast_unlock, bast_skip);
- printf("ast status: eunlock %d ecancel %d etimedout %d edeadlk %d eagain %d\n",
- sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain);
- printf("ast status: zero %d other %d\n", sts_zero, sts_other);
-}
-
-static void dstress(int num)
-{
- unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops;
- int i;
- struct lk *lk;
-
- n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0;
- sts_eunlock = sts_ecancel = sts_etimedout = sts_edeadlk = sts_eagain = sts_other = sts_zero = 0;
- bast_unlock = bast_skip = 0;
-
- noqueue = 0;
- ignore_bast = 1;
- quiet = 0;
-
- while (!stress_stop && n < num) {
-
- sleep(1);
-
- process_libdlm();
-
- if (n && !(n % 60))
- unlock_all();
- n++;
-
- i = rand_int(0, maxn-1);
- lk = get_lock(i);
- if (!lk)
- continue;
-
- if (lk->wait_ast || lk->grmode > -1) {
- printf("%8x: lock %3d\t%x: skip gr %d wait_ast %d\n",
- n, i, lk->lksb.sb_lkid, lk->grmode, lk->wait_ast);
- continue;
- }
-
- lock(i, rand_int(0, 5));
- lock_ops++;
- printf("%8x: lock %3d\t%x\n", n, i, lk->lksb.sb_lkid);
- }
-
- printf("ops: skip %d lock %d unlock %d unlockf %d cancel %d\n",
- skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops);
- printf("bast: unlock %u skip %u\n", bast_unlock, bast_skip);
- printf("ast status: eunlock %d ecancel %d etimedout %d edeadlk %d eagain %d\n",
- sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain);
- printf("ast status: zero %d other %d\n", sts_zero, sts_other);
-}
-
-static void stress(int num)
-{
- int i, o, op, max_op, skip;
- unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops;
- struct lk *lk;
-
- n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0;
- sts_eunlock = sts_ecancel = sts_etimedout = sts_edeadlk = sts_eagain = sts_other = sts_zero = 0;
- bast_unlock = bast_skip = 0;
-
- while (!stress_stop) {
- if (stress_delay)
- usleep(stress_delay);
-
- process_libdlm();
-
- if (++n == num)
- break;
-
- i = rand_int(0, maxn-1);
- lk = get_lock(i);
- if (!lk)
- continue;
-
- max_op = 5;
- if (stress_lock_only)
- max_op = 2;
-
- o = rand_int(0, max_op);
- switch (o) {
- case 0:
- case 1:
- case 2:
- op = Op_lock;
- break;
- case 3:
- op = Op_unlock;
- break;
- case 4:
- op = Op_unlockf;
- break;
- case 5:
- op = Op_cancel;
- break;
- default:
- op = 0;
- }
-
- skip = 0;
-
- switch (op) {
- case Op_lock:
- if (lk->wait_ast) {
- skip = 1;
- break;
- }
-
- noqueue = !!o;
- our_xid = n;
-
- lock(i, rand_int(0, 5));
- lock_ops++;
- log_op("%8x: lock %3d\t%x\n", n, i, lk->lksb.sb_lkid);
- break;
-
- case Op_unlock:
- if (lk->wait_ast) {
- skip = 1;
- break;
- }
- if (lk->lastop == Op_unlock || lk->lastop == Op_unlockf) {
- skip = 1;
- break;
- }
- if (!lk->lksb.sb_lkid) {
- skip = 1;
- break;
- }
-
- unlock(i);
- unlock_ops++;
- log_op("%8x: unlock %3d\t%x\n", n, i, lk->lksb.sb_lkid);
- break;
-
- case Op_unlockf:
- if (lk->lastop == Op_unlock || lk->lastop == Op_unlockf) {
- skip = 1;
- break;
- }
- if (!lk->lksb.sb_lkid) {
- skip = 1;
- break;
- }
-
- unlockf(i);
- unlockf_ops++;
- log_op("%8x: unlockf %3d\t%x\n", n, i, lk->lksb.sb_lkid);
- break;
-
- case Op_cancel:
- if (!lk->wait_ast) {
- skip = 1;
- break;
- }
- if (lk->lastop > Op_lock) {
- skip = 1;
- break;
- }
-
- cancel(i);
- cancel_ops++;
- log_op("%8x: cancel %3d\t%x\n", n, i, lk->lksb.sb_lkid);
- break;
- }
-
- if (skip)
- skips++;
- }
-
- printf("ops: skip %d lock %d unlock %d unlockf %d cancel %d\n",
- skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops);
- printf("bast: unlock %u skip %u\n", bast_unlock, bast_skip);
- printf("ast status: eunlock %d ecancel %d etimedout %d edeadlk %d eagain %d\n",
- sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain);
- printf("ast status: zero %d other %d\n", sts_zero, sts_other);
-}
-
-static int client_add(int fd, int *maxi)
-{
- int i;
-
- for (i = 0; i < client_size; i++) {
- if (client[i].fd == -1) {
- client[i].fd = fd;
- pollfd[i].fd = fd;
- pollfd[i].events = POLLIN;
- if (i > *maxi)
- *maxi = i;
- printf("client %d fd %d added\n", i, fd);
- return i;
- }
- }
- printf("client add failed\n");
- return -1;
-}
-
-static void client_dead(int ci)
-{
- printf("client %d fd %d dead\n", ci, client[ci].fd);
- close(client[ci].fd);
- client[ci].fd = -1;
- pollfd[ci].fd = -1;
-}
-
-static void client_init(void)
-{
- int i;
-
- for (i = 0; i < client_size; i++)
- client[i].fd = -1;
-}
-
-static void print_commands(void)
-{
- printf("Usage:\n");
- printf("max locks (maxn) is %d (x of 0 to %d)\n", maxn, maxn-1);
- printf("max resources (maxr) is %d, lock x used on resource (x %% maxr)\n", maxr);
- printf("EXIT - exit program after unlocking any held locks\n");
- printf("kill - exit program without unlocking any locks\n");
- printf("lock x mode - request/convert lock x\n");
- printf("unlock x - unlock lock x\n");
- printf("unlockf x - force unlock lock x\n");
- printf("cancel x - cancel lock x\n");
- printf("canceld x lkid - cancel lock x, return EDEADLK as status\n");
- printf("lock_sync x mode - synchronous version of lock\n");
- printf("unlock_sync x - synchronous version of unlock\n");
- printf("ex x - equivalent to: lock x 5\n");
- printf("pr x - equivalent to: lock x 3\n");
- printf("hold - for x in 0 to max, lock x 3\n");
- printf("release - for x in 0 to max, unlock x\n");
- printf("purge nodeid pid - purge orphan locks of process\n");
- printf("stress n - loop doing random lock/unlock/unlockf/cancel on all locks, n times\n");
- printf("tstress n - stress timeouts\n");
- printf("dstress n - stress deadlock\n");
- printf("timeout n - enable lock timeouts, set timeout to n seconds\n");
- printf("dump - show info for all locks\n");
- printf("minhold - set minimum number of seconds locks will be held\n");
- printf("ignore_bast - ignore all basts\n");
- printf("noqueue - toggle NOQUEUE flag for all requests\n");
- printf("persistent - toggle PERSISTENT flag for all requests\n");
- printf("quiet - toggle quiet flag\n");
- printf("verbose - toggle verbose flag\n");
- printf("settings - show settings\n");
-
- printf("\ncombined operations\n");
- printf("hold-kill - hold; kill\n");
- printf("release-kill - release; kill\n");
- printf("lock-kill x mode - lock; kill\n");
- printf("unlock-kill x - unlock; kill\n");
- printf("lock-cancel x mode msec - lock; sleep; cancel\n");
- printf("lock-unlockf x mode msec - lock; sleep; unlockf\n");
- printf("lock-cancel-kill x mode msec - lock; sleep; cancel; kill\n");
- printf("lock-unlockf-kill x mode msec - lock; sleep; unlockf; kill\n");
- printf("purgetest nodeid pid\n");
-}
-
-static void print_settings(void)
-{
- printf("timewarn %d\n", timewarn);
- printf("timeout %llu\n", (unsigned long long) timeout);
- printf("noqueue %d\n", noqueue);
- printf("persistent %d\n", persistent);
- printf("ignore_bast %d\n", ignore_bast);
- printf("quiet %d\n", quiet);
- printf("verbose %d\n", verbose);
- printf("maxn %d\n", maxn);
- printf("maxr %d\n", maxr);
- printf("iterations %d\n", iterations);
- printf("minhold %d\n", minhold);
- printf("stress_stop %d\n", stress_stop);
- printf("stress_delay %d\n", stress_delay);
- printf("stress_lock_only %d\n", stress_lock_only);
- printf("our_xid %llx\n", (unsigned long long)our_xid);
-}
-
-static void process_command(int *quit)
-{
- char inbuf[132];
- int x = 0, y = 0;
-
- fgets(inbuf, sizeof(inbuf), stdin);
- sscanf(inbuf, "%s %d %d", cmd, &x, &y);
-
- if (!strncmp(cmd, "EXIT", 4)) {
- *quit = 1;
- unlock_all();
- return;
- }
-
- if (!strncmp(cmd, "CLOSE", 5)) {
- *quit = 1;
- openclose_ls = 1;
- unlock_all();
- return;
- }
-
- if (!strncmp(cmd, "kill", 4)) {
- printf("process exiting\n");
- exit(0);
- }
-
- if (!strncmp(cmd, "lock", 4) && strlen(cmd) == 4) {
- lock(x, y);
- return;
- }
-
- if (!strncmp(cmd, "unlock", 6) && strlen(cmd) == 6) {
- unlock(x);
- return;
- }
-
- if (!strncmp(cmd, "unlockf", 7) && strlen(cmd) == 7) {
- unlockf(x);
- return;
- }
-
- if (!strncmp(cmd, "cancel", 6) && strlen(cmd) == 6) {
- cancel(x);
- return;
- }
-
- if (!strncmp(cmd, "canceld", 7) && strlen(cmd) == 7) {
- canceld(x, y);
- return;
- }
-
- if (!strncmp(cmd, "lock_sync", 9) && strlen(cmd) == 9) {
- lock_sync(x, y);
- return;
- }
-
- if (!strncmp(cmd, "unlock_sync", 11) && strlen(cmd) == 11) {
- unlock_sync(x);
- return;
- }
-
- if (!strncmp(cmd, "lock-kill", 9) && strlen(cmd) == 9) {
- lock(x, y);
- printf("process exiting\n");
- exit(0);
- }
-
- if (!strncmp(cmd, "unlock-kill", 11) && strlen(cmd) == 11) {
- unlock(x);
- printf("process exiting\n");
- exit(0);
- }
-
- if (!strncmp(cmd, "lock-cancel", 11) && strlen(cmd) == 11) {
- lock(x, y);
- /* usleep(1000 * z); */
- cancel(x);
- return;
- }
-
- if (!strncmp(cmd, "lock-unlockf", 12) && strlen(cmd) == 12) {
- lock(x, y);
- /* usleep(1000 * z); */
- unlockf(x);
- return;
- }
-
- if (!strncmp(cmd, "ex", 2)) {
- lock(x, LKM_EXMODE);
- return;
- }
-
- if (!strncmp(cmd, "pr", 2)) {
- lock(x, LKM_PRMODE);
- return;
- }
-
- if (!strncmp(cmd, "hold", 4) && strlen(cmd) == 4) {
- lock_all(LKM_PRMODE);
- return;
- }
-
- if (!strncmp(cmd, "hold-kill", 9) && strlen(cmd) == 9) {
- lock_all(LKM_PRMODE);
- exit(0);
- }
-
- if (!strncmp(cmd, "release", 7) && strlen(cmd) == 7) {
- unlock_all();
- return;
- }
-
- if (!strncmp(cmd, "release-kill", 12) && strlen(cmd) == 12) {
- unlock_all();
- exit(0);
- }
-
- if (!strncmp(cmd, "dump", 4) && strlen(cmd) == 4) {
- dump();
- return;
- }
-
- if (!strncmp(cmd, "stress", 6) && strlen(cmd) == 6) {
- if (iterations && !x)
- x = iterations;
- stress(x);
- return;
- }
-
- if (!strncmp(cmd, "tstress", 7) && strlen(cmd) == 7) {
- tstress(x);
- return;
- }
-
- if (!strncmp(cmd, "dstress", 7) && strlen(cmd) == 7) {
- dstress(x);
- return;
- }
-
- if (!strncmp(cmd, "stress_delay", 12) && strlen(cmd) == 12) {
- stress_delay = x;
- return;
- }
-
- if (!strncmp(cmd, "stress_lock_only", 16) && strlen(cmd) == 16) {
- stress_lock_only = !stress_lock_only;
- printf("stress_lock_only is %s\n", stress_lock_only ? "on" : "off");
- return;
- }
-
- if (!strncmp(cmd, "stress_stop", 11) && strlen(cmd) == 11) {
- stress_stop = !stress_stop;
- printf("stress_stop is %d\n", stress_stop);
- return;
- }
-
- if (!strncmp(cmd, "ignore_bast", 11) && strlen(cmd) == 11) {
- ignore_bast = !ignore_bast;
- printf("ignore_bast is %s\n", ignore_bast ? "on" : "off");
- return;
- }
-
- if (!strncmp(cmd, "our_xid", 7) && strlen(cmd) == 7) {
- our_xid = x;
- printf("our_xid is %llx\n", (unsigned long long)our_xid);
- return;
- }
-
-
- if (!strncmp(cmd, "purge", 5) && strlen(cmd) == 5) {
- purge(x, y);
- return;
- }
-
- if (!strncmp(cmd, "purgetest", 9) && strlen(cmd) == 9) {
- purgetest(x, y);
- return;
- }
-
- if (!strncmp(cmd, "noqueue", 7)) {
- noqueue = !noqueue;
- printf("noqueue is %s\n", noqueue ? "on" : "off");
- return;
- }
-
- if (!strncmp(cmd, "persistent", 10)) {
- persistent = !persistent;
- printf("persistent is %s\n", persistent ? "on" : "off");
- return;
- }
-
- if (!strncmp(cmd, "minhold", 7)) {
- minhold = x;
- return;
- }
-
- if (!strncmp(cmd, "timeout", 7)) {
- timeout = (uint64_t) 100 * x; /* dlm takes it in centiseconds */
- printf("timeout is %d\n", x);
- return;
- }
-
- if (!strncmp(cmd, "quiet", 5)) {
- quiet = !quiet;
- printf("quiet is %d\n", quiet);
- return;
- }
-
- if (!strncmp(cmd, "verbose", 7)) {
- verbose = !verbose;
- printf("verbose is %d\n", verbose);
- return;
- }
-
- if (!strncmp(cmd, "help", 4)) {
- print_commands();
- return;
- }
-
- if (!strncmp(cmd, "settings", 8)) {
- print_settings();
- return;
- }
-
- printf("unknown command %s\n", cmd);
-}
-
-static void print_usage(void)
-{
- printf("Options:\n");
- printf("\n");
- printf(" -n The number of locks to work with, default %d\n", MAX_LOCKS);
- printf(" -r The number of resources to work with, default %d\n", MAX_RESOURCES);
- printf(" -i Iterations in looping stress test, default 0 is no limit\n");
- printf(" -t Enable timeout warnings\n");
-}
-
-static void decode_arguments(int argc, char **argv)
-{
- int cont = 1;
- int optchar;
-
- while (cont) {
- optchar = getopt(argc, argv, "n:r:i:thVoq:v:");
-
- switch (optchar) {
-
- case 'n':
- maxn = atoi(optarg);
- break;
-
- case 'r':
- maxr = atoi(optarg);
- break;
-
- case 'i':
- iterations = atoi(optarg);
- break;
-
- case 't':
- timewarn = 1;
- break;
-
- case 'o':
- openclose_ls = 1;
- break;
-
- case 'q':
- quiet = atoi(optarg);
- break;
-
- case 'v':
- verbose = atoi(optarg);
- break;
-
- case 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case 'V':
- printf("%s (built %s %s)\n", argv[0], __DATE__, __TIME__);
- /* printf("%s\n", REDHAT_COPYRIGHT); */
- exit(EXIT_SUCCESS);
- break;
-
- case ':':
- case '?':
- fprintf(stderr, "Please use '-h' for usage.\n");
- exit(EXIT_FAILURE);
- break;
-
- case EOF:
- cont = 0;
- break;
-
- default:
- fprintf(stderr, "unknown option: %c\n", optchar);
- exit(EXIT_FAILURE);
- break;
- };
- }
-}
-
-static void sigterm_handler(int sig)
-{
- stress_stop = 1;
-}
-
-int main(int argc, char *argv[])
-{
- uint32_t major, minor, patch;
- struct lk *lk;
- int i, rv, maxi = 0, quit = 0;
-
- srandom(time(NULL));
-
- decode_arguments(argc, argv);
-
- if (maxn < maxr) {
- printf("number of resources must be >= number of locks\n");
- return -1;
- }
- if (maxn % maxr) {
- printf("number of locks must be multiple of number of resources\n");
- return -1;
- }
-
- printf("maxn = %d\n", maxn);
- printf("maxr = %d\n", maxr);
- printf("locks per resource = %d\n", maxn / maxr);
-
- signal(SIGTERM, sigterm_handler);
-
- client_init();
-
- locks = malloc(maxn * sizeof(struct lk));
- if (!locks) {
- printf("no mem for %d locks\n", maxn);
- return 0;
- }
- memset(locks, 0, sizeof(*locks));
-
- lk = locks;
- for (i = 0; i < maxn; i++) {
- lk->id = i;
- lk->grmode = -1;
- lk->rqmode = -1;
- lk++;
- }
-
- rv = dlm_kernel_version(&major, &minor, &patch);
- if (rv < 0) {
- printf("can't detect dlm in kernel %d\n", errno);
- return -1;
- }
- printf("dlm kernel version: %u.%u.%u\n", major, minor, patch);
- dlm_library_version(&major, &minor, &patch);
- printf("dlm library version: %u.%u.%u\n", major, minor, patch);
-
- if (openclose_ls) {
- printf("dlm_open_lockspace...\n");
-
- dh = dlm_open_lockspace("test");
- if (!dh) {
- printf("dlm_open_lockspace error %lu %d\n",
- (unsigned long)dh, errno);
- return -ENOTCONN;
- }
- } else {
- printf("dlm_new_lockspace...\n");
-
- dh = dlm_new_lockspace("test", 0600,
- timewarn ? DLM_LSFL_TIMEWARN : 0);
- if (!dh) {
- printf("dlm_new_lockspace error %lu %d\n",
- (unsigned long)dh, errno);
- return -ENOTCONN;
- }
- }
-
- rv = dlm_ls_get_fd(dh);
- if (rv < 0) {
- printf("dlm_ls_get_fd error %d %d\n", rv, errno);
- dlm_release_lockspace("test", dh, 1);
- return rv;
- }
- libdlm_fd = rv;
-
- client_add(libdlm_fd, &maxi);
-
- client_add(STDIN_FILENO, &maxi);
-
- printf("Type EXIT to finish, help for usage\n");
-
- while (1) {
- rv = poll(pollfd, maxi + 1, -1);
- if (rv < 0 && errno == EINTR)
- continue;
- if (rv < 0)
- printf("poll error %d errno %d\n", rv, errno);
-
- for (i = 0; i <= maxi; i++) {
- if (client[i].fd < 0)
- continue;
-
- if (pollfd[i].revents & POLLIN) {
- if (pollfd[i].fd == libdlm_fd)
- process_libdlm();
- else if (pollfd[i].fd == STDIN_FILENO)
- process_command(&quit);
- }
-
- if (pollfd[i].revents & (POLLHUP | POLLERR | POLLNVAL))
- client_dead(i);
- }
-
- if (quit && all_unlocks_done())
- break;
- }
-
- if (openclose_ls) {
- printf("dlm_close_lockspace\n");
-
- rv = dlm_close_lockspace(dh);
- if (rv < 0)
- printf("dlm_close_lockspace error %d %d\n", rv, errno);
- } else {
- printf("dlm_release_lockspace\n");
-
- rv = dlm_release_lockspace("test", dh, 1);
- if (rv < 0)
- printf("dlm_release_lockspace error %d %d\n", rv, errno);
- }
-
- return 0;
-}
-
diff --git a/dlm/tests/usertest/flood.c b/dlm/tests/usertest/flood.c
deleted file mode 100644
index c01bc0d..0000000
--- a/dlm/tests/usertest/flood.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* Flood the DLM !
- but not too much...
-*/
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/poll.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <unistd.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "libdlm.h"
-
-static pthread_cond_t cond;
-static pthread_mutex_t mutex;
-
-static int count = 0;
-
-static void usage(char *prog, FILE *file)
-{
- fprintf(file, "Usage:\n");
- fprintf(file, "%s [mcnpquhV] <lockname>\n", prog);
- fprintf(file, "\n");
- fprintf(file, " -V Show version of %s\n", prog);
- fprintf(file, " -h Show this help information\n");
- fprintf(file, " -m <num> Maximum number of locks to hold (default 100000)\n");
- fprintf(file, " -i <num> Show progress in <n> increments (default 1000)\n");
- fprintf(file, " -n <num> Number of resources (default 10)\n");
- fprintf(file, " -q Quit\n");
-
-
- fprintf(file, "\n");
-
-}
-
-static void ast_routine(void *arg)
-{
- struct dlm_lksb *lksb = arg;
-
- if (lksb->sb_status == 0) {
- dlm_unlock(lksb->sb_lkid, 0, lksb, lksb);
- return;
- }
-
- if (lksb->sb_status == EUNLOCK) {
- count--;
- }
-}
-
-int main(int argc, char *argv[])
-{
- int flags = 0;
- int lockops = 0;
- int maxlocks = 100000;
- int rescount = 10;
- int increment = 1000;
- int quiet = 0;
- int status;
- int i;
- int mode = LKM_CRMODE;
- int lksbnum = 0;
- signed char opt;
- char **resources;
- struct dlm_lksb *lksbs;
-
- /* Deal with command-line arguments */
- opterr = 0;
- optind = 0;
- while ((opt=getopt(argc,argv,"?m:i:qn:vV")) != EOF)
- {
- switch(opt)
- {
- case 'h':
- usage(argv[0], stdout);
- exit(0);
-
- case '?':
- usage(argv[0], stderr);
- exit(0);
-
- case 'm':
- maxlocks = atoi(optarg);
- break;
-
- case 'i':
- increment = atoi(optarg);
- break;
-
- case 'n':
- rescount = atoi(optarg);
- break;
-
- case 'q':
- quiet = 1;
- break;
-
- case 'V':
- printf("\nflood version 0.3\n\n");
- exit(1);
- break;
- }
- }
-
- if ((resources = malloc(sizeof(char*) * rescount)) == NULL)
- {
- perror("exhausted virtual memory");
- return 1;
- }
- for (i=0; i < rescount; i++) {
- char resname[256];
- sprintf(resname, "TESTLOCK%d", i);
- resources[i] = strdup(resname);
- }
-
- lksbs = malloc(sizeof(struct dlm_lksb) * maxlocks);
- if (!lksbs)
- {
- perror("cannot allocate lksbs");
- return 1;
- }
-
- pthread_cond_init(&cond, NULL);
- pthread_mutex_init(&mutex, NULL);
- pthread_mutex_lock(&mutex);
-
- dlm_pthread_init();
-
- while (1) {
- char *resource = resources[rand() % rescount];
-
- status = dlm_lock(mode,
- &lksbs[lksbnum],
- flags,
- resource,
- strlen(resource),
- 0, // Parent,
- ast_routine,
- &lksbs[lksbnum],
- NULL, // bast_routine,
- NULL); // Range
- if (status == -1)
- {
- perror("lock failed");
- return -1;
- }
-
- count++;
- lockops++;
- if ((lockops % increment) == 0 && !quiet)
- fprintf(stderr, "%d lockops, %d locks\n", lockops, count);
-
- while (count > maxlocks) {
- sleep(1);
- }
- lksbnum = (lksbnum+1)%maxlocks;
- }
-
- return 0;
-}
diff --git a/dlm/tests/usertest/joinleave.c b/dlm/tests/usertest/joinleave.c
deleted file mode 100644
index 5dc2c3e..0000000
--- a/dlm/tests/usertest/joinleave.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/time.h>
-#include <syslog.h>
-#include <sys/types.h>
-#include <sys/errno.h>
-
-#include "libdlm.h"
-
-static dlm_lshandle_t *dh;
-
-int main(int argc, char *argv[])
-{
- struct timeval begin, end, diff;
- char *name;
- int sec = 0;
-
- if (argc < 2) {
- printf("%s <lockspace name> [sleep sec]\n", argv[0]);
- exit(-1);
- }
-
- name = argv[1];
-
- if (argc > 2)
- sec = atoi(argv[2]);
-
- printf("Joining lockspace \"%s\" ... ", name);
- fflush(stdout);
-
- gettimeofday(&begin, NULL);
- dh = dlm_create_lockspace(name, 0600);
- if (!dh) {
- printf("dlm_create_lockspace error %p %d\n", dh, errno);
- return -ENOTCONN;
- }
- gettimeofday(&end, NULL);
-
- timersub(&end, &begin, &diff);
- printf("%lu s\n", diff.tv_sec);
-
- if (sec)
- sleep(sec);
-
- printf("Leaving lockspace \"%s\" ... ", name);
- fflush(stdout);
-
- gettimeofday(&begin, NULL);
- dlm_release_lockspace(name, dh, 1);
- gettimeofday(&end, NULL);
-
- timersub(&end, &begin, &diff);
- printf("%lu s\n", diff.tv_sec);
-
- return 0;
-}
-
diff --git a/dlm/tests/usertest/lstest.c b/dlm/tests/usertest/lstest.c
deleted file mode 100644
index ef582bf..0000000
--- a/dlm/tests/usertest/lstest.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/* Test program for userland lockspaces */
-
-#ifdef _REENTRANT
-#include <pthread.h>
-#endif
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/poll.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <unistd.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "libdlm.h"
-
-static struct dlm_lksb lksb;
-static int use_threads = 0;
-static int quiet = 0;
-
-/* Used by the pthread test */
-static pthread_cond_t cond;
-static pthread_mutex_t mutex;
-
-/* Used by the poll() test */
-static int ast_called = 0;
-
-static int modetonum(char *modestr)
-{
- int mode = LKM_EXMODE;
-
- if (strncasecmp(modestr, "NL", 2) == 0) mode = LKM_NLMODE;
- if (strncasecmp(modestr, "CR", 2) == 0) mode = LKM_CRMODE;
- if (strncasecmp(modestr, "CW", 2) == 0) mode = LKM_CWMODE;
- if (strncasecmp(modestr, "PR", 2) == 0) mode = LKM_PRMODE;
- if (strncasecmp(modestr, "PW", 2) == 0) mode = LKM_PWMODE;
- if (strncasecmp(modestr, "EX", 2) == 0) mode = LKM_EXMODE;
-
- return mode;
-}
-
-static const char *numtomode(int mode)
-{
- switch (mode)
- {
- case LKM_NLMODE: return "NL";
- case LKM_CRMODE: return "CR";
- case LKM_CWMODE: return "CW";
- case LKM_PRMODE: return "PR";
- case LKM_PWMODE: return "PW";
- case LKM_EXMODE: return "EX";
- default: return "??";
- }
-}
-
-static void usage(char *prog, FILE *file)
-{
- fprintf(file, "Usage:\n");
- fprintf(file, "%s [mcnpqdlrfuhV] <lockname>\n", prog);
- fprintf(file, "\n");
- fprintf(file, " -V Show version of dlmtest\n");
- fprintf(file, " -h Show this help information\n");
- fprintf(file, " -m <mode> lock mode (default EX)\n");
- fprintf(file, " -n don't block\n");
- fprintf(file, " -p Use pthreads\n");
- fprintf(file, " -q Quiet\n");
- fprintf(file, " -d <secs> Delay betwen lock & unlock\n");
- fprintf(file, " -l <ls> Lockspace name to create\n");
- fprintf(file, " -r Don't release lockspace before finishing\n");
- fprintf(file, " -f Force release lockspace\n");
- fprintf(file, " -u Don't unlock explicitly\n");
- fprintf(file, "\n");
-
-}
-
-static void ast_routine(void *arg)
-{
- struct dlm_lksb *alksb = arg;
-
- if (!quiet)
- printf("ast called, status = %d, lkid=%x\n", alksb->sb_status, alksb->sb_lkid);
-
- /* Wake the main thread */
- if (use_threads)
- {
- pthread_mutex_lock(&mutex);
- pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
- }
- else
- {
- ast_called = 1;
- }
-}
-
-static void bast_routine(void *arg)
-{
- struct dlm_lksb *blksb = arg;
-
- if (!quiet)
- printf("\nblocking ast called, status = %d, lkid=%x\n", blksb->sb_status, blksb->sb_lkid);
-}
-
-/* Using poll(2) to wait for and dispatch ASTs */
-static int poll_for_ast(dlm_lshandle_t ls)
-{
- struct pollfd pfd;
-
- pfd.fd = dlm_ls_get_fd(ls);
- pfd.events = POLLIN;
- while (!ast_called)
- {
- if (poll(&pfd, 1, 0) < 0)
- {
- perror("poll");
- return -1;
- }
- dlm_dispatch(dlm_ls_get_fd(ls));
- }
- ast_called = 0;
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- const char *resource = "LOCK-NAME";
- int flags = 0;
- int status;
- int mode = LKM_EXMODE;
- int do_unlock = 1;
- int release_ls = 1;
- int open_ls = 0;
- int force = 0;
- int sleeptime = 5;
- signed char opt;
- char lsname[64];
- dlm_lshandle_t ls;
-
- strcpy(lsname, "testls");
-
- /* Deal with command-line arguments */
- opterr = 0;
- optind = 0;
- while ((opt=getopt(argc,argv,"?m:nqupd:c:l:rfoV")) != EOF)
- {
- switch(opt)
- {
- case 'h':
- usage(argv[0], stdout);
- exit(0);
-
- case '?':
- usage(argv[0], stderr);
- exit(0);
-
- case 'm':
- mode = modetonum(optarg);
- break;
-
- case 'l':
- strcpy(lsname, optarg);
- break;
-
- case 'd':
- sleeptime = atoi(optarg);
- break;
-
- case 'p':
- use_threads++;
- break;
-
- case 'o':
- open_ls++;
- break;
-
- case 'f':
- force++;
- break;
-
- case 'r':
- release_ls = 0;
- break;
-
- case 'n':
- flags |= LKF_NOQUEUE;
- break;
-
- case 'q':
- quiet = 1;
- break;
-
- case 'u':
- do_unlock = 0;
- break;
-
- case 'V':
- printf("\nasttest version 0.2\n\n");
- exit(1);
- break;
- }
- }
-
- if (argv[optind])
- resource = argv[optind];
-
-
- if (!open_ls)
- {
- if (!quiet)
- fprintf(stderr, "Creating lockspace %s\n", lsname);
-
-
- ls = dlm_create_lockspace(lsname, 0444);
- if (ls == NULL)
- {
- perror("ls create");
- exit(4);
- }
- }
- else
- {
- if (!quiet)
- fprintf(stderr, "Opening lockspace %s\n", lsname);
-
-
- ls = dlm_open_lockspace(lsname);
- if (ls == NULL)
- {
- perror("ls open");
- exit(4);
- }
- }
-
-
- if (!quiet)
- fprintf(stderr, "locking %s %s %s...", resource,
- numtomode(mode),
- (flags&LKF_NOQUEUE?"(NOQUEUE)":""));
-
- fflush(stderr);
-
- if (use_threads)
- {
- pthread_cond_init(&cond, NULL);
- pthread_mutex_init(&mutex, NULL);
- pthread_mutex_lock(&mutex);
-
- status = dlm_ls_pthread_init(ls); printf("status=%d\n", status);
- status = dlm_ls_pthread_init(ls); printf("status=%d\n", status);
- }
-
- status = dlm_ls_lock(ls,mode,
- &lksb,
- flags,
- resource,
- strlen(resource),
- 0, // Parent,
- ast_routine,
- &lksb,
- bast_routine,
- NULL); // Range
- if (status == -1)
- {
- if (!quiet) fprintf(stderr, "\n");
- perror("lock");
-
- return -1;
- }
-
- /* Wait */
- if (use_threads)
- pthread_cond_wait(&cond, &mutex);
- else
- poll_for_ast(ls);
-
- sleep(sleeptime);
-
- if (!quiet)
- {
- fprintf(stderr, "unlocking %s...", resource);
- fflush(stderr);
- }
-
- if (do_unlock)
- {
- status = dlm_ls_unlock(ls,
- lksb.sb_lkid,
- 0, // flags
- &lksb,
- &lksb); // AST args
- if (status == -1)
- {
- if (!quiet) fprintf(stderr, "\n");
- perror("unlock");
- return -1;
- }
-
- /* Wait */
- if (use_threads)
- pthread_cond_wait(&cond, &mutex);
- else
- poll_for_ast(ls);
- }
-
- if (release_ls)
- {
- if (!quiet)
- fprintf(stderr, "Releasing ls %s\n", lsname);
-
- status = dlm_release_lockspace(lsname, ls, force);
- if (status)
- perror("release ls");
- }
-
- return 0;
-}
-
diff --git a/dlm/tests/usertest/lvb.c b/dlm/tests/usertest/lvb.c
deleted file mode 100644
index db2ce32..0000000
--- a/dlm/tests/usertest/lvb.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/* Simple LVB test prog */
-
-#ifdef VMS
-#include starlet
-#include psldef
-#include ssdef
-#include errno
-#include descrip
-#include rsdmdef
-#include lckdef
-
-#include stdio
-#include stdlib
-#include string
-
-struct lksb
-{
- int sb_status;
- int sb_lkid;
- char sb_lvb[16];
-};
-#endif
-
-#ifdef __linux__
-#include <stdio.h>
-#include <pthread.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libdlm.h>
-#include <unistd.h>
-#define LCK$M_VALBLK LKF_VALBLK
-#define LCK$M_CONVERT LKF_CONVERT
-#define LCK$K_CRMODE LKM_CRMODE
-#define LCK$K_PWMODE LKM_PWMODE
-#define PSL$C_USER 0
-#define SS$_NORMAL 0
-#define SS$_DEADLOCK EDEADLOCK
-#define EVMSERR errno
-#define sys$exit exit
-#define sys$hiber pause
-
-
-struct lksb {
- int sb_status;
- uint32_t sb_lkid;
- char sb_flags;
- char *sb_lvb;
-};
-
-struct dsc$descriptor_s
-{
- int dsc$w_length;
- char *dsc$a_pointer;
-};
-
-static int sys$enq(int efn, int mode, struct lksb *lksb, int flags,
- struct dsc$descriptor_s *name, int parent,
- void *compast, void *astarg, void *blockast,
- int accmode, int nullarg)
-{
- if (name)
- return dlm_lock(mode, (struct dlm_lksb *)lksb, flags,
- name->dsc$a_pointer,
- name->dsc$w_length,
- parent,
- compast, astarg,
- blockast, NULL);
- else
- return dlm_lock(mode, (struct dlm_lksb *)lksb, flags,
- NULL,
- 0,
- parent,
- compast, astarg,
- blockast, NULL);
-}
-
-static int sys$deq(int lkid, struct lksb *lksb, int accmode, int flags, int c)
-{
- return dlm_unlock(lkid, flags, (struct dlm_lksb *)lksb, NULL);
-}
-
-static char *linux_strerror(int vmserr, int err)
-{
- return strerror(err);
-}
-#define strerror linux_strerror
-
-#endif
-
-
-static struct lksb our_lksb;
-static int cur_mode;
-static void compast_routine(void *arg);
-static void blockast_routine(void *arg, int mode);
-static const char *name = "TESTLOCK";
-
-#ifdef __linux__
-static char lksb_lvb[DLM_LVB_LEN];
-#endif
-
-static void start_lock(int mode)
-{
- struct dsc$descriptor_s name_s;
- int status;
-
- cur_mode = mode;
-
-/* Make a descriptor of the name */
- memset(&name_s, 0, sizeof(struct dsc$descriptor_s));
- name_s.dsc$w_length = strlen(name);
- name_s.dsc$a_pointer = (char *)name;
-
- /* Lock it */
- status = sys$enq(0,
- cur_mode,
- &our_lksb,
- LCK$M_VALBLK, /* flags */
- &name_s,
- 0, /* parent */
- compast_routine,
- 0, /* astp */
- blockast_routine,
- PSL$C_USER,
- 0);
-
- if (status != SS$_NORMAL)
- {
- printf("lock enq failed : %s\n", strerror(EVMSERR, status));
- sys$exit(status);
- }
-
- printf("Lock ID is %x\n", our_lksb.sb_lkid);
- return;
-}
-
-static int convert_lock(int mode, char *lvb)
-{
- int status;
-
- memset(our_lksb.sb_lvb, 0, 16);
- if (lvb[strlen(lvb)-1] == '\n')
- lvb[strlen(lvb)-1] = '\0';
-
- cur_mode = mode;
- strcpy(our_lksb.sb_lvb, lvb);
- printf("converting to %d\n", mode);
-
- /* Lock it */
- status = sys$enq(0,
- mode,
- &our_lksb,
- LCK$M_CONVERT | LCK$M_VALBLK,
- NULL,
- 0, /* parent */
- compast_routine,
- 0, /* astp */
- blockast_routine,
- PSL$C_USER,
- 0);
-
- if (status != SS$_NORMAL)
- {
- printf("convert enq failed : %s\n", strerror(EVMSERR, status));
- }
-
- return status;
-}
-
-static void unlock(void)
-{
- int status;
-
- status = sys$deq(our_lksb.sb_lkid, NULL,0,0,0);
- if (status != SS$_NORMAL)
- {
- printf("denq failed : %s\n", strerror(EVMSERR, status));
- }
-}
-
-static void compast_routine(void *arg)
-{
-#ifdef __linux__
- if (our_lksb.sb_flags & DLM_SBF_VALNOTVALID)
- {
- printf("testlock: LVB not valid\n");
- sys$hiber();
- }
-#endif
- if (our_lksb.sb_status == SS$_DEADLOCK)
- {
- printf("testlock: deadlocked\n");
- unlock();
- return;
- }
-
- if (our_lksb.sb_status == SS$_NORMAL)
- {
- printf("testlock. compast, now at %d, lvb=%s\n", cur_mode, our_lksb.sb_lvb);
- }
- else
- {
- printf("testlock: lock failed (compast): %s\n", strerror(EVMSERR, our_lksb.sb_status));
- sys$hiber();
- }
-}
-
-static void blockast_routine(void *arg, int mode)
-{
- printf("testlock. blkast.\n");
-}
-
-int main(int argc, char *argv[])
-{
- char buf[80];
-
-#ifdef __linux__
- our_lksb.sb_lvb = lksb_lvb;
- dlm_pthread_init();
-#endif
-
- if (argc > 1)
- name = argv[1];
-
- start_lock(LCK$K_CRMODE);
-
- do {
- char cmd;
-
- fgets(buf, sizeof(buf), stdin);
- cmd = buf[0] & 0x5F;
-
- if (cmd == 'W')
- convert_lock(LCK$K_CRMODE, &buf[1]);
- else
- convert_lock(LCK$K_PWMODE, &buf[1]);
- }
- while (buf[0] != 'x');
-
- return SS$_NORMAL;
-}
-
diff --git a/dlm/tests/usertest/pingtest.c b/dlm/tests/usertest/pingtest.c
deleted file mode 100644
index 2fdbf18..0000000
--- a/dlm/tests/usertest/pingtest.c
+++ /dev/null
@@ -1,343 +0,0 @@
-
-/* Ping Test the locking interface */
-
-#ifdef __linux__
-#include <pthread.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <netdb.h>
-#include <unistd.h>
-
-#include <libdlm.h>
-
-static char our_lvb[DLM_LVB_LEN];
-static struct dlm_lksb our_lksb = {.sb_lvbptr = our_lvb};
-static int *lvb_int = (int *)our_lvb;
-#define SUCCESS 0
-#endif
-
-
-#ifdef VMS
-#include starlet
-#include psldef
-#include ssdef
-#include errno
-#include descrip
-#include rsdmdef
-#include lckdef
-
-#include stdio
-#include stdlib
-#include string
-
-struct lksb
-{
- int sb_status;
- int sb_lkid;
- char sb_lvb[16];
-};
-
-static struct lksb our_lksb;
-static int *lvb_int = (int *)&our_lksb.sb_lvb;
-
-#define LKM_NLMODE LCK$K_NLMODE
-#define LKM_CRMODE LCK$K_CRMODE
-#define LKM_CWMODE LCK$K_CWMODE
-#define LKM_PRMODE LCK$K_PRMODE
-#define LKM_PWMODE LCK$K_PWMODE
-#define LKM_EXMODE LCK$K_EXMODE
-#define EDEADLOCK SS$_DEADLOCK
-
-/* This is wrong...VMS does not deliver ASTs
- for $DEQ but we'll never get this code, honest.
- */
-#define EUNLOCK 65535
-
-#define SUCCESS SS$_NORMAL
-#endif
-
-static const char *lockname="ping";
-static int us = 1;
-static int maxnode = 2;
-static int cur_mode;
-
-static int granted = 0;
-static void compast_routine(void *arg);
-static void blockast_routine(void *arg);
-
-#ifdef __linux__
-static int convert_lock(int mode)
-{
- int status;
-
- printf("pinglock: convert to %d starting\n", mode);
- status = dlm_lock( mode,
- &our_lksb,
- LKF_VALBLK | LKF_CONVERT,
- NULL,
- 0,
- 0,
- compast_routine,
- &our_lksb,
- blockast_routine,
- NULL);
- if (status != 0)
- {
- perror("pinglock: convert failed");
- }
- else
- {
- cur_mode = mode;
- printf("pinglock: convert to %d started\n", mode);
- }
- return status;
-}
-
-static void unlock(void)
-{
- int status;
- status = dlm_unlock( our_lksb.sb_lkid,
- 0,
- &our_lksb,
- 0);
- if (status != 0)
- perror("pinglock: unlock failed");
-
-}
-
-static void start_lock(void)
-{
- int status;
- cur_mode = LKM_EXMODE;
-
- *lvb_int = us-1;
-
- printf("pinglock: starting\n");
- status = dlm_lock( cur_mode,
- &our_lksb,
- LKF_VALBLK,
- lockname,
- strlen(lockname)+1, /* include trailing NUL for ease of following */
- 0, /* Parent */
- compast_routine,
- &our_lksb,
- blockast_routine,
- NULL);
- if (status != 0)
- perror("pinglock: lock failed");
-}
-
-#endif /* __linux__ */
-
-#ifdef VMS
-
-static void start_lock()
-{
- struct dsc$descriptor_s name_s;
- int status;
- char *name = "PINGLOCK";
-
- cur_mode = LCK$K_EXMODE;
-
- *lvb_int = us-1;
-
-/* Make a descriptor of the name */
- memset(&name_s, 0, sizeof(struct dsc$descriptor_s));
- name_s.dsc$w_length = strlen(name);
- name_s.dsc$a_pointer = name;
-
- /* Lock it */
- status = sys$enqw(0,
- cur_mode,
- &our_lksb,
- 0, /* flags */
- &name_s,
- 0, /* parent */
- compast_routine,
- 0, /* astp */
- blockast_routine,
- PSL$C_USER,
- RSDM$K_PROCESS_RSDM_ID,
- 0);
-
- if (status != SS$_NORMAL)
- {
- printf("lock enq failed : %s\n", strerror(EVMSERR, status));
- sys$exit(status);
- }
-
- printf("Lock ID is %x\n", our_lksb.sb_lkid);
- return;
-}
-
-static int convert_lock(int mode)
-{
- int status;
- int old_mode = cur_mode;
-
- printf("converting to %d\n", mode);
-
- /* Lock it */
- status = sys$enq(0,
- mode,
- &our_lksb,
- LCK$M_CONVERT | LCK$M_VALBLK,
- NULL,
- 0, /* parent */
- compast_routine,
- 0, /* astp */
- blockast_routine,
- PSL$C_USER,
- RSDM$K_PROCESS_RSDM_ID,
- 0);
-
- if (status != SS$_NORMAL)
- {
- printf("convert enq failed : %s\n", strerror(EVMSERR, status));
- sys$wake();
- }
- else
- {
- cur_mode = mode;
- status = 0; /* simulate Unix retcodes */
- }
- return status;
-}
-
-static void unlock()
-{
- int status;
-
- status = sys$deq(our_lksb.sb_lkid, NULL,0,0,0);
- if (status != SS$_NORMAL)
- {
- printf("denq failed : %s\n", strerror(EVMSERR, status));
- sys$wake();
- }
-}
-
-#endif
-
-static void compast_routine(void *arg)
-{
-
-#ifdef __linux__
- if (our_lksb.sb_flags & DLM_SBF_VALNOTVALID)
-#endif
-#ifdef VMS
- if (our_lksb.sb_status == SS$_VALNOTVALID)
-#endif
- {
- printf(" valblk not valid. current value is %d\n", *lvb_int);
- unlock();
- exit(10);
- }
-
- if (our_lksb.sb_status == EDEADLOCK)
- {
- printf("pinglock: deadlocked\n");
- unlock();
- exit(11);
- }
-
- if (our_lksb.sb_status == EUNLOCK)
- {
- return;
- }
-
- if (our_lksb.sb_status == SUCCESS)
- {
- granted = 1;
- switch (cur_mode)
- {
- case LKM_NLMODE:
- printf("pinglock. compast, (valblk = %d) now at NL\n", *lvb_int);
- if (convert_lock(LKM_CRMODE) == 0)
- granted = 0;
- break;
-
- case LKM_CRMODE:
- printf("pinglock. compast, (valblk = %d) now at CR\n", *lvb_int);
- if (*lvb_int == us-1)
- {
- if (convert_lock(LKM_EXMODE) == 0)
- granted = 0;
- }
- break;
-
- case LKM_EXMODE:
- printf("pinglock. compast. (valblk = %d) now at EX\n", *lvb_int);
- if (*lvb_int == us-1)
- {
- (*lvb_int)++;
- *lvb_int %= maxnode;
- printf("pinglock. compast. incrementing valblk to %d\n", *lvb_int);
- }
- if (convert_lock(LKM_CRMODE) == 0)
- granted = 0;
- break;
- }
- }
- else
- {
- printf("pinglock: lock failed (compast): %d\n", our_lksb.sb_status);
- unlock();
- }
-}
-
-static void blockast_routine(void *arg)
-{
- printf("pinglock. blkast, granted = %d\n", granted);
- if (!granted)
- {
- return;
- }
-
- printf("pinglock. blkast, demoting lock to NL\n");
- if (convert_lock(LKM_NLMODE) == 0)
- granted = 0;
-}
-
-
-#ifdef __linux__
-int main(int argc, char *argv[])
-{
- if (argc < 3)
- {
- printf("usage: %s <maxnodes> <us>\n", argv[0]);
- return 2;
- }
- maxnode = atoi(argv[1]);
- us = atoi(argv[2]);
-
- dlm_pthread_init();
- start_lock();
- while(1)
- sleep(100000);
- return 0;
-}
-
-
-#endif
-
-#ifdef VMS
-int main(int argc, char *argv[])
-{
- if (argc < 3)
- {
- printf("usage: %s <maxnodes> <us>\n", argv[0]);
- return 2;
- }
- maxnode = atoi(argv[1]);
- us = atoi(argv[2]);
-
- start_lock();
- while(1)
- sys$hiber();
-
- return SS$_NORMAL;
-}
-#endif
diff --git a/dlm/tests/usertest/sublocks.c b/dlm/tests/usertest/sublocks.c
deleted file mode 100644
index d994b86..0000000
--- a/dlm/tests/usertest/sublocks.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/* Test program for userland DLM interface */
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <unistd.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "libdlm.h"
-
-static int modetonum(char *modestr)
-{
- int mode = LKM_EXMODE;
-
- if (strncasecmp(modestr, "NL", 2) == 0) mode = LKM_NLMODE;
- if (strncasecmp(modestr, "CR", 2) == 0) mode = LKM_CRMODE;
- if (strncasecmp(modestr, "CW", 2) == 0) mode = LKM_CWMODE;
- if (strncasecmp(modestr, "PR", 2) == 0) mode = LKM_PRMODE;
- if (strncasecmp(modestr, "PW", 2) == 0) mode = LKM_PWMODE;
- if (strncasecmp(modestr, "EX", 2) == 0) mode = LKM_EXMODE;
-
- return mode;
-}
-
-static void usage(char *prog, FILE *file)
-{
- fprintf(file, "Usage:\n");
- fprintf(file, "%s [mndvV] <parent>\n", prog);
- fprintf(file, "\n");
- fprintf(file, " -V Show version of %s\n", prog);
- fprintf(file, " -h Show this help information\n");
- fprintf(file, " -v Do it verbosely\n");
- fprintf(file, " -m <mode> lock mode (default CR)\n");
- fprintf(file, " -p Pause at end\n");
- fprintf(file, " -d <num> Depth of lock tree (default 4)\n");
- fprintf(file, " -n <num> Number of children (default 4)\n");
- fprintf(file, " -s <name> Subresource name (eg SUBRES-%%d)\n");
- fprintf(file, "\n");
-
-}
-
-int maxdepth = 4;
-int nchildren = 4;
-int verbose = 0;
-char *subresformat="SUBRES-%d-%d";
-
-
-int do_childlocks(int parent, int mode, int depth, int flags)
-{
- int status;
- int i;
- char subresname[64];
- struct dlm_lksb lksb;
-
- if (depth > maxdepth) return 0;
-
- memset(&lksb, 0, sizeof(lksb));
-
- for (i = 0; i < nchildren; i++)
- {
- sprintf(subresname, subresformat, depth, i);
-
- if (verbose)
- printf("locking '%s', depth %d\n", subresname, depth);
-
- status = dlm_lock_wait(mode, &lksb, flags, subresname, strlen(subresname)+1,
- parent, NULL, NULL, NULL);
- if (status || !lksb.sb_lkid)
- {
- perror("lock failed");
- return 0;
- }
- do_childlocks(lksb.sb_lkid, mode, depth+1, flags);
- }
- return 0;
-}
-
-
-int main(int argc, char *argv[])
-{
- char *resource = "LOCK-NAME";
- int flags = 0;
- int status;
- int mode = LKM_CRMODE;
- int pause_at_end=0;
- struct dlm_lksb lksb;
- signed char opt;
-
- /* Deal with command-line arguments */
- opterr = 0;
- optind = 0;
- while ((opt=getopt(argc,argv,"?m:n:d:s:pvV")) != EOF)
- {
- switch(opt)
- {
- case 'h':
- usage(argv[0], stdout);
- exit(0);
-
- case '?':
- usage(argv[0], stderr);
- exit(0);
-
- case 'm':
- mode = modetonum(optarg);
- break;
-
- case 'v':
- verbose++;
- break;
-
- case 'p':
- pause_at_end++;
- break;
-
- case 'd':
- maxdepth = atoi(optarg);
- break;
-
- case 'n':
- nchildren = atoi(optarg);
- break;
-
- case 's':
- strcpy(subresformat, optarg);
- break;
-
- case 'V':
- printf("\n%s version 0.1\n\n", argv[0]);
- exit(1);
- break;
- }
- }
-
- if (argv[optind])
- resource = argv[optind];
-
- /* Lock parent */
- if (verbose)
- fprintf(stderr, "locking parent '%s'\n", resource);
-
- fflush(stderr);
-
- status = dlm_lock_wait(mode, &lksb, flags,
- resource, strlen(resource)+1,
- 0, NULL, NULL, NULL);
- if (status == -1)
- {
- perror("lock");
- return -1;
- }
-
- if (lksb.sb_lkid == 0)
- {
- fprintf(stderr, "error: got lockid of zero\n");
- return 0;
- }
-
- do_childlocks(lksb.sb_lkid, mode, 0, flags);
-
- if (pause_at_end)
- {
- printf("paused\n");
- pause();
- }
- return 0;
-}
diff --git a/dlm/tests/usertest/threads.c b/dlm/tests/usertest/threads.c
deleted file mode 100644
index afbd19a..0000000
--- a/dlm/tests/usertest/threads.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Threaded DLM example
- */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/poll.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <unistd.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "libdlm.h"
-
-struct lock_wait {
- pthread_cond_t cond;
- pthread_mutex_t mutex;
- struct dlm_lksb lksb;
-};
-
-struct thread_args
-{
- dlm_lshandle_t *lockspace;
- char *resource;
- int flags;
- int delay;
- int mode;
- int verbose;
- int num;
-};
-
-static int modetonum(char *modestr)
-{
- int mode = LKM_EXMODE;
-
- if (strncasecmp(modestr, "NL", 2) == 0) mode = LKM_NLMODE;
- if (strncasecmp(modestr, "CR", 2) == 0) mode = LKM_CRMODE;
- if (strncasecmp(modestr, "CW", 2) == 0) mode = LKM_CWMODE;
- if (strncasecmp(modestr, "PR", 2) == 0) mode = LKM_PRMODE;
- if (strncasecmp(modestr, "PW", 2) == 0) mode = LKM_PWMODE;
- if (strncasecmp(modestr, "EX", 2) == 0) mode = LKM_EXMODE;
-
- return mode;
-}
-
-static void usage(char *prog, FILE *file)
-{
- fprintf(file, "Usage:\n");
- fprintf(file, "%s [mcnpquhV] <lockname>\n", prog);
- fprintf(file, "\n");
- fprintf(file, " -V show version of %s\n", prog);
- fprintf(file, " -h show this help information\n");
- fprintf(file, " -m <mode> lock mode (default EX)\n");
- fprintf(file, " -n don't block\n");
- fprintf(file, " -t <threads> number of threads\n");
- fprintf(file, " -d <secs> delay while holding lock\n");
- fprintf(file, " -l <name> lockspace name\n");
- fprintf(file, " -v verbose (up to 3)\n");
- fprintf(file, "\n");
-
-}
-
-/* Simply wakes the thread that initiated the lock */
-static void sync_ast_routine(void *arg)
-{
- struct lock_wait *lwait = arg;
-
- pthread_mutex_lock(&lwait->mutex);
- pthread_cond_signal(&lwait->cond);
- pthread_mutex_unlock(&lwait->mutex);
-}
-
-/* Get/Convert a lock and wait for it to complete (or fail) */
-static int sync_lock(dlm_lshandle_t lockspace,
- const char *resource,
- int mode,
- int flags,
- int *lockid)
-{
- int status;
- struct lock_wait lwait;
-
- if (!lockid) {
- errno = EINVAL;
- return -1;
- }
-
- /* Conversions need the lockid in the LKSB */
- if (flags & LKF_CONVERT)
- lwait.lksb.sb_lkid = *lockid;
-
- pthread_cond_init(&lwait.cond, NULL);
- pthread_mutex_init(&lwait.mutex, NULL);
- pthread_mutex_lock(&lwait.mutex);
-
- status = dlm_ls_lock(lockspace,
- mode,
- &lwait.lksb,
- flags,
- resource,
- strlen(resource),
- 0, sync_ast_routine, &lwait, NULL, NULL);
- if (status)
- return status;
-
- /* Wait for it to complete */
- pthread_cond_wait(&lwait.cond, &lwait.mutex);
- pthread_mutex_unlock(&lwait.mutex);
-
- *lockid = lwait.lksb.sb_lkid;
-
- errno = lwait.lksb.sb_status;
-
- if (lwait.lksb.sb_status)
- return -1;
- else
- return 0;
-}
-
-/* Unlock - and wait for it to complete */
-static int sync_unlock(dlm_lshandle_t lockspace, int lockid)
-{
- int status;
- struct lock_wait lwait;
-
- pthread_cond_init(&lwait.cond, NULL);
- pthread_mutex_init(&lwait.mutex, NULL);
- pthread_mutex_lock(&lwait.mutex);
-
- status = dlm_ls_unlock(lockspace, lockid, 0, &lwait.lksb, &lwait);
-
- if (status)
- return status;
-
- /* Wait for it to complete */
- pthread_cond_wait(&lwait.cond, &lwait.mutex);
- pthread_mutex_unlock(&lwait.mutex);
-
- errno = lwait.lksb.sb_status;
- if (lwait.lksb.sb_status != EUNLOCK)
- return -1;
- else
- return 0;
-
-}
-
-static void *thread_fn(void *arg)
-{
- struct thread_args *ta = arg;
- int lockid=0;
- int status;
-
- if (ta->verbose > 1)
- fprintf(stderr, "Locking in thread %lx\n", pthread_self());
-
- status = sync_lock(ta->lockspace, ta->resource,
- ta->mode, ta->flags, &lockid);
-
- if (status)
- {
- if (ta->verbose)
- fprintf(stderr, "Lock in thread %lx failed: %s\n", pthread_self(), strerror(errno));
- return NULL;
- }
-
- sleep(ta->delay);
-
- if (ta->verbose > 1)
- fprintf(stderr, "Unlocking in thread %lx\n", pthread_self());
-
- status = sync_unlock(ta->lockspace,lockid);
- if (status)
- {
- if (ta->verbose)
- fprintf(stderr, "Unlock in thread %lx failed: %s\n", pthread_self(), strerror(errno));
- }
-
- return NULL;
-}
-
-
-int main(int argc, char *argv[])
-{
- char const *resource = "LOCK-NAME";
- char const *lockspace_name = "threadtest";
- dlm_lshandle_t *lockspace;
- int flags = 0;
- int num_threads = 5;
- int delay = 1;
- int mode = LKM_EXMODE;
- int verbose = 0;
- int i;
- signed char opt;
- pthread_t *threads;
- struct thread_args ta;
-
- /* Deal with command-line arguments */
- opterr = 0;
- optind = 0;
- while ((opt=getopt(argc,argv,"h?nt:d:l:m:vV")) != EOF)
- {
- switch(opt)
- {
- case 'h':
- usage(argv[0], stdout);
- exit(0);
-
- case '?':
- usage(argv[0], stderr);
- exit(0);
-
- case 'n':
- flags |= LKF_NOQUEUE;
- break;
-
- case 't':
- num_threads = atoi(optarg);
- break;
-
- case 'm':
- mode = modetonum(optarg);
- break;
-
- case 'l':
- lockspace_name = strdup(optarg);
- break;
-
- case 'd':
- delay = atoi(optarg);
- break;
-
- case 'v':
- verbose++;
- break;
-
- case 'V':
- printf("\nthread example version 0.1\n\n");
- exit(1);
- break;
- }
- }
-
- if (argv[optind])
- resource = argv[optind];
-
- if (verbose)
- fprintf(stderr, "Creating lockspace '%s'...", lockspace_name);
-
- /* You need to be root to create the lockspace ... but not to use it */
- lockspace = dlm_create_lockspace(lockspace_name, 0666);
- if (!lockspace) {
- perror("Unable to create lockspace");
- return 1;
- }
- if (verbose)
- fprintf(stderr, "done\n");
-
- dlm_ls_pthread_init(lockspace);
-
- threads = malloc(sizeof(pthread_t) * num_threads);
- if (!threads)
- {
- perror("can't malloc threads array");
- return 2;
- }
-
- if (verbose)
- fprintf(stderr, "Starting threads\n");
-
- ta.lockspace = lockspace;
- ta.mode = mode;
- ta.flags = flags;
- ta.delay = delay;
- ta.verbose = verbose;
- ta.resource = (char *)resource;
-
- for (i=0; i<num_threads; i++)
- {
- if (verbose > 2)
- fprintf(stderr, "Starting thread %d\n", i);
-
- pthread_create(&threads[i], NULL, thread_fn, &ta);
- }
-
- if (verbose)
- fprintf(stderr, "All threads started\n");
-
- for (i=0; i<num_threads; i++)
- {
- void *status;
- if (verbose > 2)
- fprintf(stderr, "Waiting for thread %d\n", i);
- pthread_join(threads[i], &status);
- }
-
- return 0;
-}
-
diff --git a/dlm/tool/Makefile b/dlm/tool/Makefile
deleted file mode 100644
index 680cc88..0000000
--- a/dlm/tool/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-TARGET= dlm_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
-
-CFLAGS += -I${dlmincdir} -I${dlmcontrolincdir}
-CFLAGS += -I$(SRCDIR)/group/dlm_controld/
-CFLAGS += -I${incdir}
-CFLAGS += -I${KERNEL_SRC}/include/
-
-LDFLAGS += -L${dlmlibdir} -L${dlmcontrollibdir} -ldlm -ldlmcontrol
-LDFLAGS += -L${libdir}
-
-${TARGET}: ${OBJS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-clean: generalclean
-
-depends:
- $(MAKE) -C ../libdlm all
- $(MAKE) -C ../libdlmcontrol all
-
--include $(OBJS:.o=.Tpo)
diff --git a/dlm/tool/main.c b/dlm/tool/main.c
deleted file mode 100644
index 4752008..0000000
--- a/dlm/tool/main.c
+++ /dev/null
@@ -1,1324 +0,0 @@
-#include <sys/types.h>
-#include <sys/un.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <netinet/in.h>
-
-#include <linux/dlmconstants.h>
-#include "libdlm.h"
-#include "libdlmcontrol.h"
-#include "copyright.cf"
-
-#define LKM_IVMODE -1
-
-#define OP_JOIN 1
-#define OP_LEAVE 2
-#define OP_JOINLEAVE 3
-#define OP_LIST 4
-#define OP_DEADLOCK_CHECK 5
-#define OP_DUMP 6
-#define OP_PLOCKS 7
-#define OP_LOCKDUMP 8
-#define OP_LOCKDEBUG 9
-#define OP_LOG_PLOCK 10
-
-static char *prog_name;
-static char *lsname;
-static int operation;
-static int opt_ind;
-static int ls_all_nodes = 0;
-static int opt_dir = 0;
-static int opt_excl = 0;
-static int opt_fs = 0;
-static int dump_mstcpy = 0;
-static mode_t create_mode = 0600;
-static int verbose;
-static int wide;
-static int summarize;
-
-#define MAX_LS 128
-#define MAX_NODES 128
-
-/* from linux/fs/dlm/dlm_internal.h */
-#define DLM_LKSTS_WAITING 1
-#define DLM_LKSTS_GRANTED 2
-#define DLM_LKSTS_CONVERT 3
-
-#define DLM_MSG_REQUEST 1
-#define DLM_MSG_CONVERT 2
-#define DLM_MSG_UNLOCK 3
-#define DLM_MSG_CANCEL 4
-#define DLM_MSG_REQUEST_REPLY 5
-#define DLM_MSG_CONVERT_REPLY 6
-#define DLM_MSG_UNLOCK_REPLY 7
-#define DLM_MSG_CANCEL_REPLY 8
-#define DLM_MSG_GRANT 9
-#define DLM_MSG_BAST 10
-#define DLM_MSG_LOOKUP 11
-#define DLM_MSG_REMOVE 12
-#define DLM_MSG_LOOKUP_REPLY 13
-#define DLM_MSG_PURGE 14
-
-
-struct dlmc_lockspace lss[MAX_LS];
-struct dlmc_node nodes[MAX_NODES];
-
-struct rinfo {
- int print_granted;
- int print_convert;
- int print_waiting;
- int print_lookup;
- int namelen;
- int nodeid;
- int lvb;
- unsigned int lkb_count;
- unsigned int lkb_granted;
- unsigned int lkb_convert;
- unsigned int lkb_waiting;
- unsigned int lkb_lookup;
- unsigned int lkb_wait_msg;
- unsigned int lkb_master_copy;
- unsigned int lkb_local_copy;
- unsigned int lkb_process_copy;
-};
-
-struct summary {
- unsigned int rsb_total;
- unsigned int rsb_with_lvb;
- unsigned int rsb_no_locks;
- unsigned int rsb_lookup;
- unsigned int rsb_master;
- unsigned int rsb_local;
- unsigned int rsb_nodeid_error;
- unsigned int lkb_count;
- unsigned int lkb_granted;
- unsigned int lkb_convert;
- unsigned int lkb_waiting;
- unsigned int lkb_lookup;
- unsigned int lkb_wait_msg;
- unsigned int lkb_master_copy;
- unsigned int lkb_local_copy;
- unsigned int lkb_process_copy;
- unsigned int expect_replies;
-};
-
-static const char *mode_str(int mode)
-{
- switch (mode) {
- case -1:
- return "IV";
- case LKM_NLMODE:
- return "NL";
- case LKM_CRMODE:
- return "CR";
- case LKM_CWMODE:
- return "CW";
- case LKM_PRMODE:
- return "PR";
- case LKM_PWMODE:
- return "PW";
- case LKM_EXMODE:
- return "EX";
- }
- return "??";
-}
-
-static const char *msg_str(int type)
-{
- switch (type) {
- case DLM_MSG_REQUEST:
- return "request";
- case DLM_MSG_CONVERT:
- return "convert";
- case DLM_MSG_UNLOCK:
- return "unlock ";
- case DLM_MSG_CANCEL:
- return "cancel ";
- case DLM_MSG_REQUEST_REPLY:
- return "r_reply";
- case DLM_MSG_CONVERT_REPLY:
- return "c_reply";
- case DLM_MSG_UNLOCK_REPLY:
- return "u_reply";
- case DLM_MSG_CANCEL_REPLY:
- return "c_reply";
- case DLM_MSG_GRANT:
- return "grant ";
- case DLM_MSG_BAST:
- return "bast ";
- case DLM_MSG_LOOKUP:
- return "lookup ";
- case DLM_MSG_REMOVE:
- return "remove ";
- case DLM_MSG_LOOKUP_REPLY:
- return "l_reply";
- case DLM_MSG_PURGE:
- return "purge ";
- default:
- return "unknown";
- }
-}
-
-static void print_usage(void)
-{
- printf("Usage:\n");
- printf("\n");
- printf("dlm_tool [options] [join | leave | lockdump | lockdebug |\n"
- " ls | dump | log_plock | plocks |\n"
- " deadlock_check]\n");
- printf("\n");
- printf("Options:\n");
- printf(" -n Show all node information in ls\n");
- printf(" -d <n> Resource directory off/on (0/1) in join, default 0\n");
- printf(" -e <n> Exclusive create off/on (0/1) in join, default 0\n");
- printf(" -f <n> FS memory allocation off/on (0/1) in join, default 0\n");
- printf(" -m <mode> Permission mode for lockspace device (octal), default 0600\n");
- printf(" -M Print MSTCPY locks in lockdump\n"
- " (remote locks that are locally mastered)\n");
- printf(" -s Summary following lockdebug output\n");
- printf(" (experimental, format not fixed)\n");
- printf(" -v Verbose lockdebug output\n");
- printf(" -w Wide lockdebug output\n");
- printf(" -h Print this help, then exit\n");
- printf(" -V Print program version information, then exit\n");
- printf("\n");
-}
-
-#define OPTION_STRING "MhVnd:m:e:f:vws"
-
-static void decode_arguments(int argc, char **argv)
-{
- int cont = 1;
- int optchar;
- int need_lsname;
- char modebuf[8];
-
- while (cont) {
- optchar = getopt(argc, argv, OPTION_STRING);
-
- switch (optchar) {
- case 'd':
- opt_dir = atoi(optarg);
- break;
-
- case 'e':
- opt_excl = atoi(optarg);
- break;
-
- case 'f':
- opt_fs = atoi(optarg);
- break;
-
- case 'm':
- memset(modebuf, 0, sizeof(modebuf));
- snprintf(modebuf, 8, "%s", optarg);
- sscanf(modebuf, "%o", &create_mode);
- break;
-
- case 'M':
- dump_mstcpy = 1;
- break;
-
- case 'n':
- ls_all_nodes = 1;
- break;
-
- case 's':
- summarize = 1;
- break;
-
- case 'v':
- verbose = 1;
- break;
-
- case 'w':
- wide = 1;
- break;
-
- case 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case 'V':
- printf("%s %s (built %s %s)\n",
- prog_name, RELEASE_VERSION, __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- break;
-
- case ':':
- case '?':
- fprintf(stderr, "Please use '-h' for usage.\n");
- exit(EXIT_FAILURE);
- break;
-
- case EOF:
- cont = 0;
- break;
-
- default:
- fprintf(stderr, "unknown option: %c\n", optchar);
- exit(EXIT_FAILURE);
- break;
- };
- }
-
- need_lsname = 1;
-
- while (optind < argc) {
-
- /*
- * libdlm
- */
-
- if (!strncmp(argv[optind], "join", 4) &&
- (strlen(argv[optind]) == 4)) {
- operation = OP_JOIN;
- opt_ind = optind + 1;
- break;
- } else if (!strncmp(argv[optind], "leave", 5) &&
- (strlen(argv[optind]) == 5)) {
- operation = OP_LEAVE;
- opt_ind = optind + 1;
- break;
- } else if (!strncmp(argv[optind], "joinleave", 9) &&
- (strlen(argv[optind]) == 9)) {
- operation = OP_JOINLEAVE;
- opt_ind = optind + 1;
- break;
- }
-
- /*
- * libdlmcontrol
- */
-
- else if (!strncmp(argv[optind], "ls", 2) &&
- (strlen(argv[optind]) == 2)) {
- operation = OP_LIST;
- opt_ind = optind + 1;
- need_lsname = 0;
- break;
- } else if (!strncmp(argv[optind], "deadlock_check", 14) &&
- (strlen(argv[optind]) == 14)) {
- operation = OP_DEADLOCK_CHECK;
- opt_ind = optind + 1;
- break;
- } else if (!strncmp(argv[optind], "dump", 4) &&
- (strlen(argv[optind]) == 4)) {
- operation = OP_DUMP;
- opt_ind = optind + 1;
- need_lsname = 0;
- break;
- } else if (!strncmp(argv[optind], "plocks", 6) &&
- (strlen(argv[optind]) == 6)) {
- operation = OP_PLOCKS;
- opt_ind = optind + 1;
- break;
- } else if (!strncmp(argv[optind], "log_plock", 9) &&
- (strlen(argv[optind]) == 9)) {
- operation = OP_LOG_PLOCK;
- opt_ind = optind + 1;
- need_lsname = 0;
- break;
- }
-
- /*
- * debugfs
- */
-
- else if (!strncmp(argv[optind], "lockdump", 8) &&
- (strlen(argv[optind]) == 8)) {
- operation = OP_LOCKDUMP;
- opt_ind = optind + 1;
- break;
- } else if (!strncmp(argv[optind], "lockdebug", 9) &&
- (strlen(argv[optind]) == 9)) {
- operation = OP_LOCKDEBUG;
- opt_ind = optind + 1;
- break;
- }
- optind++;
- }
-
- if (!operation || !opt_ind) {
- print_usage();
- exit(EXIT_FAILURE);
- }
-
- if (optind < argc - 1)
- lsname = argv[opt_ind];
- else if (need_lsname) {
- fprintf(stderr, "lockspace name required\n");
- exit(EXIT_FAILURE);
- }
-}
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, (char *)buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0)
- return rv;
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-static char *flag_str(uint32_t flags)
-{
- static char join_flags[128];
-
- memset(join_flags, 0, sizeof(join_flags));
-
- strcat(join_flags, "flags ");
-
- if (flags & DLM_LSFL_NODIR)
- strcat(join_flags, "NODIR ");
-
- if (flags & DLM_LSFL_NEWEXCL)
- strcat(join_flags, "NEWEXCL ");
-
- if (flags & DLM_LSFL_FS)
- strcat(join_flags, "FS ");
-
- return join_flags;
-}
-
-static void do_join(char *name)
-{
- dlm_lshandle_t *dh;
- uint32_t flags = 0;
-
- if (!opt_dir)
- flags |= DLM_LSFL_NODIR;
-
- if (opt_excl)
- flags |= DLM_LSFL_NEWEXCL;
-
- if (opt_fs)
- flags |= DLM_LSFL_FS;
-
- printf("Joining lockspace \"%s\" permission %o %s\n",
- name, create_mode, flags ? flag_str(flags) : "");
- fflush(stdout);
-
- dh = dlm_new_lockspace(name, create_mode, flags);
- if (!dh) {
- fprintf(stderr, "dlm_new_lockspace %s error %d\n",
- name, errno);
- exit(-1);
- }
-
- dlm_close_lockspace(dh);
- /* there's no autofree so the ls should stay around */
- printf("done\n");
-}
-
-static void do_leave(char *name)
-{
- dlm_lshandle_t *dh;
-
- printf("Leaving lockspace \"%s\"\n", name);
- fflush(stdout);
-
- dh = dlm_open_lockspace(name);
- if (!dh) {
- fprintf(stderr, "dlm_open_lockspace %s error %p %d\n",
- name, dh, errno);
- exit(-1);
- }
-
- dlm_release_lockspace(name, dh, 1);
- printf("done\n");
-}
-
-static char *pr_master(int nodeid)
-{
- static char buf[64];
-
- memset(buf, 0, sizeof(buf));
-
- if (nodeid > 0)
- sprintf(buf, "Local %d", nodeid);
- else if (!nodeid)
- sprintf(buf, "Master");
- else if (nodeid == -1)
- sprintf(buf, "Lookup");
-
- return buf;
-}
-
-static char *pr_extra(uint32_t flags, int root_list, int recover_list,
- int recover_locks_count, char *first_lkid)
-{
- static char buf[128];
- int first = 0;
-
- memset(buf, 0, sizeof(buf));
-
- if (strcmp(first_lkid, "0"))
- first = 1;
-
- if (flags || first || root_list || recover_list || recover_locks_count)
- sprintf(buf,
- "flags %08x first_lkid %s root %d recover %d locks %d",
- flags, first_lkid, root_list, recover_list, recover_locks_count);
-
- return buf;
-}
-
-static void print_rsb(char *line, struct rinfo *ri)
-{
- char type[4], namefmt[4], *p;
- char addr[64];
- char first_lkid[64];
- int rv, nodeid, root_list, recover_list, recover_locks_count, namelen;
- uint32_t flags;
-
- rv = sscanf(line, "%s %s %d %s %u %d %d %u %u %s",
- type,
- addr,
- &nodeid,
- first_lkid,
- &flags,
- &root_list,
- &recover_list,
- &recover_locks_count,
- &namelen,
- namefmt);
-
- if (rv != 10)
- goto fail;
-
- /* used for lkb prints */
- ri->nodeid = nodeid;
-
- ri->namelen = namelen;
-
- p = strchr(line, '\n');
- if (!p)
- goto fail;
- *p = '\0';
-
- p = strstr(line, namefmt);
- if (!p)
- goto fail;
- p += 4;
-
- strcat(addr, " ");
-
- if (!strncmp(namefmt, "str", 3))
- printf("Resource len %2d \"%s\"\n", namelen, p);
- else if (!strncmp(namefmt, "hex", 3))
- printf("Resource len %2d hex %s\n", namelen, p);
- else
- goto fail;
-
- printf("%-16s %s\n",
- pr_master(nodeid),
- pr_extra(flags, root_list, recover_list, recover_locks_count, first_lkid));
- return;
-
- fail:
- fprintf(stderr, "print_rsb error rv %d line \"%s\"\n", rv, line);
-}
-
-static void print_lvb(char *line)
-{
- char lvb[1024];
- char type[4];
- int i, c, rv, lvblen;
- uint32_t lvbseq;
-
- memset(lvb, 0, 1024);
-
- rv = sscanf(line, "%s %u %d %[0-9A-Fa-f ]", type, &lvbseq, &lvblen, lvb);
-
- if (rv != 4) {
- fprintf(stderr, "print_lvb error rv %d line \"%s\"\n", rv, line);
- return;
- }
-
- printf("LVB len %d seq %u\n", lvblen, lvbseq);
-
- for (c = 0, i = 0; ; i++) {
- printf("%c", lvb[i]);
- if (lvb[i] != ' ')
- c++;
- if (!wide && lvb[i] == ' ' && !(c % 32))
- printf("\n");
- if (c == (lvblen * 2))
- break;
- }
- printf("\n");
-}
-
-struct lkb {
- uint64_t xid, timestamp, time_bast;
- uint32_t id, remid, exflags, flags, lvbseq;
- int nodeid, ownpid, status, grmode, rqmode, highbast, rsb_lookup, wait_type;
-};
-
-static const char *pr_grmode(struct lkb *lkb)
-{
- if (lkb->status == DLM_LKSTS_GRANTED || lkb->status == DLM_LKSTS_CONVERT)
- return mode_str(lkb->grmode);
- else if (lkb->status == DLM_LKSTS_WAITING || lkb->rsb_lookup)
- return "--";
- else
- return "XX";
-}
-
-static const char *pr_rqmode(struct lkb *lkb)
-{
- static char buf[5];
-
- memset(buf, 0, sizeof(buf));
-
- if (lkb->status == DLM_LKSTS_GRANTED) {
- return " ";
- } else if (lkb->status == DLM_LKSTS_CONVERT ||
- lkb->status == DLM_LKSTS_WAITING ||
- lkb->rsb_lookup) {
- sprintf(buf, "(%s)", mode_str(lkb->rqmode));
- return buf;
- } else {
- return "(XX)";
- }
-}
-
-static const char *pr_remote(struct lkb *lkb, struct rinfo *ri)
-{
- static char buf[64];
-
- memset(buf, 0, sizeof(buf));
-
- if (!lkb->nodeid) {
- return " ";
- } else if (lkb->nodeid != ri->nodeid) {
- sprintf(buf, "Remote: %3d %08x", lkb->nodeid, lkb->remid);
- return buf;
- } else {
- sprintf(buf, "Master: %3d %08x", lkb->nodeid, lkb->remid);
- return buf;
- }
-}
-
-static const char *pr_wait(struct lkb *lkb)
-{
- static char buf[16];
-
- memset(buf, 0, sizeof(buf));
-
- if (!lkb->wait_type) {
- return " ";
- } else {
- sprintf(buf, " wait %02d", lkb->wait_type);
- return buf;
- }
-}
-
-static char *pr_verbose(struct lkb *lkb)
-{
- static char buf[128];
-
- memset(buf, 0, sizeof(buf));
-
- sprintf(buf, "time %016llu flags %08x %08x bast %d %llu",
- (unsigned long long)lkb->timestamp,
- lkb->exflags, lkb->flags, lkb->highbast,
- (unsigned long long)lkb->time_bast);
-
- return buf;
-}
-
-static void print_lkb(char *line, struct rinfo *ri)
-{
- struct lkb lkb;
- char type[4];
- int rv;
-
- rv = sscanf(line, "%s %x %d %x %u %"PRIu64" %x %x %d %d %d %d %d %d %u %"PRIu64" %"PRIu64,
- type,
- &lkb.id,
- &lkb.nodeid,
- &lkb.remid,
- &lkb.ownpid,
- &lkb.xid,
- &lkb.exflags,
- &lkb.flags,
- &lkb.status,
- &lkb.grmode,
- &lkb.rqmode,
- &lkb.highbast,
- &lkb.rsb_lookup,
- &lkb.wait_type,
- &lkb.lvbseq,
- &lkb.timestamp,
- &lkb.time_bast);
-
- ri->lkb_count++;
-
- if (lkb.status == DLM_LKSTS_GRANTED) {
- if (!ri->print_granted++)
- printf("Granted\n");
- ri->lkb_granted++;
- }
- if (lkb.status == DLM_LKSTS_CONVERT) {
- if (!ri->print_convert++)
- printf("Convert\n");
- ri->lkb_convert++;
- }
- if (lkb.status == DLM_LKSTS_WAITING) {
- if (!ri->print_waiting++)
- printf("Waiting\n");
- ri->lkb_waiting++;
- }
- if (lkb.rsb_lookup) {
- if (!ri->print_lookup++)
- printf("Lookup\n");
- ri->lkb_lookup++;
- }
-
- if (lkb.wait_type)
- ri->lkb_wait_msg++;
-
- if (!ri->nodeid) {
- if (lkb.nodeid)
- ri->lkb_master_copy++;
- else
- ri->lkb_local_copy++;
- } else {
- ri->lkb_process_copy++;
- }
-
- printf("%08x %s %s %s %s %s\n",
- lkb.id, pr_grmode(&lkb), pr_rqmode(&lkb),
- pr_remote(&lkb, ri), pr_wait(&lkb),
- (verbose && wide) ? pr_verbose(&lkb) : "");
-
- if (verbose && !wide)
- printf("%s\n", pr_verbose(&lkb));
-}
-
-static void clear_rinfo(struct rinfo *ri)
-{
- memset(ri, 0, sizeof(struct rinfo));
- ri->nodeid = -9;
-}
-
-static void count_rinfo(struct summary *s, struct rinfo *ri)
-{
- /* the first time called */
- if (!ri->namelen)
- return;
-
- s->rsb_total++;
-
- if (ri->lvb)
- s->rsb_with_lvb++;
-
- if (!ri->lkb_count) {
- s->rsb_no_locks++;
- printf("no locks\n");
- }
-
- if (!ri->nodeid)
- s->rsb_master++;
- else if (ri->nodeid == -1)
- s->rsb_lookup++;
- else if (ri->nodeid > 0)
- s->rsb_local++;
- else
- s->rsb_nodeid_error++;
-
- s->lkb_count += ri->lkb_count;
- s->lkb_granted += ri->lkb_granted;
- s->lkb_convert += ri->lkb_convert;
- s->lkb_waiting += ri->lkb_waiting;
- s->lkb_lookup += ri->lkb_lookup;
- s->lkb_wait_msg += ri->lkb_wait_msg;
- s->lkb_master_copy += ri->lkb_master_copy;
- s->lkb_local_copy += ri->lkb_local_copy;
- s->lkb_process_copy += ri->lkb_process_copy;
-}
-
-static void print_summary(struct summary *s)
-{
- printf("rsb\n");
- printf(" total %u\n", s->rsb_total);
- printf(" master %u\n", s->rsb_master);
- printf(" remote master %u\n", s->rsb_local);
- printf(" lookup master %u\n", s->rsb_lookup);
- printf(" with lvb %u\n", s->rsb_with_lvb);
- printf(" with no locks %u\n", s->rsb_no_locks);
- printf(" nodeid error %u\n", s->rsb_nodeid_error);
- printf("\n");
-
- printf("lkb\n");
- printf(" total %u\n", s->lkb_count);
- printf(" granted %u\n", s->lkb_granted);
- printf(" convert %u\n", s->lkb_convert);
- printf(" waiting %u\n", s->lkb_waiting);
- printf(" local copy %u\n", s->lkb_local_copy);
- printf(" master copy %u\n", s->lkb_master_copy);
- printf(" process copy %u\n", s->lkb_process_copy);
- printf(" rsb lookup %u\n", s->lkb_lookup);
- printf(" wait message %u\n", s->lkb_wait_msg);
- printf(" expect reply %u\n", s->expect_replies);
-}
-
-#define LOCK_LINE_MAX 1024
-
-static void do_waiters(char *name, struct summary *sum)
-{
- FILE *file;
- char path[PATH_MAX];
- char line[LOCK_LINE_MAX];
- char rname[65];
- int header = 0;
- int i, j, spaces;
- int rv, nodeid, wait_type;
- uint32_t id;
-
- snprintf(path, PATH_MAX, "/sys/kernel/debug/dlm/%s_waiters", name);
-
- file = fopen(path, "r");
- if (!file)
- return;
-
- while (fgets(line, LOCK_LINE_MAX, file)) {
- if (!header) {
- printf("\n");
- printf("Expecting reply\n");
- header = 1;
- }
-
- rv = sscanf(line, "%x %d %d",
- &id, &wait_type, &nodeid);
-
- if (rv != 3) {
- printf("waiters: %s", line);
- continue;
- }
-
- /* parse the resource name from the remainder of the line */
- j = 0;
- spaces = 0;
-
- for (i = 0; i < LOCK_LINE_MAX; i++) {
- if (line[i] == '\n')
- break;
- if (spaces == 3) {
- rname[j++] = line[i];
- if (j == (sizeof(rname) - 1))
- break;
- } else if (line[i] == ' ') {
- spaces++;
- }
- }
-
- printf("nodeid %2d msg %s lkid %08x resource \"%s\"\n",
- nodeid, msg_str(wait_type), id, rname);
-
- sum->expect_replies++;
- }
- fclose(file);
-}
-
-static void do_lockdebug(char *name)
-{
- struct summary summary;
- struct rinfo info;
- FILE *file;
- char path[PATH_MAX];
- char line[LOCK_LINE_MAX];
- int old = 0;
-
- snprintf(path, PATH_MAX, "/sys/kernel/debug/dlm/%s_all", name);
-
- file = fopen(path, "r");
- if (!file) {
- snprintf(path, PATH_MAX, "/sys/kernel/debug/dlm/%s", name);
- file = fopen(path, "r");
- if (!file) {
- fprintf(stderr, "can't open %s: %s\n", path, strerror(errno));
- return;
- }
- old = 1;
- }
-
- memset(&summary, 0, sizeof(struct summary));
- memset(&info, 0, sizeof(struct rinfo));
-
- while (fgets(line, LOCK_LINE_MAX, file)) {
-
- if (old)
- goto raw;
-
- if (!strncmp(line, "version", 7))
- continue;
-
- if (!strncmp(line, "rsb", 3)) {
- count_rinfo(&summary, &info);
- clear_rinfo(&info);
- printf("\n");
- print_rsb(line, &info);
- continue;
- }
-
- if (!strncmp(line, "lvb", 3)) {
- print_lvb(line);
- info.lvb = 1;
- continue;
- }
-
- if (!strncmp(line, "lkb", 3)) {
- print_lkb(line, &info);
- continue;
- }
- raw:
- printf("%s", line);
- }
- fclose(file);
-
- do_waiters(name, &summary);
-
- if (summarize) {
- printf("\n");
- print_summary(&summary);
- }
-}
-
-static void parse_r_name(char *line, char *name)
-{
- char *p;
- int i = 0;
- int begin = 0;
-
- for (p = line; ; p++) {
- if (*p == '"') {
- if (begin)
- break;
- begin = 1;
- continue;
- }
- if (begin)
- name[i++] = *p;
- }
-}
-
-static void do_lockdump(char *name)
-{
- FILE *file;
- char path[PATH_MAX];
- char line[LOCK_LINE_MAX];
- char r_name[65];
- int r_nodeid;
- int r_len;
- int rv;
- unsigned int time;
- unsigned long long xid;
- uint32_t id;
- int nodeid;
- uint32_t remid;
- int ownpid;
- uint32_t exflags;
- uint32_t flags;
- int8_t status;
- int8_t grmode;
- int8_t rqmode;
-
- snprintf(path, PATH_MAX, "/sys/kernel/debug/dlm/%s_locks", name);
-
- file = fopen(path, "r");
- if (!file) {
- fprintf(stderr, "can't open %s: %s\n", path, strerror(errno));
- return;
- }
-
- /* skip the header on the first line */
- if (!fgets(line, LOCK_LINE_MAX, file))
- return;
-
- while (fgets(line, LOCK_LINE_MAX, file)) {
- rv = sscanf(line, "%x %d %x %u %llu %x %x %hhd %hhd %hhd %u %d %d",
- &id,
- &nodeid,
- &remid,
- &ownpid,
- &xid,
- &exflags,
- &flags,
- &status,
- &grmode,
- &rqmode,
- &time,
- &r_nodeid,
- &r_len);
-
- if (rv != 13) {
- fprintf(stderr, "invalid debugfs line %d: %s\n",
- rv, line);
- return;
- }
-
- memset(r_name, 0, sizeof(r_name));
- parse_r_name(line, r_name);
-
- /* don't print MSTCPY locks without -M */
- if (!r_nodeid && nodeid) {
- if (!dump_mstcpy)
- continue;
- printf("id %08x gr %s rq %s pid %u MSTCPY %d \"%s\"\n",
- id, mode_str(grmode), mode_str(rqmode),
- ownpid, nodeid, r_name);
- continue;
- }
-
- /* A hack because dlm-kernel doesn't set rqmode back to IV when
- a NOQUEUE convert fails, which means in a lockdump it looks
- like a granted lock is still converting since rqmode is not
- IV. (does it make sense to include status in the output,
- e.g. G,C,W?) */
-
- if (status == DLM_LKSTS_GRANTED)
- rqmode = LKM_IVMODE;
-
- printf("id %08x gr %s rq %s pid %u master %d \"%s\"\n",
- id, mode_str(grmode), mode_str(rqmode),
- ownpid, nodeid, r_name);
- }
-
- fclose(file);
-}
-
-static char *dlmc_lf_str(uint32_t flags)
-{
- static char str[128];
- int i = 0;
-
- memset(str, 0, sizeof(str));
-
- if (flags & DLMC_LF_SAVE_PLOCKS) {
- i++;
- strcat(str, "save_plock");
- }
- if (flags & DLMC_LF_NEED_PLOCKS) {
- strcat(str, i++ ? "," : "");
- strcat(str, "need_plock");
- }
- if (flags & DLMC_LF_FS_REGISTERED) {
- strcat(str, i++ ? "," : "");
- strcat(str, "fs_reg");
- }
- if (flags & DLMC_LF_KERNEL_STOPPED) {
- strcat(str, i++ ? "," : "");
- strcat(str, "kern_stop");
- }
- if (flags & DLMC_LF_LEAVING) {
- strcat(str, i++ ? "," : "");
- strcat(str, "leave");
- }
- if (flags & DLMC_LF_JOINING) {
- strcat(str, i++ ? "," : "");
- strcat(str, "join");
- }
-
- return str;
-}
-
-static const char *nf_check_str(uint32_t flags)
-{
- if (flags & DLMC_NF_CHECK_FENCING)
- return "fence";
-
- if (flags & DLMC_NF_CHECK_QUORUM)
- return "quorum";
-
- if (flags & DLMC_NF_CHECK_FS)
- return "fs";
-
- return "none";
-}
-
-static const char *condition_str(int cond)
-{
- switch (cond) {
- case 0:
- return "";
- case 1:
- return "fencing";
- case 2:
- return "quorum";
- case 3:
- return "fs";
- case 4:
- return "pending";
- default:
- return "unknown";
- }
-}
-
-static int node_compare(const void *va, const void *vb)
-{
- const struct dlmc_node *a = va;
- const struct dlmc_node *b = vb;
-
- return a->nodeid - b->nodeid;
-}
-
-static void show_nodeids(int count, struct dlmc_node *nodes_in)
-{
- struct dlmc_node *n = nodes_in;
- int i;
-
- for (i = 0; i < count; i++) {
- printf("%d ", n->nodeid);
- n++;
- }
- printf("\n");
-}
-
-static void show_ls(struct dlmc_lockspace *ls)
-{
- int rv, node_count;
-
- printf("name %s\n", ls->name);
- printf("id 0x%08x\n", ls->global_id);
- printf("flags 0x%08x %s\n",
- ls->flags, dlmc_lf_str(ls->flags));
- printf("change member %d joined %d remove %d failed %d seq %d,%d\n",
- ls->cg_prev.member_count, ls->cg_prev.joined_count,
- ls->cg_prev.remove_count, ls->cg_prev.failed_count,
- ls->cg_prev.combined_seq, ls->cg_prev.seq);
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
- rv = dlmc_lockspace_nodes(ls->name, DLMC_NODES_MEMBERS,
- MAX_NODES, &node_count, nodes);
- if (rv < 0) {
- printf("members error\n");
- goto next;
- }
- qsort(nodes, node_count, sizeof(struct dlmc_node), node_compare);
-
- printf("members ");
- show_nodeids(node_count, nodes);
-
- next:
- if (!ls->cg_next.seq)
- return;
-
- printf("new change member %d joined %d remove %d failed %d seq %d,%d\n",
- ls->cg_next.member_count, ls->cg_next.joined_count,
- ls->cg_next.remove_count, ls->cg_next.failed_count,
- ls->cg_next.combined_seq, ls->cg_next.seq);
-
- printf("new status wait_messages %d wait_condition %d %s\n",
- ls->cg_next.wait_messages, ls->cg_next.wait_condition,
- condition_str(ls->cg_next.wait_condition));
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
- rv = dlmc_lockspace_nodes(ls->name, DLMC_NODES_NEXT,
- MAX_NODES, &node_count, nodes);
- if (rv < 0) {
- printf("new members error\n");
- return;
- }
- qsort(nodes, node_count, sizeof(struct dlmc_node), node_compare);
-
- printf("new members ");
- show_nodeids(node_count, nodes);
-}
-
-static int member_int(struct dlmc_node *n)
-{
- if (n->flags & DLMC_NF_DISALLOWED)
- return -1;
- if (n->flags & DLMC_NF_MEMBER)
- return 1;
- return 0;
-}
-
-static void show_all_nodes(int count, struct dlmc_node *nodes_in)
-{
- struct dlmc_node *n = nodes_in;
- int i;
-
- for (i = 0; i < count; i++) {
- printf("nodeid %d member %d failed %d start %d seq_add %u seq_rem %u check %s\n",
- n->nodeid,
- member_int(n),
- n->failed_reason,
- (n->flags & DLMC_NF_START) ? 1 : 0,
- n->added_seq,
- n->removed_seq,
- nf_check_str(n->flags));
- n++;
- }
-}
-
-static void do_list(char *name)
-{
- struct dlmc_lockspace *ls;
- int node_count;
- int ls_count;
- int rv;
- int i;
-
- memset(lss, 0, sizeof(lss));
-
- if (name) {
- ls_count = 1;
- rv = dlmc_lockspace_info(name, lss);
- } else {
- rv = dlmc_lockspaces(MAX_LS, &ls_count, lss);
- }
-
- if (rv < 0)
- exit(EXIT_FAILURE); /* dlm_controld probably not running */
-
- if (ls_count)
- printf("dlm lockspaces\n");
-
- for (i = 0; i < ls_count; i++) {
- ls = &lss[i];
-
- show_ls(ls);
-
- if (!ls_all_nodes)
- goto next;
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
-
- rv = dlmc_lockspace_nodes(ls->name, DLMC_NODES_ALL,
- MAX_NODES, &node_count, nodes);
- if (rv < 0) {
- printf("all nodes error %d %d\n", rv, errno);
- goto next;
- }
-
- qsort(nodes, node_count, sizeof(struct dlmc_node),node_compare);
-
- printf("all nodes\n");
- show_all_nodes(node_count, nodes);
- next:
- printf("\n");
- }
-}
-
-static void do_deadlock_check(char *name)
-{
- dlmc_deadlock_check(name);
-}
-
-static void do_plocks(char *name)
-{
- char buf[DLMC_DUMP_SIZE];
-
- memset(buf, 0, sizeof(buf));
-
- dlmc_dump_plocks(name, buf);
-
- do_write(STDOUT_FILENO, buf, strlen(buf));
-}
-
-static void do_dump(void)
-{
- char buf[DLMC_DUMP_SIZE];
-
- memset(buf, 0, sizeof(buf));
-
- dlmc_dump_debug(buf);
-
- do_write(STDOUT_FILENO, buf, strlen(buf));
-}
-
-static void do_log_plock(void)
-{
- char buf[DLMC_DUMP_SIZE];
-
- memset(buf, 0, sizeof(buf));
-
- dlmc_dump_log_plock(buf);
-
- do_write(STDOUT_FILENO, buf, strlen(buf));
-}
-
-int main(int argc, char **argv)
-{
- prog_name = argv[0];
- decode_arguments(argc, argv);
-
- switch (operation) {
-
- /* calls to libdlm; pass a command to dlm-kernel */
-
- case OP_JOIN:
- do_join(lsname);
- break;
-
- case OP_LEAVE:
- do_leave(lsname);
- break;
-
- case OP_JOINLEAVE:
- do_join(lsname);
- do_leave(lsname);
- break;
-
- /* calls to libdlmcontrol; pass a command/query to dlm_controld */
-
- case OP_LIST:
- do_list(lsname);
- break;
-
- case OP_DUMP:
- do_dump();
- break;
-
- case OP_LOG_PLOCK:
- do_log_plock();
- break;
-
- case OP_PLOCKS:
- do_plocks(lsname);
- break;
-
- case OP_DEADLOCK_CHECK:
- do_deadlock_check(lsname);
- break;
-
- /* calls to read debugfs; query info from dlm-kernel */
-
- case OP_LOCKDUMP:
- do_lockdump(lsname);
- break;
-
- case OP_LOCKDEBUG:
- do_lockdebug(lsname);
- break;
- }
- return 0;
-}
-
diff --git a/doc/COPYING.applications b/doc/COPYING.applications
deleted file mode 100644
index d511905..0000000
--- a/doc/COPYING.applications
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/doc/COPYING.libraries b/doc/COPYING.libraries
deleted file mode 100644
index 2d2d780..0000000
--- a/doc/COPYING.libraries
+++ /dev/null
@@ -1,510 +0,0 @@
-
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations
-below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it
-becomes a de-facto standard. To achieve this, non-free programs must
-be allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control
-compilation and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at least
- three years, to give the same user the materials specified in
- Subsection 6a, above, for a charge no more than the cost of
- performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply, and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License
-may add an explicit geographical distribution limitation excluding those
-countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms
-of the ordinary General Public License).
-
- To apply these terms, attach the following notices to the library.
-It is safest to attach them to the start of each source file to most
-effectively convey the exclusion of warranty; and each file should
-have at least the "copyright" line and a pointer to where the full
-notice is found.
-
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or
-your school, if any, to sign a "copyright disclaimer" for the library,
-if necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James
- Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/doc/COPYRIGHT b/doc/COPYRIGHT
deleted file mode 100644
index 92b5e30..0000000
--- a/doc/COPYRIGHT
+++ /dev/null
@@ -1,141 +0,0 @@
-Unless specified otherwise in the "exceptions section" below:
-
-Copyright (C) 1997-2003 Sistina Software, Inc. All rights reserved.
-Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
-
-Exceptions:
-
-contrib/libaislock:
- Contributed by Stanley Wang of Intel.
-
-cman/qdisk/crc32.c:
- Copyright (C) 2000 Bryan Call <bc at fodder.org>
- Modified by Lon H. Hohberger <lhh at redhat.com>
- Copyright (C) 2003-2010 Red Hat, Inc. All rights reserved.
-
-cman/qdisk/daemon_init.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author: Jeff Moyer <jmoyer at redhat.com>
-
-cman/qdisk/disk.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author: Tim Burke <tburke at redhat.com>
-
-cman/qdisk/scandisk.{c,h}:
- Original design by: Joel Becker <Joel.Becker at oracle.com> and
- Fabio M. Di Nitto <fdinitto at redhat.com>
-
-cman/daemon/fnvhash.c
- This code is in the public domain.
- Phong Vo (http://www.research.att.com/info/kpv/)
- Glenn Fowler (http://www.research.att.com/~gsf/)
- Landon Curt Noll (http://www.isthe.com/chongo/)
-
-dlm/doc/example.c:
- Author: Daniel Phillips <phillips at redhat.com>
-
-From rgmanager/AUTHORS:
-
-Lon Hohberger lhh at redhat.com
-* Resource tree
-* Failover domains
-* Resource agent scripts
-
-Gregory Myrdal [private]
-* Misc utilities
-* Resource agent scripts
-
-Jeff Moyer jmoyer at redhat.com
-* Syslog wrapper & logging program
-
-Portions of this code (C) 2000-2001 Mission Critical Linux, Inc.
-
-rgmanager/include/clulog.h:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author: Jeff Moyer <moyer at missioncriticallinux.com>
-
-rgmanager/src/clulib/clulog.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author: Jeff Moyer <moyer at missioncriticallinux.com>
-
-rgmanager/src/clulib/daemon_init.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author: Jeff Moyer <moyer at missioncriticallinux.com>
-
-rgmanager/src/clulib/msgsimple.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/clulib/tmgr.c:
- Copyright (C) 2006-2007 Crosswalk.
- Copyright (C) 2007-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/clulib/wrap_lock.c:
- Copyright (C) 2006-2007 Crosswalk.
- Copyright (C) 2007-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/daemons/groups.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/daemons/main.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/utils/clubufflush.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author: Gregory P. Myrdal <Myrdal at MissionCriticalLinux.Com>
-
-rgmanager/src/utils/clufindhostname.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Richard Rabbat <rabbat at missioncriticallinux.com>
-
-rgmanager/src/utils/clulog.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author: Jeff Moyer <moyer at missioncriticallinux.com>
-
-rgmanager/src/utils/syscall.h
- Copyright (C) 1995-1997 Olaf Kirch <okir at monad.swb.de>
- Copyright (C) 1997-2003 Sistina Software, Inc. All rights reserved.
- Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
-
-Authors as known by current RCS as of the time of writing:
-
-Abhijith Das <adas at redhat.com>
-Adam Manthei <amanthei at redhat.com>
-A. J. Lewis <alewis at redhat.com>
-Alasdair G. Kergon <agk at redhat.com>
-Andrew Price <andy at andrewprice.me.uk>
-Benjamin Marzinski <bmarzins at redhat.com>
-Bob Peterson <rpeterso at redhat.com>
-Chris Feist <cfeist at redhat.com>
-Christine Caulfield <ccaulfie at redhat.com>
-Daniel Phillips <phillips at redhat.com>
-David Teigland <teigland at redhat.com>
-Fabio M. Di Nitto <fdinitto at redhat.com>
-James Parsons <jparsons at redhat.com>
-Joel Becker <joel.becker at oracle.com>
-Jonathan Brassow <jbrassow at redhat.com>
-jparsons <jparsons at redhat.com>
-Ken Preslan <kpreslan at redhat.com>
-Lon Hohberger <lhh at redhat.com>
-Marc - A. Dahlhaus <mad at wol.de>
-Marek 'marx' Grac <mgrac at redhat.com>
-Mark Hlawatschek <hlawatschek at atix.de>
-Michael Conrad Tadpol Tilstra <mtilstra at redhat.com>
-Patrick Caulfield <pcaulfie at redhat.com>
-Robert Peterson <rpeterso at redhat.com>
-Ross Vandegrift <ross at kallisti.us>
-Ryan McCabe <rmccabe at redhat.com>
-Ryan O'Hara <rohara at redhat.com>
-Stanko Kupcevic <kupcevic at redhat.com>
-Steven Whitehouse <swhiteho at redhat.com>
-Wendy Cheng <wcheng at redhat.com>
diff --git a/doc/Makefile b/doc/Makefile
deleted file mode 100644
index efc83e6..0000000
--- a/doc/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-DOCS = usage.txt \
- COPYING.applications \
- COPYING.libraries \
- COPYRIGHT \
- README.licence \
- cluster_conf.html
-
-TARGET= cluster
-
-LOGRORATED = $(TARGET)
-
-all: $(TARGET)
-
-include ../make/defines.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-include $(OBJDIR)/make/clean.mk
-
-$(TARGET):
- cat $(S)/$(TARGET).logrotate.in | sed \
- -e 's#@LOGDIR@#${logdir}#g' \
- > $(TARGET)
-
-clean: generalclean
diff --git a/doc/README.licence b/doc/README.licence
deleted file mode 100644
index 075aa77..0000000
--- a/doc/README.licence
+++ /dev/null
@@ -1,33 +0,0 @@
-The Red Hat Cluster is a collection of free software built on top of different
-libraries and applications.
-
-For a detailed list of authors and copyright holders, please check the
-included COPYRIGHT file.
-
-Libraries:
-
-You can redistribute them and/or modify them under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-The libraries are distributed in the hope that they will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details.
-
-Applications:
-
-You can redistribute them and/or modify them under the terms of the GNU General
-Public License as published by the Free Software Foundation; either version
-2 of the License, or (at your option) any later version.
-
-The applications are distributed in the hope that they will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-details.
-
-A copy of each license is included for your convenience in COPYING.applications
-and COPYING.libraries.
-
-If missing, write to the Free Software Foundation, Inc., 51 Franklin St,
-Fifth Floor, Boston, MA 02110-1301 USA.
diff --git a/doc/cluster.logrotate.in b/doc/cluster.logrotate.in
deleted file mode 100644
index bd55cce..0000000
--- a/doc/cluster.logrotate.in
+++ /dev/null
@@ -1,9 +0,0 @@
-@LOGDIR@/*log {
- missingok
- compress
- copytruncate
- daily
- rotate 31
- minsize 2048
- notifempty
-}
diff --git a/doc/cluster_conf.html b/doc/cluster_conf.html
deleted file mode 100644
index ab857f1..0000000
--- a/doc/cluster_conf.html
+++ /dev/null
@@ -1,1212 +0,0 @@
-<html>
-<h2><a name="toc_tree_reference"/>Tree Structure Reference</h2>
-<small><a href="#toc_tag_reference">Jump to Tag Reference</a></small><br/><br/>
-<<a href="#tag_cluster">cluster</a> ...><br/>
- <<a href="#tag_cman">cman</a> ...><br/>
- <<a href="#tag_multicast">multicast</a> .../><br/>
- <<a href="#tag_cman">/cman</a>><br/>
- <<a href="#tag_totem">totem</a> ...><br/>
- <<a href="#tag_interface">interface</a> .../><br/>
- <<a href="#tag_totem">/totem</a>><br/>
- <<a href="#tag_quorumd">quorumd</a> ...><br/>
- <<a href="#tag_heuristic">heuristic</a> .../><br/>
- <<a href="#tag_quorumd">/quorumd</a>><br/>
- <<a href="#tag_fence_daemon">fence_daemon</a> .../><br/>
- <<a href="#tag_fence_xvmd">fence_xvmd</a> .../><br/>
- <<a href="#tag_dlm">dlm</a> ...><br/>
- <<a href="#tag_lockspace">lockspace</a> ...><br/>
- <<a href="#tag_master">master</a> .../><br/>
- <<a href="#tag_lockspace">/lockspace</a>><br/>
- <<a href="#tag_dlm">/dlm</a>><br/>
- <<a href="#tag_gfs_controld">gfs_controld</a> .../><br/>
- <<a href="#tag_group">group</a> .../><br/>
- <<a href="#tag_logging">logging</a> ...><br/>
- <<a href="#tag_logging_daemon">logging_daemon</a> .../><br/>
- <<a href="#tag_logging">/logging</a>><br/>
- <<a href="#tag_clusternodes">clusternodes</a>><br/>
- <<a href="#tag_clusternode">clusternode</a> ...><br/>
- <<a href="#tag_altname">altname</a> .../><br/>
- <a href="#ref_FENCE">FENCE</a><br/>
- <a href="#ref_UNFENCE">UNFENCE</a><br/>
- <<a href="#tag_clusternode">/clusternode</a>><br/>
- <<a href="#tag_clusternodes">/clusternodes</a>><br/>
- <<a href="#tag_fencedevices">fencedevices</a>><br/>
- <<a href="#tag_fencedevice">fencedevice</a> ...><br/>
- <a href="#ref_FENCEDEVICEOPTIONS">FENCEDEVICEOPTIONS</a><br/>
- <<a href="#tag_fencedevice">/fencedevice</a>><br/>
- <<a href="#tag_fencedevices">/fencedevices</a>><br/>
- <<a href="#tag_rm">rm</a> ...><br/>
- <<a href="#tag_failoverdomains">failoverdomains</a>><br/>
- <<a href="#tag_failoverdomain">failoverdomain</a> ...><br/>
- <<a href="#tag_failoverdomainnode">failoverdomainnode</a> .../><br/>
- <<a href="#tag_failoverdomain">/failoverdomain</a>><br/>
- <<a href="#tag_failoverdomains">/failoverdomains</a>><br/>
- <<a href="#tag_events">events</a>><br/>
- <<a href="#tag_event">event</a> .../><br/>
- <<a href="#tag_events">/events</a>><br/>
- <<a href="#tag_resources">resources</a>><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_resources">/resources</a>><br/>
- <<a href="#tag_resource-defaults">resource-defaults</a>><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_resource-defaults">/resource-defaults</a>><br/>
- <a href="#ref_SERVICE">SERVICE</a><br/>
- <a href="#ref_VM">VM</a><br/>
- <<a href="#tag_rm">/rm</a>><br/>
- <<a href="#tag_clvmd">clvmd</a> .../><br/>
-<<a href="#tag_cluster">/cluster</a>><br/>
-<br/><a name="ref_SERVICE"/>SERVICE definition<br/>
- <<a href="#tag_service">service</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_service">/service</a>><br/>
-<br/><a name="ref_IP"/>IP definition<br/>
- <<a href="#tag_ip">ip</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_ip">/ip</a>><br/>
-<br/><a name="ref_NFSCLIENT"/>NFSCLIENT definition<br/>
- <<a href="#tag_nfsclient">nfsclient</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_nfsclient">/nfsclient</a>><br/>
-<br/><a name="ref_NFSEXPORT"/>NFSEXPORT definition<br/>
- <<a href="#tag_nfsexport">nfsexport</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_nfsexport">/nfsexport</a>><br/>
-<br/><a name="ref_SCRIPT"/>SCRIPT definition<br/>
- <<a href="#tag_script">script</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_script">/script</a>><br/>
-<br/><a name="ref_NETFS"/>NETFS definition<br/>
- <<a href="#tag_netfs">netfs</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_netfs">/netfs</a>><br/>
-<br/><a name="ref_CLUSTERFS"/>CLUSTERFS definition<br/>
- <<a href="#tag_clusterfs">clusterfs</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_clusterfs">/clusterfs</a>><br/>
-<br/><a name="ref_SMB"/>SMB definition<br/>
- <<a href="#tag_smb">smb</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_smb">/smb</a>><br/>
-<br/><a name="ref_APACHE"/>APACHE definition<br/>
- <<a href="#tag_apache">apache</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_apache">/apache</a>><br/>
-<br/><a name="ref_OPENLDAP"/>OPENLDAP definition<br/>
- <<a href="#tag_openldap">openldap</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_openldap">/openldap</a>><br/>
-<br/><a name="ref_SAMBA"/>SAMBA definition<br/>
- <<a href="#tag_samba">samba</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_samba">/samba</a>><br/>
-<br/><a name="ref_MYSQL"/>MYSQL definition<br/>
- <<a href="#tag_mysql">mysql</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_mysql">/mysql</a>><br/>
-<br/><a name="ref_POSTGRES-8"/>POSTGRES-8 definition<br/>
- <<a href="#tag_postgres-8">postgres-8</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_postgres-8">/postgres-8</a>><br/>
-<br/><a name="ref_TOMCAT-5"/>TOMCAT-5 definition<br/>
- <<a href="#tag_tomcat-5">tomcat-5</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_tomcat-5">/tomcat-5</a>><br/>
-<br/><a name="ref_TOMCAT-6"/>TOMCAT-6 definition<br/>
- <<a href="#tag_tomcat-6">tomcat-6</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_tomcat-6">/tomcat-6</a>><br/>
-<br/><a name="ref_LVM"/>LVM definition<br/>
- <<a href="#tag_lvm">lvm</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_lvm">/lvm</a>><br/>
-<br/><a name="ref_VM"/>VM definition<br/>
- <<a href="#tag_vm">vm</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_vm">/vm</a>><br/>
-<br/><a name="ref_SAPINSTANCE"/>SAPINSTANCE definition<br/>
- <<a href="#tag_SAPInstance">SAPInstance</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_SAPInstance">/SAPInstance</a>><br/>
-<br/><a name="ref_SAPDATABASE"/>SAPDATABASE definition<br/>
- <<a href="#tag_SAPDatabase">SAPDatabase</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_SAPDatabase">/SAPDatabase</a>><br/>
-<br/><a name="ref_NAMED"/>NAMED definition<br/>
- <<a href="#tag_named">named</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_named">/named</a>><br/>
-<br/><a name="ref_ASEHAAGENT"/>ASEHAAGENT definition<br/>
- <<a href="#tag_ASEHAagent">ASEHAagent</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_ASEHAagent">/ASEHAagent</a>><br/>
-<br/><a name="ref_DRBD"/>DRBD definition<br/>
- <<a href="#tag_drbd">drbd</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_drbd">/drbd</a>><br/>
-<br/><a name="ref_NFSSERVER"/>NFSSERVER definition<br/>
- <<a href="#tag_nfsserver">nfsserver</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_nfsserver">/nfsserver</a>><br/>
-<br/><a name="ref_FS"/>FS definition<br/>
- <<a href="#tag_fs">fs</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_fs">/fs</a>><br/>
-<br/><a name="ref_ORACLEDB"/>ORACLEDB definition<br/>
- <<a href="#tag_oracledb">oracledb</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_oracledb">/oracledb</a>><br/>
-<br/><a name="ref_CHILDREN"/>CHILDREN definition<br/>
- <a href="#ref_SERVICE">SERVICE</a><br/>
- <a href="#ref_IP">IP</a><br/>
- <a href="#ref_NFSCLIENT">NFSCLIENT</a><br/>
- <a href="#ref_NFSEXPORT">NFSEXPORT</a><br/>
- <a href="#ref_SCRIPT">SCRIPT</a><br/>
- <a href="#ref_NETFS">NETFS</a><br/>
- <a href="#ref_CLUSTERFS">CLUSTERFS</a><br/>
- <a href="#ref_SMB">SMB</a><br/>
- <a href="#ref_APACHE">APACHE</a><br/>
- <a href="#ref_OPENLDAP">OPENLDAP</a><br/>
- <a href="#ref_SAMBA">SAMBA</a><br/>
- <a href="#ref_MYSQL">MYSQL</a><br/>
- <a href="#ref_POSTGRES-8">POSTGRES-8</a><br/>
- <a href="#ref_TOMCAT-5">TOMCAT-5</a><br/>
- <a href="#ref_TOMCAT-6">TOMCAT-6</a><br/>
- <a href="#ref_LVM">LVM</a><br/>
- <a href="#ref_VM">VM</a><br/>
- <a href="#ref_SAPINSTANCE">SAPINSTANCE</a><br/>
- <a href="#ref_SAPDATABASE">SAPDATABASE</a><br/>
- <a href="#ref_NAMED">NAMED</a><br/>
- <a href="#ref_ASEHAAGENT">ASEHAAGENT</a><br/>
- <a href="#ref_DRBD">DRBD</a><br/>
- <a href="#ref_NFSSERVER">NFSSERVER</a><br/>
- <a href="#ref_FS">FS</a><br/>
- <a href="#ref_ORACLEDB">ORACLEDB</a><br/>
- <a href="#ref_RESOURCEACTION">RESOURCEACTION</a><br/>
-<br/><a name="ref_RESOURCEACTION"/>RESOURCEACTION definition<br/>
- <<a href="#tag_action">action</a> .../><br/>
-<br/><a name="ref_FENCE"/>FENCE definition<br/>
- <<a href="#tag_fence">fence</a>><br/>
- <<a href="#tag_method">method</a> ...><br/>
- <a href="#ref_DEVICE">DEVICE</a><br/>
- <<a href="#tag_method">/method</a>><br/>
- <<a href="#tag_fence">/fence</a>><br/>
-<br/><a name="ref_UNFENCE"/>UNFENCE definition<br/>
- <<a href="#tag_unfence">unfence</a>><br/>
- <a href="#ref_DEVICE">DEVICE</a><br/>
- <<a href="#tag_unfence">/unfence</a>><br/>
-<br/><a name="ref_DEVICE"/>DEVICE definition<br/>
- <<a href="#tag_device">device</a> ...><br/>
- <a href="#ref_FENCEDEVICEOPTIONS">FENCEDEVICEOPTIONS</a><br/>
- <<a href="#tag_device">/device</a>><br/>
-<br/><a name="ref_FENCEDEVICEOPTIONS"/>FENCEDEVICEOPTIONS definition<br/>
-<h2>Tag Reference<a name="toc_tag_reference"/></h2><small><a href="#toc_tree_reference">Jump to Tree Structure Reference</a></small><br/><br/>
-<table>
-<tr valign="top"><td><a href="#tag_action"><b>action</b></a></td><td>Overrides resource action timings for a resource instance.</td></tr>
-<tr valign="top"><td><a href="#tag_altname"><b>altname</b></a></td><td>Defines a second network interface to use for corosync redundant ring mode. cman(5)</td></tr>
-<tr valign="top"><td><a href="#tag_apache"><b>apache</b></a></td><td>Defines an Apache web server</td></tr>
-<tr valign="top"><td><a href="#tag_ASEHAagent"><b>ASEHAagent</b></a></td><td>Sybase ASE Failover Instance</td></tr>
-<tr valign="top"><td><a href="#tag_cluster"><b>cluster</b></a></td><td>Defines cluster properties, and contains all other configuration. cluster.conf(5)</td></tr>
-<tr valign="top"><td><a href="#tag_clusterfs"><b>clusterfs</b></a></td><td>Defines a cluster file system mount.</td></tr>
-<tr valign="top"><td><a href="#tag_clusternode"><b>clusternode</b></a></td><td>Defines cluster node properties, and contains other node specific configuration. cluster.conf(5)</td></tr>
-<tr valign="top"><td><a href="#tag_clusternodes"><b>clusternodes</b></a></td><td>Contains all cluster node definitions. cluster.conf(5)</td></tr>
-<tr valign="top"><td><a href="#tag_clvmd"><b>clvmd</b></a></td><td>The clvmd element contains attributes that define parameters for the cluster LVM daemon.</td></tr>
-<tr valign="top"><td><a href="#tag_cman"><b>cman</b></a></td><td>The cman element contains attributes that define the following cluster-wide parameters and behaviors: whether the cluster is a two-node cluster, expected votes, user-specified multicast address, and logging.</td></tr>
-<tr valign="top"><td><a href="#tag_device"><b>device</b></a></td><td>Defines the properties of a device used for fencing or unfencing a node. fenced(8)</td></tr>
-<tr valign="top"><td><a href="#tag_dlm"><b>dlm</b></a></td><td>Configuration for dlm and dlm_controld daemon. dlm_controld(8)</td></tr>
-<tr valign="top"><td><a href="#tag_drbd"><b>drbd</b></a></td><td>This is a DRBD resource.</td></tr>
-<tr valign="top"><td><a href="#tag_event"><b>event</b></a></td><td>Defines an event.</td></tr>
-<tr valign="top"><td><a href="#tag_events"><b>events</b></a></td><td>Event definitions (central_processing only).</td></tr>
-<tr valign="top"><td><a href="#tag_failoverdomain"><b>failoverdomain</b></a></td><td>Specifies properties of a specific failover domain</td></tr>
-<tr valign="top"><td><a href="#tag_failoverdomainnode"><b>failoverdomainnode</b></a></td><td>A node in a failover domain</td></tr>
-<tr valign="top"><td><a href="#tag_failoverdomains"><b>failoverdomains</b></a></td><td>Failover domain definitions.</td></tr>
-<tr valign="top"><td><a href="#tag_fence"><b>fence</b></a></td><td>Contains methods for fencing the node in different ways. fenced(8)</td></tr>
-<tr valign="top"><td><a href="#tag_fencedevice"><b>fencedevice</b></a></td><td>Defines fence device properties. fenced(8)</td></tr>
-<tr valign="top"><td><a href="#tag_fencedevices"><b>fencedevices</b></a></td><td>Contains all fence device definitions. fenced(8)</td></tr>
-<tr valign="top"><td><a href="#tag_fence_daemon"><b>fence_daemon</b></a></td><td>Configuration for fenced daemon. fenced(8)</td></tr>
-<tr valign="top"><td><a href="#tag_fence_xvmd"><b>fence_xvmd</b></a></td><td>Fence_xvm daemon. The fence_xvmd fence device is an I/O fencing host that resides on dom0 and is used in conjunction with the fence_xvm fencing agent. Together, these two programs fence Xen virtual machines that are in a cluster. There is a requirement that the parent dom0s are also a part of their own CMAN/OpenAIS based cluster, and that the dom0 cluster does not share any members with the domU cluster. Furthermore, the dom0 cluster is required to have fencing if domU recovery is expected to be automatic.</td></tr>
-<tr valign="top"><td><a href="#tag_fs"><b>fs</b></a></td><td>Defines a file system mount.</td></tr>
-<tr valign="top"><td><a href="#tag_gfs_controld"><b>gfs_controld</b></a></td><td>Configuration for gfs_controld daemon. gfs_controld(8)</td></tr>
-<tr valign="top"><td><a href="#tag_group"><b>group</b></a></td><td>Defines groupd configuration. groupd(8)</td></tr>
-<tr valign="top"><td><a href="#tag_heuristic"><b>heuristic</b></a></td><td>Defines a heuristic. qdisk(5).</td></tr>
-<tr valign="top"><td><a href="#tag_interface"><b>interface</b></a></td><td>Defines Totem interface options. corosync.conf(5)</td></tr>
-<tr valign="top"><td><a href="#tag_ip"><b>ip</b></a></td><td>This is an IP address.</td></tr>
-<tr valign="top"><td><a href="#tag_lockspace"><b>lockspace</b></a></td><td>Individual lockspace configuration. dlm_controld(8)</td></tr>
-<tr valign="top"><td><a href="#tag_logging"><b>logging</b></a></td><td>Defines global logging configuration, and contains daemon-specific configuration. cluster.conf(5)</td></tr>
-<tr valign="top"><td><a href="#tag_logging_daemon"><b>logging_daemon</b></a></td><td>Defines daemon-specific logging configuration. cluster.conf(5)</td></tr>
-<tr valign="top"><td><a href="#tag_lvm"><b>lvm</b></a></td><td>LVM Failover script</td></tr>
-<tr valign="top"><td><a href="#tag_master"><b>master</b></a></td><td>Defines a master node. dlm_controld(8)</td></tr>
-<tr valign="top"><td><a href="#tag_method"><b>method</b></a></td><td>Contains one or more devices for fencing the node a single way. fenced(8)</td></tr>
-<tr valign="top"><td><a href="#tag_multicast"><b>multicast</b></a></td><td>The multicast element provides the ability for a user to specify a multicast address instead of using the multicast address generated by cman. If a user does not specify a multicast address, cman creates one. It forms the upper 16 bits of the multicast address with 239.192 and forms the lower 16 bits based on the cluster ID.</td></tr>
-<tr valign="top"><td><a href="#tag_mysql"><b>mysql</b></a></td><td>Defines a MySQL database server</td></tr>
-<tr valign="top"><td><a href="#tag_named"><b>named</b></a></td><td>Defines an instance of named server</td></tr>
-<tr valign="top"><td><a href="#tag_netfs"><b>netfs</b></a></td><td>Defines an NFS/CIFS file system mount.</td></tr>
-<tr valign="top"><td><a href="#tag_nfsclient"><b>nfsclient</b></a></td><td>Defines an NFS client.</td></tr>
-<tr valign="top"><td><a href="#tag_nfsexport"><b>nfsexport</b></a></td><td>This defines an NFS export.</td></tr>
-<tr valign="top"><td><a href="#tag_nfsserver"><b>nfsserver</b></a></td><td>This defines an NFS server resource.</td></tr>
-<tr valign="top"><td><a href="#tag_openldap"><b>openldap</b></a></td><td>Defines an Open LDAP server</td></tr>
-<tr valign="top"><td><a href="#tag_oracledb"><b>oracledb</b></a></td><td>Oracle 10g Failover Instance</td></tr>
-<tr valign="top"><td><a href="#tag_postgres-8"><b>postgres-8</b></a></td><td>Defines a PostgreSQL server</td></tr>
-<tr valign="top"><td><a href="#tag_quorumd"><b>quorumd</b></a></td><td>This element and its attributes define parameters for the quorum disk daemon, quorumd. qdisk(5).</td></tr>
-<tr valign="top"><td><a href="#tag_resources"><b>resources</b></a></td><td>Defines global resources which may be referenced in services. You may redefine actions for resources here, but child resource definitions are ignored in this section.</td></tr>
-<tr valign="top"><td><a href="#tag_resource-defaults"><b>resource-defaults</b></a></td><td>This section allows the administrator to change defaults for resource agents. Overriding parameters which must be unique is not allowed. Overriding a value which, by default, inherits a value from a parent resource will disable inheritance for that resource type.</td></tr>
-<tr valign="top"><td><a href="#tag_rm"><b>rm</b></a></td><td>This element and its attributes define resources (for example an IP address) required to create HA cluster services, the HA cluster services themselves, and failover domains for the HA cluster services.</td></tr>
-<tr valign="top"><td><a href="#tag_samba"><b>samba</b></a></td><td>Dynamic smbd/nmbd resource agent</td></tr>
-<tr valign="top"><td><a href="#tag_SAPDatabase"><b>SAPDatabase</b></a></td><td>SAP database resource agent</td></tr>
-<tr valign="top"><td><a href="#tag_SAPInstance"><b>SAPInstance</b></a></td><td>SAP instance resource agent</td></tr>
-<tr valign="top"><td><a href="#tag_script"><b>script</b></a></td><td>LSB-compliant init script as a clustered resource.</td></tr>
-<tr valign="top"><td><a href="#tag_service"><b>service</b></a></td><td>Defines a service (resource group).</td></tr>
-<tr valign="top"><td><a href="#tag_smb"><b>smb</b></a></td><td>Dynamic smbd/nmbd resource agent</td></tr>
-<tr valign="top"><td><a href="#tag_tomcat-5"><b>tomcat-5</b></a></td><td>Defines a Tomcat server</td></tr>
-<tr valign="top"><td><a href="#tag_tomcat-6"><b>tomcat-6</b></a></td><td>Defines a Tomcat server</td></tr>
-<tr valign="top"><td><a href="#tag_totem"><b>totem</b></a></td><td>OpenAIS msg transport protocol</td></tr>
-<tr valign="top"><td><a href="#tag_unfence"><b>unfence</b></a></td><td>Contains devices for unfencing the node. fence_node(8)</td></tr>
-<tr valign="top"><td><a href="#tag_vm"><b>vm</b></a></td><td>Defines a Virtual Machine</td></tr>
-</table>
-<hr/>
-<h3><a name="tag_action"/>action</h3>
-Overrides resource action timings for a resource instance.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. Name of resource action (start, stop, status, etc.).</td></tr>
- <tr><td><b>depth</b></td><td>Status check depth (resource agent dependent; * = all depths).</td></tr>
- <tr><td><b>interval</b></td><td>Status check interval.</td></tr>
- <tr><td><b>timeout</b></td><td>Action timeout. Meaningless unless __enforce_timeouts is set for this resource.</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_altname"/>altname</h3>
-Defines a second network interface to use for corosync redundant ring mode. cman(5)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. A second hostname or IP address of the node. cman(5)</td></tr>
- <tr><td><b>mcast</b></td><td>The multicast address to use on the second interface. cman(5)</td></tr>
- <tr><td><b>port</b></td><td>The network port to use on the second interface. cman(5)</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_apache"/>apache</h3>
-Defines an Apache web server<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_file</b></td><td>Initial ServerConfigFile</td></tr>
- <tr><td><b>httpd_options</b></td><td>Other command-line options for httpd</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing apache resource in the resources section.</td></tr>
- <tr><td><b>server_root</b></td><td>Initial ServerRoot</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>shutdown_wait</b></td><td>Wait X seconds for correct end of service shutdown</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_ASEHAagent"/>ASEHAagent</h3>
-Sybase ASE Failover Instance<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>deep_probe_timeout</b></td><td>Deep probe timeout value</td></tr>
- <tr><td><b>interfaces_file</b></td><td>Interfaces file</td></tr>
- <tr><td><b>login_file</b></td><td>Login file</td></tr>
- <tr><td><b>name</b></td><td>name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing ASEHAagent resource in the resources section.</td></tr>
- <tr><td><b>server_name</b></td><td>ASE server name</td></tr>
- <tr><td><b>shutdown_timeout</b></td><td>Shutdown timeout value</td></tr>
- <tr><td><b>start_timeout</b></td><td>Start timeout value</td></tr>
- <tr><td><b>sybase_ase</b></td><td>SYBASE_ASE directory name</td></tr>
- <tr><td><b>sybase_home</b></td><td>SYBASE home directory</td></tr>
- <tr><td><b>sybase_ocs</b></td><td>SYBASE_OCS directory name</td></tr>
- <tr><td><b>sybase_user</b></td><td>Sybase user</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_cluster"/>cluster</h3>
-Defines cluster properties, and contains all other configuration. cluster.conf(5)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_version</b></td><td>Required. Revision level of cluster.conf file. cluster.conf(5)</td></tr>
- <tr><td><b>name</b></td><td>Required. Name of the cluster. cluster.conf(5)</td></tr>
-</table><br/>
-Children: <a href="#tag_cman">cman</a> <a href="#tag_totem">totem</a> <a href="#tag_quorumd">quorumd</a> <a href="#tag_fence_daemon">fence_daemon</a> <a href="#tag_fence_xvmd">fence_xvmd</a> <a href="#tag_dlm">dlm</a> <a href="#tag_gfs_controld">gfs_controld</a> <a href="#tag_group">group</a> <a href="#tag_logging">logging</a> <a href="#tag_clusternodes">clusternodes</a> <a href="#tag_fencedevices">fencedevices</a> <a href="#tag_rm">rm</a> <a href="#tag_clvmd">clvmd</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_clusterfs"/>clusterfs</h3>
-Defines a cluster file system mount.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>device</b></td><td>Device or Label</td></tr>
- <tr><td><b>force_unmount</b></td><td>Force Unmount</td></tr>
- <tr><td><b>fsid</b></td><td>NFS File system ID</td></tr>
- <tr><td><b>fstype</b></td><td>File system type</td></tr>
- <tr><td><b>mountpoint</b></td><td>Mount Point</td></tr>
- <tr><td><b>name</b></td><td>File System Name</td></tr>
- <tr><td><b>nfslock</b></td><td>Enable NFS lock workarounds</td></tr>
- <tr><td><b>options</b></td><td>Mount Options</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing clusterfs resource in the resources section.</td></tr>
- <tr><td><b>self_fence</b></td><td>Seppuku Unmount</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_clusternode"/>clusternode</h3>
-Defines cluster node properties, and contains other node specific configuration. cluster.conf(5)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. The hostname or IP address of the node. cluster.conf(5)</td></tr>
- <tr><td><b>nodeid</b></td><td>Required. A unique integer to use as a node identifier. cluster.conf(5)</td></tr>
- <tr><td><b>votes</b></td><td>The number of votes the node contributes to quorum. cman(5)</td></tr>
- <tr><td><b>weight</b></td><td>The dlm locking weight. dlm_controld(8)</td></tr>
-</table><br/>
-Children: <a href="#tag_altname">altname</a> <a href="#ref_FENCE">FENCE</a> <a href="#ref_UNFENCE">UNFENCE</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_clusternodes"/>clusternodes</h3>
-Contains all cluster node definitions. cluster.conf(5)<br/>
-<br/>
-Children: <a href="#tag_clusternode">clusternode</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_clvmd"/>clvmd</h3>
-The clvmd element contains attributes that define parameters for the cluster LVM daemon.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>interface</b></td><td>The interface attribute tells clvmd which cluster interface it should use for internode communications and locking. Valid values for this depend on how the daemon is configured at compile-time, but are typically cman, corosync or openais.</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_cman"/>cman</h3>
-The cman element contains attributes that define the following cluster-wide parameters and behaviors: whether the cluster is a two-node cluster, expected votes, user-specified multicast address, and logging.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>broadcast</b></td><td>enable cman broadcast</td></tr>
- <tr><td><b>ccsd_poll</b></td><td></td></tr>
- <tr><td><b>cluster_id</b></td><td> </td></tr>
- <tr><td><b>debug_mask</b></td><td></td></tr>
- <tr><td><b>disable_openais</b></td><td> </td></tr>
- <tr><td><b>disallowed</b></td><td>Set this to 1 enable cman's Disallowed mode. This is usually only needed for backwards compatibility.</td></tr>
- <tr><td><b>expected_votes</b></td><td>The expected votes value is used by cman to determine quorum. The cluster is quorate if the sum of votes of 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 overriden by setting an explicit expected_votes value.</td></tr>
- <tr><td><b>hash_cluster_id</b></td><td>Enable stronger hashing of cluster ID to avoid collisions.</td></tr>
- <tr><td><b>keyfile</b></td><td></td></tr>
- <tr><td><b>nodename</b></td><td>Local node name; this is set internally by cman-preconfig and should never be set by a user.</td></tr>
- <tr><td><b>port</b></td><td> </td></tr>
- <tr><td><b>quorum_dev_poll</b></td><td>The amount of time after a qdisk poll, in milliseconds, before a quorum disk is considered dead. The quorum disk daemon, qdisk, periodically sends hello messages to cman and ais, indicating that qdisk is present. If qdisk takes more time to send a hello message to cman and ais than by quorum_dev_poll, then cman declares qdisk dead and prints a message indicating that connection to the quorum device has been lost.</td></tr>
- <tr><td><b>shutdown_timeout</b></td><td>Timeout period, in milliseconds, to allow a service to respond during a shutdown.</td></tr>
- <tr><td><b>two_node</b></td><td>The two_node attribute allows you to configure a cluster with only two nodes. Ordinarily, the loss of quorum after one of two nodes fails prevents the remaining node from continuing (if both nodes have one vote.) To enable a two-node cluster, set the two_node value equal to 1. If the two_node value is enabled, the expected_votes value must be set to 1.</td></tr>
- <tr><td><b>upgrading</b></td><td>Set this if you are performing a rolling upgrade of the cluster between major releases.</td></tr>
-</table><br/>
-Children: <a href="#tag_multicast">multicast</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_device"/>device</h3>
-Defines the properties of a device used for fencing or unfencing a node. fenced(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. The name of a fencedevice defined in the fencedevices section. fenced(8)</td></tr>
- <tr><td><b>action</b></td><td>Fencing action to take (off or on).</td></tr>
- <tr><td><b>aptpl</b></td><td></td></tr>
- <tr><td><b>auth</b></td><td>For IPMI LAN only. Authentication Type: none, password, md2, or md5</td></tr>
- <tr><td><b>channel_address</b></td><td>VM Channel IP address (default=10.0.2.179)</td></tr>
- <tr><td><b>cmd_prompt</b></td><td>Force command prompt</td></tr>
- <tr><td><b>community</b></td><td>Set the community string</td></tr>
- <tr><td><b>cserver</b></td><td>The hostname (and optionally the username in the form of username@hostname) assigned to the device. Refer to the fence_egenera(8) man page for more information.</td></tr>
- <tr><td><b>debug</b></td><td>Specify (stdin) or increment (command line) debug level</td></tr>
- <tr><td><b>delay</b></td><td>Wait this many seconds before fencing is started. fence_egenera(8)</td></tr>
- <tr><td><b>device</b></td><td>The device the switch is connected to on the controlling host.</td></tr>
- <tr><td><b>devices</b></td><td>List of devices to fence (separated by commas).</td></tr>
- <tr><td><b>domain</b></td><td>Virtual Machine (domain name) to fence (deprecated)</td></tr>
- <tr><td><b>drac_version</b></td><td>Force DRAC version to use</td></tr>
- <tr><td><b>esh</b></td><td>Path to the esh command on the cserver. fence_egenera(8)</td></tr>
- <tr><td><b>exec</b></td><td>Command to execute</td></tr>
- <tr><td><b>hash</b></td><td>Packet hash strength (none, sha1, [sha256], sha512)</td></tr>
- <tr><td><b>help</b></td><td>Display help and exit</td></tr>
- <tr><td><b>hmc_version</b></td><td>Force HMC version to use (3 or 4)</td></tr>
- <tr><td><b>identity_file</b></td><td>Identity file for ssh</td></tr>
- <tr><td><b>inet4_only</b></td><td>Forces agent to use IPv4 addresses only</td></tr>
- <tr><td><b>inet6_only</b></td><td>Forces agent to use IPv6 addresses only</td></tr>
- <tr><td><b>io_fencing</b></td><td>Fencing Action</td></tr>
- <tr><td><b>ipaddr</b></td><td>IP address or the name of the device.</td></tr>
- <tr><td><b>ipport</b></td><td>Multicast or VMChannel IP port (default=1229)</td></tr>
- <tr><td><b>ip_family</b></td><td>IP Family ([auto], ipv4, ipv6)</td></tr>
- <tr><td><b>key</b></td><td></td></tr>
- <tr><td><b>key_file</b></td><td>Shared key file (default=/etc/cluster/fence_xvm.key)</td></tr>
- <tr><td><b>lanplus</b></td><td>For IPMI LAN only. Set value to either True or 1; leave out for false.</td></tr>
- <tr><td><b>logfile</b></td><td>Location to output logs from fence_scsi.</td></tr>
- <tr><td><b>login</b></td><td>The login name used to access the device. </td></tr>
- <tr><td><b>login_timeout</b></td><td>Wait X seconds for cmd prompt after login</td></tr>
- <tr><td><b>lpan</b></td><td>The lpan to operate on. fence_egenera(8)</td></tr>
- <tr><td><b>managed</b></td><td>Managed system name</td></tr>
- <tr><td><b>missing_as_off</b></td><td>Missing port returns OFF instead of failure</td></tr>
- <tr><td><b>module_name</b></td><td>DRAC/MC module name</td></tr>
- <tr><td><b>multicast_address</b></td><td>Multicast address (default=225.0.0.12 / ff05::3:1)</td></tr>
- <tr><td><b>nodename</b></td><td>Name of the node to be fenced. Refer to fence_scsi(8) for more information.</td></tr>
- <tr><td><b>option</b></td><td> </td></tr>
- <tr><td><b>partition</b></td><td>Partition name</td></tr>
- <tr><td><b>passwd</b></td><td>The password used to authenticate the connection to the device.</td></tr>
- <tr><td><b>passwd_script</b></td><td>The script that supplies a password for access to the fence device. Using this supersedes the Password parameter.</td></tr>
- <tr><td><b>port</b></td><td>The switch outlet number.</td></tr>
- <tr><td><b>power_timeout</b></td><td>Test X seconds for status change after ON/OFF</td></tr>
- <tr><td><b>power_wait</b></td><td>Wait X seconds after issuing ON/OFF</td></tr>
- <tr><td><b>pserver</b></td><td>The pserver to operate on. fence_egenera(8)</td></tr>
- <tr><td><b>quiet</b></td><td>Supress output</td></tr>
- <tr><td><b>retrans</b></td><td>Multicast retransmit time (in 1/10sec; default=20)</td></tr>
- <tr><td><b>retry_on</b></td><td>Count of attempts to retry power on</td></tr>
- <tr><td><b>ribcl</b></td><td>Force ribcl version to use</td></tr>
- <tr><td><b>rpowerpath</b></td><td></td></tr>
- <tr><td><b>secure</b></td><td>SSH connection</td></tr>
- <tr><td><b>separator</b></td><td>Separator for CSV created by operation list</td></tr>
- <tr><td><b>serial_device</b></td><td>Serial device (default=/dev/ttyS1)</td></tr>
- <tr><td><b>serial_params</b></td><td>Serial Parameters (default=115200,8N1)</td></tr>
- <tr><td><b>servers</b></td><td>The hostname of each GNBD to disable. For multiple hostnames, separate each hostname with a space.</td></tr>
- <tr><td><b>shell_timeout</b></td><td>Wait X seconds for cmd promprt after issuing command</td></tr>
- <tr><td><b>snmp_auth_prot</b></td><td>Set authentication protocol (MD5|SHA)</td></tr>
- <tr><td><b>snmp_priv_passwd</b></td><td>Set privacy protocol password</td></tr>
- <tr><td><b>snmp_priv_passwd_script</b></td><td>Script to run to retrieve privacy password</td></tr>
- <tr><td><b>snmp_priv_prot</b></td><td>Set privacy protocol (DES|AES)</td></tr>
- <tr><td><b>snmp_sec_level</b></td><td>Set security level (noAuthNoPriv|authNoPriv|authPriv)</td></tr>
- <tr><td><b>snmp_version</b></td><td>Specifies SNMP version to use (1,2c,3)</td></tr>
- <tr><td><b>ssl</b></td><td>SSL connection</td></tr>
- <tr><td><b>switch</b></td><td>Physical switch number on device</td></tr>
- <tr><td><b>timeout</b></td><td>Fencing timeout (in seconds; default=30)</td></tr>
- <tr><td><b>udpport</b></td><td>UDP/TCP port to use for connection with device</td></tr>
- <tr><td><b>user</b></td><td>See fence_egenera(8)</td></tr>
- <tr><td><b>use_uuid</b></td><td>Treat [domain] as UUID instead of domain name. This is provided for compatibility with older fence_xvmd installations.</td></tr>
- <tr><td><b>verbose</b></td><td>Verbose mode</td></tr>
- <tr><td><b>version</b></td><td>Display version information and exit</td></tr>
- <tr><td><b>vmware_datacenter</b></td><td>Show only machines in specified datacenter</td></tr>
- <tr><td><b>vmware_type</b></td><td>Type of VMware to connect</td></tr>
-</table><br/>
-Children: <a href="#ref_FENCEDEVICEOPTIONS">FENCEDEVICEOPTIONS</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_dlm"/>dlm</h3>
-Configuration for dlm and dlm_controld daemon. dlm_controld(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>drop_resources_age</b></td><td>Plock ownership drop resources age. dlm_controld(8)</td></tr>
- <tr><td><b>drop_resources_count</b></td><td>Plock ownership drop resources count. dlm_controld(8)</td></tr>
- <tr><td><b>drop_resources_time</b></td><td>Plock ownership drop resources time. dlm_controld(8)</td></tr>
- <tr><td><b>enable_deadlk</b></td><td>Deadlock detection capability. dlm_controld(8)</td></tr>
- <tr><td><b>enable_fencing</b></td><td>Fencing recovery dependency. dlm_controld(8)</td></tr>
- <tr><td><b>enable_plock</b></td><td>Cluster fs posix lock capability. dlm_controld(8)</td></tr>
- <tr><td><b>enable_quorum</b></td><td>Quorum recovery dependency. dlm_controld(8)</td></tr>
- <tr><td><b>log_debug</b></td><td>Set to 1 to enable dlm kernel debugging messages. dlm_controld(8)</td></tr>
- <tr><td><b>plock_debug</b></td><td>Set to 1 to enable posix lock debugging. dlm_controld(8)</td></tr>
- <tr><td><b>plock_ownership</b></td><td>Set to 1/0 to enable/disable plock ownership. dlm_controld(8)</td></tr>
- <tr><td><b>plock_rate_limit</b></td><td>Limit the rate of plock operations. dlm_controld(8)</td></tr>
- <tr><td><b>protocol</b></td><td>The dlm lowcomms protocol. dlm_controld(8)</td></tr>
- <tr><td><b>timewarn</b></td><td>Number of centiseconds a lock is blocked before notifying dlm_controld deadlock code. dlm_controld(8)</td></tr>
-</table><br/>
-Children: <a href="#tag_lockspace">lockspace</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_drbd"/>drbd</h3>
-This is a DRBD resource.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Cluster resource name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing drbd resource in the resources section.</td></tr>
- <tr><td><b>resource</b></td><td>DRBD resource name</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_event"/>event</h3>
-Defines an event.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. Symbolic name for an event.</td></tr>
- <tr><td><b>class</b></td><td>Event class (service, node).</td></tr>
- <tr><td><b>file</b></td><td>Path to S/Lang script to execute.</td></tr>
- <tr><td><b>node</b></td><td>(Node) The node name must match the specified value in order for the script to be run.</td></tr>
- <tr><td><b>node_clean</b></td><td>(Node) The node must have been fenced in order for the script to be run.</td></tr>
- <tr><td><b>node_id</b></td><td>(Node) The node ID must match the specified value in order for the script to be run.</td></tr>
- <tr><td><b>node_local</b></td><td>(Node) This script may only run on the current central processing node.</td></tr>
- <tr><td><b>node_state</b></td><td>(Node) The node state must match the specified value (0 or 1) in order for the script to be run.</td></tr>
- <tr><td><b>priority</b></td><td>Order (1..99) of event.</td></tr>
- <tr><td><b>service</b></td><td>(Service) The service name (service:foo) must match the specified value in order for the event script to be run.</td></tr>
- <tr><td><b>service_owner</b></td><td>(Service) The service owner must match the specified value in order for the event script to be run.</td></tr>
- <tr><td><b>service_state</b></td><td>(Service) The service's state must match the specified value in order for the script to be run (started, stopped, disabled, failed).</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_events"/>events</h3>
-Event definitions (central_processing only).<br/>
-<br/>
-Children: <a href="#tag_event">event</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_failoverdomain"/>failoverdomain</h3>
-Specifies properties of a specific failover domain<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. The name of the failover domain.</td></tr>
- <tr><td><b>nofailback</b></td><td>Do not move service to a more preferred node if it is currently running.</td></tr>
- <tr><td><b>ordered</b></td><td>Set value to 1 if the failover domain is ordered; set value to 0 if unordered.</td></tr>
- <tr><td><b>restricted</b></td><td>Set value to 1 if the failover domain is restricted; set value to 0 if unrestricted.</td></tr>
-</table><br/>
-Children: <a href="#tag_failoverdomainnode">failoverdomainnode</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_failoverdomainnode"/>failoverdomainnode</h3>
-A node in a failover domain<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. Name of the node.</td></tr>
- <tr><td><b>priority</b></td><td>A number specifying the priority; lower numbers having higher priority</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_failoverdomains"/>failoverdomains</h3>
-Failover domain definitions.<br/>
-<br/>
-Children: <a href="#tag_failoverdomain">failoverdomain</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_fence"/>fence</h3>
-Contains methods for fencing the node in different ways. fenced(8)<br/>
-<br/>
-Children: <a href="#tag_method">method</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_fencedevice"/>fencedevice</h3>
-Defines fence device properties. fenced(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>agent</b></td><td>Required. The fence agent to be used. fenced(8)</td></tr>
- <tr><td><b>name</b></td><td>Required. A name that is used to reference this fence device from clusternode fence section. fenced(8)</td></tr>
- <tr><td><b>action</b></td><td>Fencing action to take (off or on).</td></tr>
- <tr><td><b>aptpl</b></td><td></td></tr>
- <tr><td><b>auth</b></td><td>For IPMI LAN only. Authentication Type: none, password, md2, or md5</td></tr>
- <tr><td><b>channel_address</b></td><td>VM Channel IP address (default=10.0.2.179)</td></tr>
- <tr><td><b>cmd_prompt</b></td><td>Force command prompt</td></tr>
- <tr><td><b>community</b></td><td>Set the community string</td></tr>
- <tr><td><b>cserver</b></td><td>The hostname (and optionally the username in the form of username@hostname) assigned to the device. Refer to the fence_egenera(8) man page for more information.</td></tr>
- <tr><td><b>debug</b></td><td>Specify (stdin) or increment (command line) debug level</td></tr>
- <tr><td><b>delay</b></td><td>Wait this many seconds before fencing is started. fence_egenera(8)</td></tr>
- <tr><td><b>device</b></td><td>The device the switch is connected to on the controlling host.</td></tr>
- <tr><td><b>devices</b></td><td>List of devices to fence (separated by commas).</td></tr>
- <tr><td><b>domain</b></td><td>Virtual Machine (domain name) to fence (deprecated)</td></tr>
- <tr><td><b>drac_version</b></td><td>Force DRAC version to use</td></tr>
- <tr><td><b>esh</b></td><td>Path to the esh command on the cserver. fence_egenera(8)</td></tr>
- <tr><td><b>exec</b></td><td>Command to execute</td></tr>
- <tr><td><b>hash</b></td><td>Packet hash strength (none, sha1, [sha256], sha512)</td></tr>
- <tr><td><b>help</b></td><td>Display help and exit</td></tr>
- <tr><td><b>hmc_version</b></td><td>Force HMC version to use (3 or 4)</td></tr>
- <tr><td><b>identity_file</b></td><td>Identity file for ssh</td></tr>
- <tr><td><b>inet4_only</b></td><td>Forces agent to use IPv4 addresses only</td></tr>
- <tr><td><b>inet6_only</b></td><td>Forces agent to use IPv6 addresses only</td></tr>
- <tr><td><b>io_fencing</b></td><td>Fencing Action</td></tr>
- <tr><td><b>ipaddr</b></td><td>IP address or the name of the device.</td></tr>
- <tr><td><b>ipport</b></td><td>Multicast or VMChannel IP port (default=1229)</td></tr>
- <tr><td><b>ip_family</b></td><td>IP Family ([auto], ipv4, ipv6)</td></tr>
- <tr><td><b>key</b></td><td></td></tr>
- <tr><td><b>key_file</b></td><td>Shared key file (default=/etc/cluster/fence_xvm.key)</td></tr>
- <tr><td><b>lanplus</b></td><td>For IPMI LAN only. Set value to either True or 1; leave out for false.</td></tr>
- <tr><td><b>logfile</b></td><td>Location to output logs from fence_scsi.</td></tr>
- <tr><td><b>login</b></td><td>The login name used to access the device. </td></tr>
- <tr><td><b>login_timeout</b></td><td>Wait X seconds for cmd prompt after login</td></tr>
- <tr><td><b>lpan</b></td><td>The lpan to operate on. fence_egenera(8)</td></tr>
- <tr><td><b>managed</b></td><td>Managed system name</td></tr>
- <tr><td><b>missing_as_off</b></td><td>Missing port returns OFF instead of failure</td></tr>
- <tr><td><b>module_name</b></td><td>DRAC/MC module name</td></tr>
- <tr><td><b>multicast_address</b></td><td>Multicast address (default=225.0.0.12 / ff05::3:1)</td></tr>
- <tr><td><b>nodename</b></td><td>Name of the node to be fenced. Refer to fence_scsi(8) for more information.</td></tr>
- <tr><td><b>option</b></td><td> </td></tr>
- <tr><td><b>partition</b></td><td>Partition name</td></tr>
- <tr><td><b>passwd</b></td><td>The password used to authenticate the connection to the device.</td></tr>
- <tr><td><b>passwd_script</b></td><td>The script that supplies a password for access to the fence device. Using this supersedes the Password parameter.</td></tr>
- <tr><td><b>port</b></td><td>The switch outlet number.</td></tr>
- <tr><td><b>power_timeout</b></td><td>Test X seconds for status change after ON/OFF</td></tr>
- <tr><td><b>power_wait</b></td><td>Wait X seconds after issuing ON/OFF</td></tr>
- <tr><td><b>pserver</b></td><td>The pserver to operate on. fence_egenera(8)</td></tr>
- <tr><td><b>quiet</b></td><td>Supress output</td></tr>
- <tr><td><b>retrans</b></td><td>Multicast retransmit time (in 1/10sec; default=20)</td></tr>
- <tr><td><b>retry_on</b></td><td>Count of attempts to retry power on</td></tr>
- <tr><td><b>ribcl</b></td><td>Force ribcl version to use</td></tr>
- <tr><td><b>rpowerpath</b></td><td></td></tr>
- <tr><td><b>secure</b></td><td>SSH connection</td></tr>
- <tr><td><b>separator</b></td><td>Separator for CSV created by operation list</td></tr>
- <tr><td><b>serial_device</b></td><td>Serial device (default=/dev/ttyS1)</td></tr>
- <tr><td><b>serial_params</b></td><td>Serial Parameters (default=115200,8N1)</td></tr>
- <tr><td><b>servers</b></td><td>The hostname of each GNBD to disable. For multiple hostnames, separate each hostname with a space.</td></tr>
- <tr><td><b>shell_timeout</b></td><td>Wait X seconds for cmd promprt after issuing command</td></tr>
- <tr><td><b>snmp_auth_prot</b></td><td>Set authentication protocol (MD5|SHA)</td></tr>
- <tr><td><b>snmp_priv_passwd</b></td><td>Set privacy protocol password</td></tr>
- <tr><td><b>snmp_priv_passwd_script</b></td><td>Script to run to retrieve privacy password</td></tr>
- <tr><td><b>snmp_priv_prot</b></td><td>Set privacy protocol (DES|AES)</td></tr>
- <tr><td><b>snmp_sec_level</b></td><td>Set security level (noAuthNoPriv|authNoPriv|authPriv)</td></tr>
- <tr><td><b>snmp_version</b></td><td>Specifies SNMP version to use (1,2c,3)</td></tr>
- <tr><td><b>ssl</b></td><td>SSL connection</td></tr>
- <tr><td><b>switch</b></td><td>Physical switch number on device</td></tr>
- <tr><td><b>timeout</b></td><td>Fencing timeout (in seconds; default=30)</td></tr>
- <tr><td><b>udpport</b></td><td>UDP/TCP port to use for connection with device</td></tr>
- <tr><td><b>user</b></td><td>See fence_egenera(8)</td></tr>
- <tr><td><b>use_uuid</b></td><td>Treat [domain] as UUID instead of domain name. This is provided for compatibility with older fence_xvmd installations.</td></tr>
- <tr><td><b>verbose</b></td><td>Verbose mode</td></tr>
- <tr><td><b>version</b></td><td>Display version information and exit</td></tr>
- <tr><td><b>vmware_datacenter</b></td><td>Show only machines in specified datacenter</td></tr>
- <tr><td><b>vmware_type</b></td><td>Type of VMware to connect</td></tr>
-</table><br/>
-Children: <a href="#ref_FENCEDEVICEOPTIONS">FENCEDEVICEOPTIONS</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_fencedevices"/>fencedevices</h3>
-Contains all fence device definitions. fenced(8)<br/>
-<br/>
-Children: <a href="#tag_fencedevice">fencedevice</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_fence_daemon"/>fence_daemon</h3>
-Configuration for fenced daemon. fenced(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>clean_start</b></td><td>Set to 1 to disable startup fencing. fenced(8)</td></tr>
- <tr><td><b>override_path</b></td><td>Location of a FIFO used for communication between fenced and fence_ack_manual. fenced(8)</td></tr>
- <tr><td><b>override_time</b></td><td>Number of seconds to wait for a manual override after a failed fencing attempt before the next attempt. fenced(8)</td></tr>
- <tr><td><b>post_fail_delay</b></td><td>Number of seconds the daemon will wait before fencing any victims after a node fails. fenced(8)</td></tr>
- <tr><td><b>post_join_delay</b></td><td>Number of seconds the daemon will wait before fencing any victims after a node joins the fence domain. fenced(8)</td></tr>
- <tr><td><b>skip_undefined</b></td><td>Set to 1 to disable startup fencing of nodes with no fence methods defined. fenced(8)</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_fence_xvmd"/>fence_xvmd</h3>
-Fence_xvm daemon. The fence_xvmd fence device is an I/O fencing host that resides on dom0 and is used in conjunction with the fence_xvm fencing agent. Together, these two programs fence Xen virtual machines that are in a cluster. There is a requirement that the parent dom0s are also a part of their own CMAN/OpenAIS based cluster, and that the dom0 cluster does not share any members with the domU cluster. Furthermore, the dom0 cluster is required to have fencing if domU recovery is expected to be automatic.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>auth</b></td><td></td></tr>
- <tr><td><b>debug</b></td><td></td></tr>
- <tr><td><b>hash</b></td><td></td></tr>
- <tr><td><b>key_file</b></td><td></td></tr>
- <tr><td><b>multicast_address</b></td><td></td></tr>
- <tr><td><b>multicast_interface</b></td><td></td></tr>
- <tr><td><b>port</b></td><td></td></tr>
- <tr><td><b>uri</b></td><td></td></tr>
- <tr><td><b>use_uuid</b></td><td></td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_fs"/>fs</h3>
-Defines a file system mount.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>device</b></td><td>Device or Label</td></tr>
- <tr><td><b>force_fsck</b></td><td>Force fsck support</td></tr>
- <tr><td><b>force_unmount</b></td><td>Force Unmount</td></tr>
- <tr><td><b>fsid</b></td><td>NFS File system ID</td></tr>
- <tr><td><b>fstype</b></td><td>File system type</td></tr>
- <tr><td><b>mountpoint</b></td><td>Mount Point</td></tr>
- <tr><td><b>name</b></td><td>File System Name</td></tr>
- <tr><td><b>nfslock</b></td><td>Enable NFS lock workarounds</td></tr>
- <tr><td><b>options</b></td><td>Mount Options</td></tr>
- <tr><td><b>quick_status</b></td><td>Quick/brief status checks.</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing fs resource in the resources section.</td></tr>
- <tr><td><b>self_fence</b></td><td>Seppuku Unmount</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_gfs_controld"/>gfs_controld</h3>
-Configuration for gfs_controld daemon. gfs_controld(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>drop_resources_age</b></td><td>Plock ownership drop resources age. gfs_controld(8)</td></tr>
- <tr><td><b>drop_resources_count</b></td><td>Plock ownership drop resources count. gfs_controld(8)</td></tr>
- <tr><td><b>drop_resources_time</b></td><td>Plock ownership drop resources time. gfs_controld(8)</td></tr>
- <tr><td><b>enable_plock</b></td><td>Cluster fs posix lock capability. gfs_controld(8)</td></tr>
- <tr><td><b>enable_withdraw</b></td><td>Set to 1/0 to enable/disable a response to a withdraw. gfs_controld(8)</td></tr>
- <tr><td><b>plock_debug</b></td><td>Set to 1 to enable posix lock debugging. gfs_controld(8)</td></tr>
- <tr><td><b>plock_ownership</b></td><td>Set to 1/0 to enable/disable plock ownership. gfs_controld(8)</td></tr>
- <tr><td><b>plock_rate_limit</b></td><td>Limit the rate of plock operations. gfs_controld(8)</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_group"/>group</h3>
-Defines groupd configuration. groupd(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>groupd_compat</b></td><td>Enable compatibility with cluster2 nodes. groupd(8)</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_heuristic"/>heuristic</h3>
-Defines a heuristic. qdisk(5).<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>program</b></td><td>Required. The program used to determine if this heuristic is alive. This can be anything that can be executed by /bin/sh -c. A return value of 0 indicates success; anything else indicates failure.</td></tr>
- <tr><td><b>interval</b></td><td>The frequency (in seconds) at which the heuristic is polled. qdisk(5).</td></tr>
- <tr><td><b>score</b></td><td>The weight of this heuristic. Be careful when determining scores for heuristics.</td></tr>
- <tr><td><b>tko</b></td><td>The number of consecutive failures before a heuristic is discounted. qdisk(5).</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_interface"/>interface</h3>
-Defines Totem interface options. corosync.conf(5)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>bindnetaddr</b></td><td>Specifies the address to which the corosync executive should bind. corosync.conf(5)</td></tr>
- <tr><td><b>broadcast</b></td><td>If set to yes, use broadcast instead of multicast for communication. corosync.conf(5)</td></tr>
- <tr><td><b>mcastaddr</b></td><td>Defines the multicast address used by corosync for this interface. corosync.conf(5)</td></tr>
- <tr><td><b>mcastport</b></td><td>Specifies the UDP port number when using multicast. corosync.conf(5)</td></tr>
- <tr><td><b>ringnumber</b></td><td>Sets the ring interface for the interface for RRP mode. corosync.conf(5)</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_ip"/>ip</h3>
-This is an IP address.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>address</b></td><td>IP Address</td></tr>
- <tr><td><b>family</b></td><td>Family</td></tr>
- <tr><td><b>monitor_link</b></td><td>Monitor NIC Link</td></tr>
- <tr><td><b>nfslock</b></td><td>Enable NFS lock workarounds</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing ip resource in the resources section.</td></tr>
- <tr><td><b>sleeptime</b></td><td>Amount of time (seconds) to sleep.</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_lockspace"/>lockspace</h3>
-Individual lockspace configuration. dlm_controld(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. Name of the lockspace. dlm_controld(8)</td></tr>
- <tr><td><b>nodir</b></td><td>Set to 1 to disable the internal resource directory. dlm_controld(8)</td></tr>
-</table><br/>
-Children: <a href="#tag_master">master</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_logging"/>logging</h3>
-Defines global logging configuration, and contains daemon-specific configuration. cluster.conf(5)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>debug</b></td><td>Set to on to enable debugging messages in log file. cluster.conf(5)</td></tr>
- <tr><td><b>logfile</b></td><td>The log file path name. cluster.conf(5)</td></tr>
- <tr><td><b>logfile_priority</b></td><td>Messages at this level and higher are written to log file. cluster.conf(5)</td></tr>
- <tr><td><b>syslog_facility</b></td><td>The facility used for syslog messages. cluster.conf(5)</td></tr>
- <tr><td><b>syslog_priority</b></td><td>Messages at this level and higher are sent to syslog. cluster.conf(5)</td></tr>
- <tr><td><b>to_logfile</b></td><td>Set to yes/no to enable/disable messages to log file. cluster.conf(5)</td></tr>
- <tr><td><b>to_syslog</b></td><td>Set to yes/no to enable/disable messages to syslog. cluster.conf(5)</td></tr>
-</table><br/>
-Children: <a href="#tag_logging_daemon">logging_daemon</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_logging_daemon"/>logging_daemon</h3>
-Defines daemon-specific logging configuration. cluster.conf(5)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. The daemon name. cluster.conf(5)</td></tr>
- <tr><td><b>debug</b></td><td>Same as global.</td></tr>
- <tr><td><b>logfile</b></td><td>Same as global.</td></tr>
- <tr><td><b>logfile_priority</b></td><td>Same as global.</td></tr>
- <tr><td><b>subsys</b></td><td>A corosync subsystem name. cluster.conf(5)</td></tr>
- <tr><td><b>syslog_facility</b></td><td>Same as global.</td></tr>
- <tr><td><b>syslog_priority</b></td><td>Same as global.</td></tr>
- <tr><td><b>to_logfile</b></td><td>Same as global.</td></tr>
- <tr><td><b>to_syslog</b></td><td>Same as global.</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_lvm"/>lvm</h3>
-LVM Failover script<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>lv_name</b></td><td>Logical Volume name (optional).</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>nfslock</b></td><td>Enable NFS lock workarounds</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing lvm resource in the resources section.</td></tr>
- <tr><td><b>self_fence</b></td><td>Fence the node if it is not able to clean up LVM tags</td></tr>
- <tr><td><b>vg_name</b></td><td>Volume group name</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_master"/>master</h3>
-Defines a master node. dlm_controld(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. The name of a node that should be master resources/locks. dlm_controld(8)</td></tr>
- <tr><td><b>weight</b></td><td>The proportion of resources this node should master. dlm_controld(8)</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_method"/>method</h3>
-Contains one or more devices for fencing the node a single way. fenced(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. A name used to distinguish multiple methods from each other. fenced(8)</td></tr>
-</table><br/>
-Children: <a href="#ref_DEVICE">DEVICE</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_multicast"/>multicast</h3>
-The multicast element provides the ability for a user to specify a multicast address instead of using the multicast address generated by cman. If a user does not specify a multicast address, cman creates one. It forms the upper 16 bits of the multicast address with 239.192 and forms the lower 16 bits based on the cluster ID.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>addr</b></td><td>Required. A multicast address specified by a user. If you do specify a multicast address, you should use the 239.192.x.x series that cman uses. Otherwise, using a multicast address outside that range may cause unpredictable results. For example, using 224.0.0.x (All hosts on the network) may not be routed correctly, or even routed at all by some hardware.</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_mysql"/>mysql</h3>
-Defines a MySQL database server<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_file</b></td><td>Define configuration file</td></tr>
- <tr><td><b>listen_address</b></td><td>Define an IP address for MySQL server. If the address is not given then first IP address from the service is taken.</td></tr>
- <tr><td><b>mysqld_options</b></td><td>Other command-line options for mysqld</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing mysql resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>shutdown_wait</b></td><td>Wait X seconds for correct end of service shutdown</td></tr>
- <tr><td><b>startup_wait</b></td><td>Wait X seconds for correct end of service startup</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_named"/>named</h3>
-Defines an instance of named server<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_file</b></td><td>Config File</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>named_options</b></td><td>Other command-line options for named</td></tr>
- <tr><td><b>named_sdb</b></td><td>Simplified Database Backend</td></tr>
- <tr><td><b>named_working_dir</b></td><td>Other command-line options for named</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing named resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>shutdown_wait</b></td><td>Wait X seconds for correct end of service shutdown</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_netfs"/>netfs</h3>
-Defines an NFS/CIFS file system mount.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>export</b></td><td>Export</td></tr>
- <tr><td><b>force_unmount</b></td><td>Force Unmount</td></tr>
- <tr><td><b>fstype</b></td><td>File System Type</td></tr>
- <tr><td><b>host</b></td><td>IP or Host</td></tr>
- <tr><td><b>mountpoint</b></td><td>Mount Point</td></tr>
- <tr><td><b>name</b></td><td>File System Name</td></tr>
- <tr><td><b>no_unmount</b></td><td>Skip unmount opration</td></tr>
- <tr><td><b>options</b></td><td>Mount Options</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing netfs resource in the resources section.</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_nfsclient"/>nfsclient</h3>
-Defines an NFS client.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>allow_recover</b></td><td>Allow recovery</td></tr>
- <tr><td><b>fsid</b></td><td>File system ID</td></tr>
- <tr><td><b>name</b></td><td>Client Name</td></tr>
- <tr><td><b>options</b></td><td>Export Options</td></tr>
- <tr><td><b>path</b></td><td>Path to Export</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing nfsclient resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Service Name</td></tr>
- <tr><td><b>svcname</b></td><td></td></tr>
- <tr><td><b>target</b></td><td>Target Hostname, Wildcard, or Netgroup</td></tr>
- <tr><td><b>use_cache</b></td><td>Enable exportfs list caching</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_nfsexport"/>nfsexport</h3>
-This defines an NFS export.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>device</b></td><td>If you can see this, your GUI is broken.</td></tr>
- <tr><td><b>fsid</b></td><td>If you can see this, your GUI is broken.</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>path</b></td><td>If you can see this, your GUI is broken.</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing nfsexport resource in the resources section.</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_nfsserver"/>nfsserver</h3>
-This defines an NFS server resource.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>nfspath</b></td><td>This is the path containing shared NFS recovery information, relative to the path parameter.</td></tr>
- <tr><td><b>path</b></td><td>This is the path you intend to export.</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing nfsserver resource in the resources section.</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_openldap"/>openldap</h3>
-Defines an Open LDAP server<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_file</b></td><td>Config File</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing openldap resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>shutdown_wait</b></td><td>Wait X seconds for correct end of service shutdown</td></tr>
- <tr><td><b>slapd_options</b></td><td>Other command-line options for slapd</td></tr>
- <tr><td><b>url_list</b></td><td>URL list</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_oracledb"/>oracledb</h3>
-Oracle 10g Failover Instance<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>home</b></td><td>Oracle Home Directory</td></tr>
- <tr><td><b>listener_name</b></td><td>Oracle Listener Instance Name</td></tr>
- <tr><td><b>name</b></td><td>Oracle SID</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing oracledb resource in the resources section.</td></tr>
- <tr><td><b>type</b></td><td>Oracle Installation Type</td></tr>
- <tr><td><b>user</b></td><td>Oracle User Name</td></tr>
- <tr><td><b>vhost</b></td><td>Virtual Hostname</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_postgres-8"/>postgres-8</h3>
-Defines a PostgreSQL server<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_file</b></td><td>Config File</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>postmaster_options</b></td><td>Other command-line options for postmaster</td></tr>
- <tr><td><b>postmaster_user</b></td><td>User who runs the database server</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing postgres-8 resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>shutdown_wait</b></td><td>Wait X seconds for correct end of service shutdown</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_quorumd"/>quorumd</h3>
-This element and its attributes define parameters for the quorum disk daemon, quorumd. qdisk(5).<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>allow_kill</b></td><td>Instruct cman to evict nodes which are not updating the quorum disk. qdisk(5).</td></tr>
- <tr><td><b>cman_label</b></td><td>This is the name used by CMAN for the quorum device instead of the device name. qdisk(5).</td></tr>
- <tr><td><b>device</b></td><td>The storage device the quorum daemon uses. The device must be the same on all nodes. qdisk(5).</td></tr>
- <tr><td><b>interval</b></td><td>The frequency of read/write cycles, in seconds. qdisk(5).</td></tr>
- <tr><td><b>io_timeout</b></td><td>Die if we cannot get a write out to disk after interval*tko. qdisk(5).</td></tr>
- <tr><td><b>label</b></td><td>Specifies the quorum disk label created by the mkqdisk utility. If this field contains an entry, the label overrides the Device field. If this field is used, the quorum daemon reads /proc/partitions and checks for qdisk signatures on every block device found, comparing the label against the specified label. This is useful in configurations where the quorum device name differs among nodes. qdisk(5).</td></tr>
- <tr><td><b>master_wins</b></td><td>Enable master-wins mode (two node clusters). qdisk(5).</td></tr>
- <tr><td><b>max_error_cycles</b></td><td>Die after this many cycles which receive I/O errors. qdisk(5).</td></tr>
- <tr><td><b>min_score</b></td><td>The minimum score for a node to be considered alive. If omitted or set to 0, the default function, floor((n+1)/2), is used, where n is the sum of the heuristics scores. The Minimum Score value must never exceed the sum of the heuristic scores; otherwise, the quorum disk cannot be available. qdisk(5).</td></tr>
- <tr><td><b>paranoid</b></td><td>Reboot if we are running too slowly. qdisk(5).</td></tr>
- <tr><td><b>priority</b></td><td>Scheduler priority. qdisk(5).</td></tr>
- <tr><td><b>reboot</b></td><td>Reboot if our score drops too low. qdisk(5).</td></tr>
- <tr><td><b>scheduler</b></td><td>Scheduler. qdisk(5).</td></tr>
- <tr><td><b>status_file</b></td><td>Debugging file. qdisk(5).</td></tr>
- <tr><td><b>stop_cman</b></td><td>Stop cman if the quorum disk cannot be found during startup. qdisk(5).</td></tr>
- <tr><td><b>tko</b></td><td>The number of cycles a node must miss to be declared dead. qdisk(5).</td></tr>
- <tr><td><b>votes</b></td><td>The number of votes the quorum daemon advertises to CMAN when it has a high enough score. qdisk(5).</td></tr>
-</table><br/>
-Children: <a href="#tag_heuristic">heuristic</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_resources"/>resources</h3>
-Defines global resources which may be referenced in services. You may redefine actions for resources here, but child resource definitions are ignored in this section.<br/>
-<br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_resource-defaults"/>resource-defaults</h3>
-This section allows the administrator to change defaults for resource agents. Overriding parameters which must be unique is not allowed. Overriding a value which, by default, inherits a value from a parent resource will disable inheritance for that resource type.<br/>
-<br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_rm"/>rm</h3>
-This element and its attributes define resources (for example an IP address) required to create HA cluster services, the HA cluster services themselves, and failover domains for the HA cluster services.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>central_processing</b></td><td>Enable central processing mode (requires cluster-wide shut down and restart of rgmanager.).</td></tr>
- <tr><td><b>log_facility</b></td><td>The facility is one of the following keywords: auth, authpriv, cron, daemon, kern, lpr, mail, news, syslog, user, uucp and local0 through local7</td></tr>
- <tr><td><b>log_level</b></td><td>An integer 0-7, inclusive, for all levels less than the selected. 0, system is unusable, emergency; 1, action must be taken immediately; 2, critical conditions; 3, error conditions; 4, warning conditions; 5, normal but significant condition; 6, informational; 7, debug-level messages.</td></tr>
- <tr><td><b>status_child_max</b></td><td>Maximum number of status child threads.</td></tr>
- <tr><td><b>status_poll_interval</b></td><td>Scan the resource tree every X seconds for resources which need to be checked.</td></tr>
- <tr><td><b>transition_throttling</b></td><td>During transitions, keep the event processor alive for this many seconds.</td></tr>
-</table><br/>
-Children: <a href="#tag_failoverdomains">failoverdomains</a> <a href="#tag_events">events</a> <a href="#tag_resources">resources</a> <a href="#tag_resource-defaults">resource-defaults</a> <a href="#ref_SERVICE">SERVICE</a> <a href="#ref_VM">VM</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_samba"/>samba</h3>
-Dynamic smbd/nmbd resource agent<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_file</b></td><td>Config File</td></tr>
- <tr><td><b>name</b></td><td>Samba Name</td></tr>
- <tr><td><b>nmbd_options</b></td><td>Other command-line options for nmbd</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing samba resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>shutdown_wait</b></td><td>Wait X seconds for correct end of service shutdown</td></tr>
- <tr><td><b>smbd_options</b></td><td>Other command-line options for smbd</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_SAPDatabase"/>SAPDatabase</h3>
-SAP database resource agent<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>AUTOMATIC_RECOVER</b></td><td>Enable or disable automatic startup recovery</td></tr>
- <tr><td><b>DBJ2EE_ONLY</b></td><td>only JAVA stack installed</td></tr>
- <tr><td><b>DBTYPE</b></td><td>database vendor</td></tr>
- <tr><td><b>DB_JARS</b></td><td>file name of the jdbc driver</td></tr>
- <tr><td><b>DIR_BOOTSTRAP</b></td><td>path to j2ee bootstrap directory</td></tr>
- <tr><td><b>DIR_EXECUTABLE</b></td><td>path of sapstartsrv and sapcontrol</td></tr>
- <tr><td><b>DIR_SECSTORE</b></td><td>path to j2ee secure store directory</td></tr>
- <tr><td><b>JAVA_HOME</b></td><td>Path to Java SDK</td></tr>
- <tr><td><b>NETSERVICENAME</b></td><td>listener name</td></tr>
- <tr><td><b>POST_START_USEREXIT</b></td><td>path to a post-start script</td></tr>
- <tr><td><b>POST_STOP_USEREXIT</b></td><td>path to a post-start script</td></tr>
- <tr><td><b>PRE_START_USEREXIT</b></td><td>path to a pre-start script</td></tr>
- <tr><td><b>PRE_STOP_USEREXIT</b></td><td>path to a pre-start script</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing SAPDatabase resource in the resources section.</td></tr>
- <tr><td><b>SID</b></td><td>SAP system ID</td></tr>
- <tr><td><b>STRICT_MONITORING</b></td><td>Activates application level monitoring</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_SAPInstance"/>SAPInstance</h3>
-SAP instance resource agent<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>AUTOMATIC_RECOVER</b></td><td>Enable or disable automatic startup recovery</td></tr>
- <tr><td><b>DIR_EXECUTABLE</b></td><td>path of sapstartsrv and sapcontrol</td></tr>
- <tr><td><b>DIR_PROFILE</b></td><td>path of start profile</td></tr>
- <tr><td><b>InstanceName</b></td><td>instance name: SID_INSTANCE_VIR-HOSTNAME</td></tr>
- <tr><td><b>POST_START_USEREXIT</b></td><td>path to a post-start script</td></tr>
- <tr><td><b>POST_STOP_USEREXIT</b></td><td>path to a post-start script</td></tr>
- <tr><td><b>PRE_START_USEREXIT</b></td><td>path to a pre-start script</td></tr>
- <tr><td><b>PRE_STOP_USEREXIT</b></td><td>path to a pre-start script</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing SAPInstance resource in the resources section.</td></tr>
- <tr><td><b>START_PROFILE</b></td><td>start profile name</td></tr>
- <tr><td><b>START_WAITTIME</b></td><td>Check the successful start after that time (do not wait for J2EE-Addin)</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_script"/>script</h3>
-LSB-compliant init script as a clustered resource.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>file</b></td><td>Path to script</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing script resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_service"/>service</h3>
-Defines a service (resource group).<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>autostart</b></td><td>Automatic start after quorum formation</td></tr>
- <tr><td><b>depend</b></td><td>Top-level service this depends on, in service:name format.</td></tr>
- <tr><td><b>depend_mode</b></td><td>Service dependency mode (soft or hard).</td></tr>
- <tr><td><b>domain</b></td><td>Failover domain.</td></tr>
- <tr><td><b>exclusive</b></td><td>Exclusive service.</td></tr>
- <tr><td><b>max_restarts</b></td><td>Maximum restarts for this service.</td></tr>
- <tr><td><b>name</b></td><td>Name.</td></tr>
- <tr><td><b>nfslock</b></td><td>Enable NFS lock workarounds.</td></tr>
- <tr><td><b>nfs_client_cache</b></td><td>Enable exportfs list caching (performance).</td></tr>
- <tr><td><b>priority</b></td><td>Service priority.</td></tr>
- <tr><td><b>recovery</b></td><td>Failure recovery policy (restart, relocate, or disable).</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing service resource in the resources section.</td></tr>
- <tr><td><b>restart_expire_time</b></td><td>Restart expiration time; amount of time before a restart is forgotten.</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_smb"/>smb</h3>
-Dynamic smbd/nmbd resource agent<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Samba Name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing smb resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>workgroup</b></td><td>Workgroup name</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_tomcat-5"/>tomcat-5</h3>
-Defines a Tomcat server<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>catalina_base</b></td><td>Catalina base directory (differs for each service)</td></tr>
- <tr><td><b>catalina_options</b></td><td>Other command-line options for Catalina</td></tr>
- <tr><td><b>config_file</b></td><td>Config File</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing tomcat-5 resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>shutdown_wait</b></td><td>Wait X seconds for correct end of service shutdown</td></tr>
- <tr><td><b>tomcat_user</b></td><td>User who runs the Tomcat server</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_tomcat-6"/>tomcat-6</h3>
-Defines a Tomcat server<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_file</b></td><td>Config File</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing tomcat-6 resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>shutdown_wait</b></td><td>Wait X seconds for correct end of service shutdown</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_totem"/>totem</h3>
-OpenAIS msg transport protocol<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>consensus</b></td><td>This is a timeout value that specifies how many milliseconds to wait for consensus to be achieved before starting a new round of membership configuration.</td></tr>
- <tr><td><b>fail_recv_const</b></td><td> </td></tr>
- <tr><td><b>join</b></td><td>This is a timeout value that specifies how many milliseconds to wait for join messages in the membership protocol.</td></tr>
- <tr><td><b>keyfile</b></td><td></td></tr>
- <tr><td><b>rrp_mode</b></td><td>This attribute specifies the redundant ring protocol mode. Its value can be set to active, passive, or none. Active replication offers slightly lower latency from transmit to delivery in faulty network environments but with less performance. Passive replication may nearly double the speed of the totem protocol if the protocol doesn't become cpu bound. The final option is none, in which case only one network interface is used to operate the totem protocol. If only one interface directive is specified, none is automatically chosen. If multiple interface directives are specified, only active or passive may be chosen.</td></tr>
- <tr><td><b>secauth</b></td><td>This attribute specifies that HMAC/SHA1 authentication should be used to authenticate all messages. It further specifies that all data should be encrypted with the sober128 encryption algorithm to protect data from eavesdropping. For more information setting this value, refer the the openais.conf man page.</td></tr>
- <tr><td><b>token</b></td><td>This is a timeout value that specifies how many milliseconds elapse before a token loss is declared after not receiving a token. This is the time spent detecting a failure of a processor in the current configuration. Reforming a new configuration takes about 50 milliseconds in addition to this timeout.</td></tr>
- <tr><td><b>token_retransmits_before_loss_const</b></td><td>This value identifies how many token retransmits should be attempted before forming a new configuration. If this value is set, retransmit and hold will be automatically calculated from retransmits_before_loss and token.</td></tr>
-</table><br/>
-Children: <a href="#tag_interface">interface</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_unfence"/>unfence</h3>
-Contains devices for unfencing the node. fence_node(8)<br/>
-<br/>
-Children: <a href="#ref_DEVICE">DEVICE</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_vm"/>vm</h3>
-Defines a Virtual Machine<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>autostart</b></td><td>Automatic start after quorum formation</td></tr>
- <tr><td><b>depend</b></td><td>Top-level service this depends on, in service:name format.</td></tr>
- <tr><td><b>depend_mode</b></td><td>Service dependency mode (soft or hard).</td></tr>
- <tr><td><b>domain</b></td><td>Cluster failover Domain</td></tr>
- <tr><td><b>exclusive</b></td><td>Exclusive resource group</td></tr>
- <tr><td><b>hypervisor</b></td><td>Hypervisor</td></tr>
- <tr><td><b>hypervisor_uri</b></td><td>Hypervisor URI (normally automatic).</td></tr>
- <tr><td><b>max_restarts</b></td><td>Maximum restarts for this service.</td></tr>
- <tr><td><b>migrate</b></td><td>Migration type (live or pause, default = live).</td></tr>
- <tr><td><b>migration_mapping</b></td><td>memberhost:targethost,memberhost:targethost ..</td></tr>
- <tr><td><b>migration_uri</b></td><td>Migration URI (normally automatic).</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>path</b></td><td>Path to virtual machine configuration files.</td></tr>
- <tr><td><b>recovery</b></td><td>Failure recovery policy</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing vm resource in the resources section.</td></tr>
- <tr><td><b>restart_expire_time</b></td><td>Restart expiration time; amount of time before a restart is forgotten.</td></tr>
- <tr><td><b>snapshot</b></td><td>Path to the snapshot directory where the virtual machine image will be stored.</td></tr>
- <tr><td><b>status_program</b></td><td>Additional status check program</td></tr>
- <tr><td><b>use_virsh</b></td><td>If set to 1, vm.sh will use the virsh command to manage virtual machines instead of xm. This is required when using non-Xen virtual machines (e.g. qemu / KVM).</td></tr>
- <tr><td><b>xmlfile</b></td><td>Full path to libvirt XML file describing the domain.</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-</html>
diff --git a/doc/cman_notify_template.sh b/doc/cman_notify_template.sh
deleted file mode 100644
index ef43860..0000000
--- a/doc/cman_notify_template.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/bash
-
-# This is a simple template that can be used as reference
-# for notification scripts. Note: notification scripts need
-# to be executable in order for cman_notify to run them.
-
-# Set the path for the commands you expect to execute!
-# cmannotifyd does not set any for you.
-
-PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
-
-# define a simple wrapper to echo that will log to file only if
-# debugging is enable.
-my_echo() {
- [ -n "$OUT" ] && echo $@ >> $OUT
-}
-
-LOGFILE="/var/log/cluster/file.log"
-
-# verify if you are running in debugging mode
-if [ "$CMAN_NOTIFICATION_DEBUG" = "1" ]; then
- # in debuggin mode, we want to see the whole output somewhere
- OUT="$LOGFILE"
- my_echo "debugging is enabled"
-fi
-
-# parse the notification we received.
-case "$CMAN_NOTIFICATION" in
- CMAN_REASON_CONFIG_UPDATE)
- # we received a configuration change
- my_echo "replace me with something to do"
- ;;
- CMAN_REASON_STATECHANGE)
- # we received a status change. A node might have left or joined
- # the cluster
- my_echo "replace me with something to do"
-
- # STATECHANGE contains information about the quorum status of
- # the node.
- # 1 = the node is part of a quorate cluster
- # 0 = there is no quorum
- if [ "$CMAN_NOTIFICATION_QUORUM" = "1" ]; then
- my_echo "we still have quorum"
- fi
- ;;
- CMAN_REASON_TRY_SHUTDOWN)
- # we received a shutdown request. It means that cman might go
- # offline very soon.
- my_echo "replace me with something to do"
- ;;
- *)
- # we received an unknown notification.
- my_echo "no clue of what to do with this"
- ;;
-esac
-
-exit 0
diff --git a/doc/usage.txt b/doc/usage.txt
deleted file mode 100644
index 2cc9df7..0000000
--- a/doc/usage.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-cluster3 minimal setup and usage
-
-cluster configuration
----------------------
-
-Create /etc/cluster/cluster.conf and copy it to all nodes.
-
-Below is a minimal cluster.conf file using manual fencing. The node names
-should resolve to the address on the network interface you want to use for
-cluster communication.
-
-<?xml version="1.0"?>
-<cluster name="alpha" config_version="1">
-
-<clusternodes>
-<clusternode name="node-01" nodeid="1"/>
-<clusternode name="node-02" nodeid="2"/>
-<clusternode name="node-03" nodeid="3"/>
-</clusternodes>
-
-</cluster>
-
-
-cluster start
--------------
-
-Use the init script on all nodes:
-
-> service cman start
-
-Or, minimal manual steps:
-
-> modprobe configfs
-> modprobe dlm
-> mount -t configfs none /sys/kernel/config
-> cman_tool join
-> fenced
-> dlm_controld
-> fence_tool join
-
-
-using clvm
-----------
-
-Use the init script on all nodes:
-
-> service clvmd start
-
-Or, manually:
-
-> clvmd
-> vgscan
-> vgchange -aly
-
-
-using rgmanager
----------------
-
-Use the init script on all nodes:
-
-> service rgmanager start
-
-Or, manually:
-
-> rgmanager
-
-Create services/resources to be managed in cluster.conf.
diff --git a/fence/Makefile b/fence/Makefile
deleted file mode 100644
index a8783bb..0000000
--- a/fence/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS=libfence libfenced fenced fence_node fence_tool fence_check man
diff --git a/fence/fence_check/Makefile b/fence/fence_check/Makefile
deleted file mode 100644
index 3788f26..0000000
--- a/fence/fence_check/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-include ../../make/defines.mk
-
-TARGET1 = fence_check
-
-SBINDIRT = $(TARGET1)
-
-all: $(TARGET1)
-
-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#@LOGDIR@#${logdir}#g' \
- -e 's#@VERSION@#${RELEASE_VERSION}#g' \
- > $(TARGET1)
-
-clean: generalclean
diff --git a/fence/fence_check/fence_check.in b/fence/fence_check/fence_check.in
deleted file mode 100644
index e194daf..0000000
--- a/fence/fence_check/fence_check.in
+++ /dev/null
@@ -1,241 +0,0 @@
-#!/bin/bash
-
-set +e
-export LC_ALL=C
-export PATH="/bin:/usr/bin:/sbin:/usr/sbin:@SBINDIR@"
-
-logfile=@LOGDIR@/fence_check.log
-verbose=""
-vardir=/var/run
-
-print_usage() {
- echo "Usage:"
- echo ""
- echo "fence_check [options]"
- echo ""
- echo "Options:"
- echo " -h Print this help, then exit"
- echo " -V Print program version information, then exit"
- echo " -d Disable output to logfile ($logfile)"
- echo " -v Produce verbose output"
- echo " -e Produce extra verbose output"
- echo " ATTENTION: IT MIGHT SHOW FENCE PASSWORDS IN LOG FILES!!!"
- echo " -f Override checks and force execution"
- echo " DO NOT USE ON PRODUCTION CLUSTERS!!!"
-}
-
-check_opts() {
- while [ "$1" != "--" ]; do
- case $1 in
- -h)
- print_usage
- exit 0
- ;;
- -V)
- echo "fence_check version @VERSION@"
- exit 0
- ;;
- -v)
- verbose=1
- ;;
- -e)
- fencenodeopts="-vv"
- ;;
- -d)
- logfile=""
- ;;
- -f)
- override="1"
- ;;
- esac
- shift
- done
-}
-
-opts=$(getopt hdefvV $@)
-if [ "$?" != 0 ]; then
- print_usage >&2
- exit 1
-fi
-check_opts $opts
-
-cleanup() {
- vecho "cleanup: $@"
- rm -f $vardir/fence_check.pid
- exit $1
-}
-
-trap "cleanup 1 ABRT" ABRT
-trap "cleanup 1 QUIT" QUIT
-trap "cleanup 1 TERM" TERM
-trap "cleanup 1 INT" INT
-
-lecho() {
- [ -n "$logfile" ] && echo "$@" | tee -a $logfile
- [ -z "$logfile" ] && echo "$@"
- return 0
-}
-
-vecho() {
- [ -z "$verbose" ] && return 0
- lecho "$@"
-}
-
-error_report()
-{
- lecho "Unable to perform fence_check: $@"
-}
-
-cman_running()
-{
- vecho -n "Checking if cman is running: "
- thisnodeid="$(cman_tool status 2>&1 | grep "Node ID:" | awk '{print $NF}')"
- [ -z "$thisnodeid" ] && {
- vecho "not running"
- return 1
- }
- vecho "running"
-}
-
-cman_has_quorum()
-{
- vecho -n "Checking if node is quorate: "
- cman_tool -t 1 -q wait > /dev/null 2>&1 || {
- vecho "not quorate"
- return 1
- }
- vecho "quorate"
-}
-
-fence_domain()
-{
- vecho -n "Checking if node is in fence domain: "
- fencels="$(fence_tool ls 2>&1)" || {
- vecho "not part of fence domain"
- return 1
- }
- vecho "yes"
-}
-
-fence_in_progress()
-{
- vecho -n "Checking if real fencing is in progress: "
- victim="$(echo "$fencels" | grep "victim count" | awk '{print $NF}')"
- [ "$victim" != "0" ] && {
- vecho "real fencing in progress"
- return 1
- }
- vecho "no fencing in progress"
-}
-
-fence_master()
-{
- vecho -n "Checking if node is fence master: "
- master="$(echo "$fencels" | grep "master nodeid" | awk '{print $NF}')"
- [ "$master" != "$thisnodeid" ] && {
- vecho "node is not fence master"
- return 1
- }
- vecho "this node is fence master"
-}
-
-can_check()
-{
- cman_running || {
- error_report "cman is not running"
- return 2
- }
-
- [ "$override" = "1" ] && return 0
-
- cman_has_quorum || {
- error_report "node is not quorate"
- return 3
- }
-
- fence_domain || {
- error_report "node is not part of the fence domain"
- return 3
- }
-
- fence_master || {
- error_report "node is not fence master"
- return 3
- }
-
- fence_in_progress || {
- error_report "real fencing operation in progress"
- return 3
- }
-
- return 0
-}
-
-execute_check()
-{
- can_check || return $?
-
- vecho -n "Get node list: "
- nodelist="$(cman_tool nodes -F id,name |grep -v '^0' | awk '{print $2}')"
- vecho $nodelist
-
- ret=0
-
- for node in $nodelist; do
- vecho "Testing $node fencing"
-
- can_check
- canret=$?
-
- if [ "$canret" != 0 ]; then
- if [ "$ret" != "5" ]; then
- return $canret
- else
- return $ret
- fi
- fi
-
- vecho "Checking how many fencing methods are configured for node $node"
- for i in $(seq 1 8); do
- ccs_tool query \
- /cluster/clusternodes/clusternode[@name=\"$node\"]/fence/method[$i]/@name >/dev/null 2>&1 || break
- done
- nummethods=$((i - 1))
- vecho "Found $nummethods method(s) to test for node $node"
-
- for method in $(seq 1 $nummethods); do
- vecho "Testing $node method $method status"
- fenceres="$(fence_node $fencenodeopts -S $node -m $method 2>&1)"
- if [ "$?" != 0 ]; then
- ret=5
- lecho "Testing $node method $method: FAILED"
- if [ -z "$fencenodeopts" ]; then
- fenceres="$(echo "$fenceres" | tail -n 2 | head -n 1)"
- else
- fenceargs="$(echo "$fenceres" | tail -n 2 | head -n 1)"
- fenceres="$(echo "$fenceres" | tail -n 3 | head -n 1)"
- fi
- lecho "$fenceres"
- [ -n "$fenceargs" ] && lecho "$fenceargs"
- else
- lecho "Testing $node method $method: success"
- fi
- done
- done
- return $ret
-}
-
-(
- lecho "fence_check run at $(date) pid: $BASHPID"
-
- flock --nonblock --exclusive 200 || {
- lecho "Another process ($(cat $vardir/fence_check.pid)) is holding the lock"
- exit 4
- }
-
- echo $BASHPID > $vardir/fence_check.pid
-
- execute_check
- cleanup $?
-
-) 200>>$vardir/fence_check.pid
diff --git a/fence/fence_node/Makefile b/fence/fence_node/Makefile
deleted file mode 100644
index 665dd62..0000000
--- a/fence/fence_node/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-TARGET = fence_node
-
-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= fence_node.o
-
-CFLAGS += -D_FILE_OFFSET_BITS=64
-
-CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${logtincdir}
-CFLAGS += -I${fenceincdir} -I${fencedincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${ccslibdir} -L${cmanlibdir} -lccs -lcman
-LDFLAGS += -L${fencelibdir} -L${fencedlibdir} -lfence -lfenced
-LDFLAGS += -L${logtlibdir} -llogthread
-LDFLAGS += -L${libdir}
-
-${TARGET}: ${OBJS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-depends:
- $(MAKE) -C ../libfence
- $(MAKE) -C ../libfenced
-
-clean: generalclean
-
--include $(OBJS:.o=.Tpo)
diff --git a/fence/fence_node/fence_node.c b/fence/fence_node/fence_node.c
deleted file mode 100644
index f926825..0000000
--- a/fence/fence_node/fence_node.c
+++ /dev/null
@@ -1,306 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <string.h>
-#include <liblogthread.h>
-#include <libcman.h>
-
-#include "libfence.h"
-#include "libfenced.h"
-#include "copyright.cf"
-
-static char *prog_name;
-static char our_name[CMAN_MAX_NODENAME_LEN+1];
-static int verbose;
-static int unfence;
-static int status;
-static int call_fenced = 1;
-static int use_method_num;
-
-#define FL_SIZE 32
-static struct fence_log flog[FL_SIZE];
-static int flog_count;
-static const char *action = "fence";
-
-#define OPTION_STRING "UvhVSe:m:"
-
-#define die(fmt, args...) \
-do \
-{ \
- fprintf(stderr, "%s: ", prog_name); \
- fprintf(stderr, fmt "\n", ##args); \
- exit(EXIT_FAILURE); \
-} \
-while (0)
-
-static void print_usage(void)
-{
- printf("Usage:\n");
- printf("\n");
- printf("%s [options] node_name\n", prog_name);
- printf("\n");
- printf("Options:\n");
- printf("\n");
- printf(" -U Unfence the node, default local node name\n");
- printf(" -S Run status on node name\n");
- printf(" -v Show fence agent results, -vv for agent args\n");
- printf(" -h Print this help, then exit\n");
- printf(" -V Print program version information, then exit\n");
- printf(" -e 0|1 Enable/disable fenced_external notification\n");
- printf(" -m <num> Method number, starting from 1\n");
- printf("\n");
-}
-
-static int setup_cman(void)
-{
- cman_handle_t ch;
- cman_node_t node;
- int active = 0;
- int rv;
-
- ch = cman_init(NULL);
- if (!ch)
- return -1;
-
- retry_active:
- rv = cman_is_active(ch);
- if (!rv) {
- if (active++ < 2) {
- sleep(1);
- goto retry_active;
- }
- cman_finish(ch);
- return -1;
- }
-
- memset(&node, 0, sizeof(node));
- rv = cman_get_node(ch, CMAN_NODEID_US, &node);
- if (rv < 0) {
- cman_finish(ch);
- return -1;
- }
-
- memset(our_name, 0, sizeof(our_name));
- strncpy(our_name, node.cn_name, CMAN_MAX_NODENAME_LEN);
- cman_finish(ch);
- return 0;
-}
-
-static const char *fe_str(int r)
-{
- switch (r) {
- case FE_AGENT_SUCCESS:
- return "success";
- case FE_AGENT_ERROR:
- return "error from agent";
- case FE_AGENT_FORK:
- return "error from fork";
- case FE_NO_CONFIG:
- return "error from ccs";
- case FE_NO_METHOD:
- return "error no method";
- case FE_NO_DEVICE:
- return "error no device";
- case FE_READ_AGENT:
- return "error config agent";
- case FE_READ_ARGS:
- return "error config args";
- case FE_READ_METHOD:
- return "error config method";
- case FE_READ_DEVICE:
- return "error config device";
- case FE_NUM_METHOD:
- return "error method number";
- case FE_AGENT_STATUS_ON:
- return "status on";
- case FE_AGENT_STATUS_OFF:
- return "status off";
- case FE_AGENT_STATUS_ERROR:
- return "status error";
- default:
- return "error unknown";
- }
-}
-
-int main(int argc, char *argv[])
-{
- char *victim = NULL;
- int cont = 1, optchar, error, rv, i, c;
-
- prog_name = argv[0];
-
- while (cont) {
- optchar = getopt(argc, argv, OPTION_STRING);
-
- switch (optchar) {
-
- case 'U':
- unfence = 1;
- action = "unfence";
- break;
-
- case 'S':
- status = 1;
- action = "status";
- break;
-
- case 'e':
- call_fenced = atoi(optarg);
- break;
-
- case 'm':
- use_method_num = atoi(optarg);
- break;
-
- case 'v':
- verbose++;
- break;
-
- case 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case 'V':
- printf("%s %s (built %s %s)\n", prog_name,
- RELEASE_VERSION, __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- break;
-
- case ':':
- case '?':
- fprintf(stderr, "Please use '-h' for usage.\n");
- exit(EXIT_FAILURE);
- break;
-
- case EOF:
- cont = 0;
- break;
-
- default:
- die("unknown option: %c", optchar);
- break;
- };
- }
-
- while (optind < argc) {
- if (victim)
- die("unknown option %s", argv[optind]);
- victim = argv[optind];
- optind++;
- }
-
- if (!victim && !unfence)
- die("no node name specified");
-
- error = setup_cman();
- if (error)
- die("cannot connect to cman");
-
- if (!victim && unfence)
- victim = our_name;
-
- memset(&flog, 0, sizeof(flog));
- flog_count = 0;
-
- if (status)
- error = fence_node_status(victim, flog, FL_SIZE, &flog_count,
- use_method_num);
- else if (unfence)
- error = unfence_node(victim, flog, FL_SIZE, &flog_count);
- else
- error = fence_node(victim, flog, FL_SIZE, &flog_count);
-
- if (status && !verbose && error < 0)
- verbose = 1;
-
- if (!verbose)
- goto skip;
-
- if (flog_count > FL_SIZE) {
- fprintf(stderr, "%s_node log overflow %d", action, flog_count);
- flog_count = FL_SIZE;
- }
-
- for (i = 0; i < flog_count; i++) {
- fprintf(stderr, "%s %s dev %d.%d agent %s result: %s\n",
- action, victim, flog[i].method_num, flog[i].device_num,
- flog[i].agent_name[0] ? flog[i].agent_name : "none",
- fe_str(flog[i].error));
-
- if (verbose < 2)
- continue;
-
- for (c = 0; c < strlen(flog[i].agent_args); c++) {
- if (flog[i].agent_args[c] == '\n')
- flog[i].agent_args[c] = ' ';
- }
- fprintf(stderr, "agent args: %s\n", flog[i].agent_args);
- }
-
- skip:
- logt_init("fence_node", LOG_MODE_OUTPUT_SYSLOG, SYSLOGFACILITY,
- SYSLOGLEVEL, 0, NULL);
-
- if (status) {
- if (error == -2) {
- fprintf(stderr, "status %s undefined\n", victim);
- rv = 2;
- } else if (error < 0) {
- fprintf(stderr, "status %s failed %d\n", victim, error);
- logt_print(LOG_ERR, "status %s failed %d\n", victim, error);
- rv = EXIT_FAILURE;
- } else if (error == 2) {
- fprintf(stderr, "status %s success off\n", victim);
- logt_print(LOG_ERR, "status %s success off\n", victim);
- rv = EXIT_SUCCESS;
- } else if (!error) {
- fprintf(stderr, "status %s success on\n", victim);
- logt_print(LOG_ERR, "status %s success on\n", victim);
- rv = EXIT_SUCCESS;
- } else {
- fprintf(stderr, "status %s failed invalid %d\n", victim, error);
- logt_print(LOG_ERR, "status %s failed invalid %d\n", victim, error);
- rv = EXIT_FAILURE;
- }
- } else if (unfence) {
- if (error == -2) {
- fprintf(stderr, "unfence %s undefined\n", victim);
- rv = 2;
- } else if (error) {
- fprintf(stderr, "unfence %s failed\n", victim);
- logt_print(LOG_ERR, "unfence %s failed\n", victim);
- rv = EXIT_FAILURE;
- } else {
- fprintf(stderr, "unfence %s success\n", victim);
- logt_print(LOG_ERR, "unfence %s success\n", victim);
- rv = EXIT_SUCCESS;
- }
- } else {
- if (error == -2) {
- fprintf(stderr, "fence %s undefined\n", victim);
- logt_print(LOG_ERR, "fence %s undefined\n", victim);
- rv = 2;
- } else if (error) {
- fprintf(stderr, "fence %s failed\n", victim);
- logt_print(LOG_ERR, "fence %s failed\n", victim);
- rv = EXIT_FAILURE;
- } else {
- fprintf(stderr, "fence %s success\n", victim);
- logt_print(LOG_ERR, "fence %s success\n", victim);
- rv = EXIT_SUCCESS;
-
- /* Tell fenced what we've done so that it can avoid
- fencing this node again if the fence_node() rebooted
- it. */
- if (call_fenced)
- fenced_external(victim);
- }
- }
-
- logt_exit();
- exit(rv);
-}
-
diff --git a/fence/fence_tool/Makefile b/fence/fence_tool/Makefile
deleted file mode 100644
index 92152fd..0000000
--- a/fence/fence_tool/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-TARGET = fence_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=fence_tool.o
-
-CFLAGS += -D_FILE_OFFSET_BITS=64
-CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${fencedincdir}
-CFLAGS += -I$(S)/../include
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${ccslibdir} -L${cmanlibdir} -lccs -lcman
-LDFLAGS += -L${fencedlibdir} -lfenced
-LDFLAGS += -L${libdir}
-
-${TARGET}: ${OBJS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-depends:
- $(MAKE) -C ../libfenced
-
-clean: generalclean
-
--include $(OBJS:.o=.Tpo)
diff --git a/fence/fence_tool/fence_tool.c b/fence/fence_tool/fence_tool.c
deleted file mode 100644
index 91155f2..0000000
--- a/fence/fence_tool/fence_tool.c
+++ /dev/null
@@ -1,737 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <signal.h>
-#include <string.h>
-#include <stdint.h>
-#include <dirent.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <errno.h>
-#include <libgen.h>
-
-#include "ccs.h"
-#include "copyright.cf"
-#include "libcman.h"
-#include "libfenced.h"
-
-#define OP_JOIN 1
-#define OP_LEAVE 2
-#define OP_LIST 3
-#define OP_DUMP 4
-
-#define MAX_NODES 128
-
-int all_nodeids[MAX_NODES];
-int all_nodeids_count;
-cman_handle_t ch;
-cman_node_t cman_nodes[MAX_NODES];
-int cman_nodes_count;
-struct fenced_node nodes[MAX_NODES];
-char *prog_name;
-int operation;
-
-#define DEFAULT_RETRY_CMAN 0 /* fail immediately if we can't connect to cman */
-#define DEFAULT_DELAY_QUORUM 0
-#define DEFAULT_DELAY_MEMBERS 0
-#define DEFAULT_WAIT_JOINLEAVE 0
-
-int opt_all_nodes = 0;
-int opt_retry_cman = DEFAULT_RETRY_CMAN;
-int opt_delay_quorum = DEFAULT_DELAY_QUORUM;
-int opt_delay_members = DEFAULT_DELAY_MEMBERS;
-int opt_wait_joinleave = DEFAULT_WAIT_JOINLEAVE;
-
-
-#define die(fmt, args...) \
-do { \
- fprintf(stderr, "%s: ", prog_name); \
- fprintf(stderr, fmt "\n", ##args); \
- exit(EXIT_FAILURE); \
-} while (0)
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, (char *)buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0)
- return rv;
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-#define LOCKFILE_NAME "/var/run/fenced.pid"
-
-static void check_fenced_running(void)
-{
- struct flock lock;
- int fd, rv;
-
- fd = open(LOCKFILE_NAME, O_RDONLY);
- if (fd < 0)
- die("fenced not running, no lockfile");
-
- lock.l_type = F_RDLCK;
- lock.l_start = 0;
- lock.l_whence= SEEK_SET;
- lock.l_len = 0;
-
- rv = fcntl(fd, F_GETLK, &lock);
- if (rv < 0)
- die("fenced not running, get lockfile");
-
- if (lock.l_type == F_UNLCK)
- die("fenced not running, unlocked lockfile");
-
- close(fd);
-}
-
-static int check_gfs(void)
-{
- FILE *file;
- char line[PATH_MAX];
- char device[PATH_MAX];
- char path[PATH_MAX];
- char type[PATH_MAX];
- int count = 0;
-
- file = fopen("/proc/mounts", "r");
- if (!file)
- return 0;
-
- while (fgets(line, PATH_MAX, file)) {
- if (sscanf(line, "%s %s %s", device, path, type) != 3)
- continue;
- if (!strcmp(type, "gfs") || !strcmp(type, "gfs2")) {
- fprintf(stderr, "found %s file system mounted from %s on %s\n",
- type, device, path);
- count++;
- }
- }
-
- fclose(file);
- return count;
-}
-
-static int check_controlled_dir(const char *path)
-{
- DIR *d;
- struct dirent *de;
- int count = 0;
-
- d = opendir(path);
- if (!d)
- return 0;
-
- while ((de = readdir(d))) {
- if (de->d_name[0] == '.')
- continue;
-
-#if 0
- if (strstr(path, "fs/gfs") && ignore_nolock(path, de->d_name))
- continue;
-#endif
-
- fprintf(stderr, "found dlm lockspace %s/%s\n", path, de->d_name);
- count++;
- }
-
- closedir(d);
- return count;
-}
-
-/* Copying fenced's check_uncontrolled_entries()/check_controlled_dir()
- in part here.
- We could also use check_controlled_dir to detect gfs file systems intead
- of looking at /proc/mounts... /proc/mounts gives us more info (mountpoint)
- to report about the offending fs */
-
-static void check_controlled_systems(void)
-{
- int count = 0;
-
- count += check_gfs();
- count += check_controlled_dir("/sys/kernel/dlm");
-
- if (count)
- die("cannot leave due to active systems");
-}
-
-static int we_are_in_fence_domain(void)
-{
- struct fenced_node nodeinfo;
- int rv;
-
- memset(&nodeinfo, 0, sizeof(nodeinfo));
-
- rv = fenced_node_info(FENCED_NODEID_US, &nodeinfo);
- if (rv < 0)
- return 0;
-
- if (nodeinfo.member)
- return 1;
- return 0;
-}
-
-static void wait_domain(int joining)
-{
- int in, tries = 0;
-
- while (1) {
- if (joining)
- check_fenced_running();
-
- in = we_are_in_fence_domain();
-
- if (joining && in)
- break;
-
- if (!joining && !in)
- break;
-
- tries++;
-
- if (opt_wait_joinleave < 0)
- goto retry_domain;
-
- if (!opt_wait_joinleave || tries >= opt_wait_joinleave) {
- fprintf(stderr, "%s: %s not complete\n",
- prog_name, joining ? "join" : "leave");
- break;
- }
- retry_domain:
- if (!(tries % 10))
- fprintf(stderr, "%s: waiting for fenced to %s the fence group.\n",
- prog_name, joining ? "join" : "leave");
-
- sleep(1);
- }
-
- return;
-}
-
-static void read_ccs_nodeids(int cd)
-{
- char path[PATH_MAX];
- char *nodeid_str;
- int i, error;
-
- memset(all_nodeids, 0, sizeof(all_nodeids));
- all_nodeids_count = 0;
-
- for (i = 1; ; i++) {
- nodeid_str = NULL;
- memset(path, 0, sizeof(path));
- sprintf(path, "/cluster/clusternodes/clusternode[%d]/@nodeid", i);
-
- error = ccs_get(cd, path, &nodeid_str);
- if (error || !nodeid_str)
- break;
-
- all_nodeids[all_nodeids_count++] = atoi(nodeid_str);
- free(nodeid_str);
- }
-}
-
-static int all_nodeids_are_members(void)
-{
- int i, j, rv, found;
-
- memset(&cman_nodes, 0, sizeof(cman_nodes));
- cman_nodes_count = 0;
-
- rv = cman_get_nodes(ch, MAX_NODES, &cman_nodes_count, cman_nodes);
- if (rv < 0)
- return -1;
-
- for (i = 0; i < all_nodeids_count; i++) {
- found = 0;
-
- for (j = 0; j < cman_nodes_count; j++) {
- if (cman_nodes[j].cn_nodeid == all_nodeids[i] &&
- cman_nodes[j].cn_member) {
- found = 1;
- break;
- }
- }
-
- if (!found)
- return 0;
- }
- return 1;
-}
-
-static int connect_cman(void)
-{
- int rv, tries = 0;
-
- while (1) {
- ch = cman_init(NULL);
- if (ch)
- break;
-
- tries++;
-
- if (opt_retry_cman < 0)
- goto retry_init;
-
- if (!opt_retry_cman || tries >= opt_retry_cman)
- return -1;
- retry_init:
- if (!(tries % 10))
- fprintf(stderr, "%s: retrying cman connection\n", prog_name);
- sleep(1);
- }
-
- while (1) {
- rv = cman_is_active(ch);
- if (rv)
- break;
-
- tries++;
-
- if (opt_retry_cman < 0)
- goto retry_active;
-
- if (!opt_retry_cman || tries >= opt_retry_cman) {
- cman_finish(ch);
- return -1;
- }
- retry_active:
- if (!(tries % 10))
- fprintf(stderr, "%s: retrying cman active check\n", prog_name);
- sleep(1);
- }
-
- return 0;
-}
-
-static void delay_quorum(void)
-{
- int rv, tries = 0;
-
- while (1) {
- rv = cman_is_quorate(ch);
- if (rv)
- break;
-
- rv = cman_is_active(ch);
- if (!rv) {
- cman_finish(ch);
- die("lost cman connection");
- }
-
- tries++;
-
- if (opt_delay_quorum < 0)
- goto retry_quorum;
-
- if (!opt_delay_quorum || tries >= opt_delay_quorum) {
- fprintf(stderr, "%s: continuing without quorum\n", prog_name);
- break;
- }
- retry_quorum:
- if (!(tries % 10))
- fprintf(stderr, "%s: delaying for quorum\n", prog_name);
-
- sleep(1);
- }
-
- return;
-}
-
-static void delay_members(void)
-{
- int rv, tries = 0;
- int cd;
-
- cd = ccs_connect();
- if (cd < 0) {
- cman_finish(ch);
- die("lost cman/ccs connection");
- }
-
- read_ccs_nodeids(cd);
-
- while (1) {
- rv = all_nodeids_are_members();
- if (rv < 0) {
- ccs_disconnect(cd);
- cman_finish(ch);
- die("lost cman connection");
- }
- if (rv)
- break;
-
- tries++;
-
- if (opt_delay_members < 0)
- goto retry_members;
-
- if (!opt_delay_members || tries > opt_delay_members) {
- fprintf(stderr, "%s: continuing without all members\n", prog_name);
- break;
- }
- retry_members:
- if (!(tries % 10))
- fprintf(stderr, "%s: delaying for members\n", prog_name);
-
- sleep(1);
- }
-
- ccs_disconnect(cd);
- return;
-}
-
-static void do_join(int argc, char *argv[])
-{
- int rv, tries = 0;
-
- rv = connect_cman();
- if (rv < 0)
- die("can't connect to cman");
-
- /* if delay_quorum() or delay_members() fail on any cman/ccs
- connection or operation, they call cman_finish() and exit
- with failure */
-
- if (opt_delay_quorum)
- delay_quorum();
-
- if (opt_delay_members)
- delay_members();
-
- cman_finish(ch);
-
- /* This loop deals with the case where fenced is slow enough starting
- up that fenced_join fails. Do we also want to add a delay here to
- deal with the case where fenced is so slow starting up that it hasn't
- locked its lockfile yet, causing check_fenced_running to fail? */
-
- while (1) {
- rv = fenced_join();
- if (!rv)
- break;
-
- check_fenced_running();
-
- tries++;
- if (!(tries % 10))
- fprintf(stderr, "%s: retrying join\n", prog_name);
- sleep(1);
- }
-
- if (opt_wait_joinleave)
- wait_domain(1);
-
- exit(EXIT_SUCCESS);
-}
-
-static void do_leave(void)
-{
- int rv;
-
- check_controlled_systems();
-
- rv = fenced_leave();
- if (rv < 0)
- die("leave: can't communicate with fenced");
-
- if (opt_wait_joinleave)
- wait_domain(0);
-
- exit(EXIT_SUCCESS);
-}
-
-static void do_dump(void)
-{
- char buf[FENCED_DUMP_SIZE];
- int rv;
-
- rv = fenced_dump_debug(buf);
- if (rv < 0)
- die("dump: can't communicate with fenced");
-
- do_write(STDOUT_FILENO, buf, strlen(buf));
-
- exit(EXIT_SUCCESS);
-}
-
-static int node_compare(const void *va, const void *vb)
-{
- const struct fenced_node *a = va;
- const struct fenced_node *b = vb;
-
- return a->nodeid - b->nodeid;
-}
-
-/* copied from fence/fenced/fd.h, should probably be in libfenced.h */
-#define CGST_WAIT_CONDITIONS 1
-#define CGST_WAIT_MESSAGES 2
-#define CGST_WAIT_FENCING 3
-
-static const char *wait_str(int state)
-{
- switch (state) {
- case 0:
- return "none";
- case CGST_WAIT_CONDITIONS:
- return "quorum";
- case CGST_WAIT_MESSAGES:
- return "messages";
- case CGST_WAIT_FENCING:
- return "fencing";
- }
- return "unknown";
-}
-
-/* copied from fence/fenced/fd.h, should probably be in libfenced.h */
-#define VIC_DONE_AGENT 1
-#define VIC_DONE_MEMBER 2
-#define VIC_DONE_OVERRIDE 3
-#define VIC_DONE_EXTERNAL 4
-
-static const char *how_str(int how)
-{
- switch (how) {
- case 0:
- return "none";
- case VIC_DONE_AGENT:
- return "agent";
- case VIC_DONE_MEMBER:
- return "member";
- case VIC_DONE_OVERRIDE:
- return "override";
- case VIC_DONE_EXTERNAL:
- return "external";
- }
- return "unknown";
-}
-
-static int do_list(void)
-{
- struct fenced_domain d;
- struct fenced_node *np;
- int node_count;
- int rv, i;
-
- rv = fenced_domain_info(&d);
- if (rv < 0)
- exit(EXIT_FAILURE); /* fenced probably not running */
-
- printf("fence domain\n");
- printf("member count %d\n", d.member_count);
- printf("victim count %d\n", d.victim_count);
- printf("victim now %d\n", d.current_victim);
- printf("master nodeid %d\n", d.master_nodeid);
- printf("wait state %s\n", wait_str(d.state));
- printf("members ");
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
-
- rv = fenced_domain_nodes(FENCED_NODES_MEMBERS, MAX_NODES,
- &node_count, nodes);
- if (rv < 0) {
- printf("error\n");
- goto fail;
- }
-
- qsort(&nodes, node_count, sizeof(struct fenced_node), node_compare);
-
- np = nodes;
- for (i = 0; i < node_count; i++) {
- printf("%d ", np->nodeid);
- np++;
- }
- printf("\n");
-
- if (!opt_all_nodes) {
- printf("\n");
- exit(EXIT_SUCCESS);
- }
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
-
- rv = fenced_domain_nodes(FENCED_NODES_ALL, MAX_NODES,
- &node_count, nodes);
- if (rv < 0)
- goto fail;
-
- qsort(&nodes, node_count, sizeof(struct fenced_node), node_compare);
-
- printf("all nodes\n");
-
- np = nodes;
- for (i = 0; i < node_count; i++) {
- printf("nodeid %d member %d victim %d last fence master %d how %s\n",
- np->nodeid,
- np->member,
- np->victim,
- np->last_fenced_master,
- how_str(np->last_fenced_how));
- np++;
- }
- printf("\n");
- exit(EXIT_SUCCESS);
- fail:
- fprintf(stderr, "fenced query error %d\n", rv);
- printf("\n");
- exit(EXIT_FAILURE);
-}
-
-static void print_usage(void)
-{
- printf("Usage:\n");
- printf("\n");
- printf("%s <ls|join|leave|dump> [options]\n", prog_name);
- printf("\n");
- printf("Actions:\n");
- printf(" ls List nodes status\n");
- printf(" join Join the default fence domain\n");
- printf(" leave Leave default fence domain\n");
- printf(" dump Dump debug buffer from fenced\n");
- printf("\n");
- printf("Options:\n");
- printf(" -n Show all node information in ls\n");
-
- printf(" -t <seconds> Retry cman connection for <seconds>.\n");
- printf(" Default %d. 0 no retry, -1 indefinite retry.\n",
- DEFAULT_RETRY_CMAN);
-
- printf(" -q <seconds> Delay join up to <seconds> for the cluster to have quorum.\n");
- printf(" Default %d. 0 no delay, -1 indefinite delay.\n",
- DEFAULT_DELAY_QUORUM);
-
- printf(" -m <seconds> Delay join up to <seconds> for all nodes in cluster.conf\n");
- printf(" to be cluster members.\n");
- printf(" Default %d. 0 no delay, -1 indefinite delay\n",
- DEFAULT_DELAY_MEMBERS);
-
- printf(" -w <seconds> Wait up to <seconds> for join or leave result.\n");
- printf(" Default %d. 0 no wait, -1 indefinite wait.\n",
- DEFAULT_WAIT_JOINLEAVE);
-
- printf(" -V Print program version information, then exit\n");
- printf(" -h Print this help, then exit\n");
- printf("\n");
-}
-
-#define OPTION_STRING "nt:q:m:w:Vh"
-
-static void decode_arguments(int argc, char *argv[])
-{
- int cont = 1;
- int optchar;
-
- while (cont) {
- optchar = getopt(argc, argv, OPTION_STRING);
-
- switch (optchar) {
-
- case 'n':
- opt_all_nodes = 1;
- break;
-
- case 't':
- opt_retry_cman = atoi(optarg);
- break;
-
- case 'q':
- opt_delay_quorum = atoi(optarg);
- break;
-
- case 'm':
- opt_delay_members = atoi(optarg);
- break;
-
- case 'w':
- opt_wait_joinleave = atoi(optarg);
- break;
-
- case 'V':
- printf("fence_tool %s (built %s %s)\n",
- RELEASE_VERSION, __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- break;
-
- case 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case ':':
- case '?':
- fprintf(stderr, "Please use '-h' for usage.\n");
- exit(EXIT_FAILURE);
- break;
-
- case EOF:
- cont = 0;
- break;
-
- default:
- die("unknown option: %c\n", optchar);
- break;
- }
- }
-
- while (optind < argc) {
- if (strcmp(argv[optind], "join") == 0) {
- operation = OP_JOIN;
- } else if (strcmp(argv[optind], "leave") == 0) {
- operation = OP_LEAVE;
- } else if (strcmp(argv[optind], "dump") == 0) {
- operation = OP_DUMP;
- } else if (strcmp(argv[optind], "ls") == 0) {
- operation = OP_LIST;
- } else
- die("unknown option %s\n", argv[optind]);
- optind++;
- }
-
- if (!operation)
- die("no operation specified\n");
-}
-
-int main(int argc, char *argv[])
-{
- prog_name = basename(argv[0]);
-
- decode_arguments(argc, argv);
-
- switch (operation) {
- case OP_JOIN:
- do_join(argc, argv);
- break;
- case OP_LEAVE:
- do_leave();
- break;
- case OP_DUMP:
- do_dump();
- break;
- case OP_LIST:
- do_list();
- break;
- }
-
- return EXIT_FAILURE;
-}
-
diff --git a/fence/fenced/Makefile b/fence/fenced/Makefile
deleted file mode 100644
index 6935475..0000000
--- a/fence/fenced/Makefile
+++ /dev/null
@@ -1,49 +0,0 @@
-TARGET = fenced
-
-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= config.o \
- cpg.o \
- group.o \
- main.o \
- member_cman.o \
- recover.o \
- logging.o \
- dbus.o
-
-CFLAGS += -D_FILE_OFFSET_BITS=64
-CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${logtincdir} -I${corosyncincdir}
-CFLAGS += -I${fenceincdir} -I${fencedincdir}
-CFLAGS += -I$(S) -I$(S)/../include -I$(SRCDIR)/group/lib
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${ccslibdir} -L${cmanlibdir} -lccs -lcman
-LDFLAGS += -L${logtlibdir} -L${fencelibdir} -llogthread -lfence
-LDFLAGS += -L${corosynclibdir} -lcpg -lpthread
-LDFLAGS += -L../../group/lib -l group
-LDFLAGS += -L${libdir}
-
-ifndef disable_dbus
-CFLAGS += $(shell pkg-config --cflags dbus-1) -DDBUS
-LDFLAGS += $(shell pkg-config --libs dbus-1)
-endif
-
-LDDEPS += ../../group/lib/libgroup.a
-
-${TARGET}: ${OBJS} ${LDDEPS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-depends:
- $(MAKE) -C ../libfence
-
-clean: generalclean
-
--include $(OBJS:.o=.Tpo)
diff --git a/fence/fenced/config.c b/fence/fenced/config.c
deleted file mode 100644
index 1b9a3e0..0000000
--- a/fence/fenced/config.c
+++ /dev/null
@@ -1,226 +0,0 @@
-#include "fd.h"
-#include "config.h"
-#include "ccs.h"
-
-int ccs_handle;
-
-/* was a config value set on command line?, 0 or 1. */
-
-int optd_groupd_compat;
-int optd_debug_logfile;
-int optd_clean_start;
-int optd_disable_dbus;
-int optd_skip_undefined;
-int optd_post_join_delay;
-int optd_post_fail_delay;
-int optd_fence_check_delay;
-int optd_override_time;
-int optd_override_path;
-
-/* actual config value from command line, cluster.conf, or default. */
-
-int cfgd_groupd_compat = DEFAULT_GROUPD_COMPAT;
-int cfgd_debug_logfile = DEFAULT_DEBUG_LOGFILE;
-int cfgd_clean_start = DEFAULT_CLEAN_START;
-int cfgd_disable_dbus = DEFAULT_DISABLE_DBUS;
-int cfgd_skip_undefined = DEFAULT_SKIP_UNDEFINED;
-int cfgd_post_join_delay = DEFAULT_POST_JOIN_DELAY;
-int cfgd_post_fail_delay = DEFAULT_POST_FAIL_DELAY;
-int cfgd_fence_check_delay = DEFAULT_FENCE_CHECK_DELAY;
-int cfgd_override_time = DEFAULT_OVERRIDE_TIME;
-const char *cfgd_override_path = DEFAULT_OVERRIDE_PATH;
-
-void read_ccs_name(const char *path, char *name)
-{
- char *str;
- int error;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return;
-
- strcpy(name, str);
-
- free(str);
-}
-
-void read_ccs_yesno(const char *path, int *yes, int *no)
-{
- char *str;
- int error;
-
- *yes = 0;
- *no = 0;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return;
-
- if (!strcmp(str, "yes"))
- *yes = 1;
-
- else if (!strcmp(str, "no"))
- *no = 1;
-
- free(str);
-}
-
-void read_ccs_int(const char *path, int *config_val)
-{
- char *str;
- int val;
- int error;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return;
-
- val = atoi(str);
-
- if (val < 0) {
- log_error("ignore invalid value %d for %s", val, path);
- return;
- }
-
- *config_val = val;
- log_debug("%s is %u", path, val);
- free(str);
-}
-
-#define GROUPD_COMPAT_PATH "/cluster/group/@groupd_compat"
-#define CLEAN_START_PATH "/cluster/fence_daemon/@clean_start"
-#define POST_JOIN_DELAY_PATH "/cluster/fence_daemon/@post_join_delay"
-#define POST_FAIL_DELAY_PATH "/cluster/fence_daemon/@post_fail_delay"
-#define FENCE_CHECK_DELAY_PATH "/cluster/fence_daemon/@fence_check_delay"
-#define OVERRIDE_PATH_PATH "/cluster/fence_daemon/@override_path"
-#define OVERRIDE_TIME_PATH "/cluster/fence_daemon/@override_time"
-#define METHOD_NAME_PATH "/cluster/clusternodes/clusternode[@name=\"%s\"]/fence/method[%d]/@name"
-#define TWO_NODE_PATH "/cluster/cman/@two_node"
-
-static int count_methods(char *victim)
-{
- char path[PATH_MAX], *name;
- int error, i;
-
- for (i = 0; i < 2; i++) {
- memset(path, 0, sizeof(path));
- sprintf(path, METHOD_NAME_PATH, victim, i+1);
-
- error = ccs_get(ccs_handle, path, &name);
- if (error)
- break;
- free(name);
- }
- return i;
-}
-
-/* These are the options that can be changed while running. */
-
-void reread_ccs(void)
-{
- if (!optd_post_join_delay)
- read_ccs_int(POST_JOIN_DELAY_PATH, &cfgd_post_join_delay);
- if (!optd_post_fail_delay)
- read_ccs_int(POST_FAIL_DELAY_PATH, &cfgd_post_fail_delay);
- if (!optd_fence_check_delay)
- read_ccs_int(FENCE_CHECK_DELAY_PATH, &cfgd_fence_check_delay);
- if (!optd_override_time)
- read_ccs_int(OVERRIDE_TIME_PATH, &cfgd_override_time);
-}
-
-/* called when the domain is joined, not when the daemon starts */
-
-int read_ccs(struct fd *fd)
-{
- char path[PATH_MAX];
- char *str, *name;
- int error, i = 0, count = 0;
- int num_methods;
-
- if (!optd_clean_start)
- read_ccs_int(CLEAN_START_PATH, &cfgd_clean_start);
-
- read_ccs_int(TWO_NODE_PATH, &two_node_mode);
-
- reread_ccs();
-
- if (!optd_override_path) {
- str = NULL;
- memset(path, 0, sizeof(path));
- sprintf(path, OVERRIDE_PATH_PATH);
-
- error = ccs_get(ccs_handle, path, &str);
- if (!error && str)
- cfgd_override_path = strdup(str);
- if (str)
- free(str);
- }
-
- if (cfgd_clean_start) {
- log_debug("clean start, skipping initial nodes");
- goto out;
- }
-
- for (i = 1; ; i++) {
- str = NULL;
- memset(path, 0, sizeof(path));
- sprintf(path, "/cluster/clusternodes/clusternode[%d]/@nodeid", i);
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- break;
-
- name = NULL;
- memset(path, 0, sizeof(path));
- sprintf(path, "/cluster/clusternodes/clusternode[%d]/@name", i);
-
- error = ccs_get(ccs_handle, path, &name);
- if (error || !name) {
- log_error("node name query failed for num %d nodeid %s",
- i, str);
- break;
- }
-
- num_methods = count_methods(name);
-
- /* the libcpg code only uses the fd->complete list for
- determining initial victims; the libgroup code uses
- fd->complete more extensively */
-
- if (cfgd_skip_undefined && !num_methods)
- log_debug("skip %s with zero methods", name);
- else
- add_complete_node(fd, atoi(str));
-
- free(str);
- free(name);
- count++;
- }
-
- log_debug("added %d nodes from ccs", count);
- out:
- return 0;
-}
-
-int setup_ccs(void)
-{
- int cd;
-
- cd = ccs_connect();
- if (cd < 0) {
- log_error("ccs_connect error %d %d", cd, errno);
- return -1;
- }
- ccs_handle = cd;
-
- if (!optd_groupd_compat)
- read_ccs_int(GROUPD_COMPAT_PATH, &cfgd_groupd_compat);
-
- return 0;
-}
-
-void close_ccs(void)
-{
- ccs_disconnect(ccs_handle);
-}
-
diff --git a/fence/fenced/config.h b/fence/fenced/config.h
deleted file mode 100644
index 5f42dea..0000000
--- a/fence/fenced/config.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef __CONFIG_DOT_H__
-#define __CONFIG_DOT_H__
-
-#define DEFAULT_GROUPD_COMPAT 0
-#define DEFAULT_DEBUG_LOGFILE 0
-#define DEFAULT_CLEAN_START 0
-#define DEFAULT_DISABLE_DBUS 0
-#define DEFAULT_SKIP_UNDEFINED 0
-#define DEFAULT_POST_JOIN_DELAY 6
-#define DEFAULT_POST_FAIL_DELAY 0
-#define DEFAULT_FENCE_CHECK_DELAY 5
-#define DEFAULT_OVERRIDE_TIME 3
-#define DEFAULT_OVERRIDE_PATH "/var/run/cluster/fenced_override"
-#define DEFAULT_FENCE_CHECK_PID_PATH "/var/run/fence_check.pid"
-
-extern int optd_groupd_compat;
-extern int optd_debug_logfile;
-extern int optd_clean_start;
-extern int optd_disable_dbus;
-extern int optd_skip_undefined;
-extern int optd_post_join_delay;
-extern int optd_post_fail_delay;
-extern int optd_fence_check_delay;
-extern int optd_override_time;
-extern int optd_override_path;
-
-extern int cfgd_groupd_compat;
-extern int cfgd_debug_logfile;
-extern int cfgd_clean_start;
-extern int cfgd_disable_dbus;
-extern int cfgd_skip_undefined;
-extern int cfgd_post_join_delay;
-extern int cfgd_post_fail_delay;
-extern int cfgd_fence_check_delay;
-extern int cfgd_override_time;
-extern const char *cfgd_override_path;
-
-#endif
-
diff --git a/fence/fenced/cpg.c b/fence/fenced/cpg.c
deleted file mode 100644
index 6634f8c..0000000
--- a/fence/fenced/cpg.c
+++ /dev/null
@@ -1,2510 +0,0 @@
-#include "fd.h"
-#include "config.h"
-
-#define PV_STATEFUL 0x0001
-
-struct protocol_version {
- uint16_t major;
- uint16_t minor;
- uint16_t patch;
- uint16_t flags;
-};
-
-struct protocol {
- union {
- struct protocol_version dm_ver;
- uint16_t daemon_max[4];
- };
- union {
- struct protocol_version dr_ver;
- uint16_t daemon_run[4];
- };
-};
-
-struct node_daemon {
- struct list_head list;
- int nodeid;
- int is_member;
- int killed;
- uint64_t join_time;
- uint64_t left_time;
- struct protocol proto;
-};
-
-struct member {
- struct list_head list;
- int nodeid;
- int start; /* 1 if we received a start message for this change */
- int added; /* 1 if added by this change */
- int failed; /* 1 if failed in this change */
- int disallowed;
- uint32_t start_flags;
-};
-
-/* fd_info and id_info: for syncing state in start message */
-
-struct fd_info {
- uint32_t fd_info_size;
- uint32_t id_info_size;
- uint32_t id_info_count;
-
- uint32_t started_count;
-
- int member_count;
- int joined_count;
- int remove_count;
- int failed_count;
-};
-
-#define IDI_NODEID_IS_MEMBER 0x00000001
-
-struct id_info {
- int nodeid;
- uint32_t flags;
-
- /* the following syncs info to make queries useful from all nodes */
-
- int fence_external_node;
- int fence_master;
- int fence_how;
- int pad;
- uint64_t fence_time;
- uint64_t fence_external_time;
-};
-
-static cpg_handle_t cpg_handle_daemon;
-static cpg_handle_t cpg_handle_domain;
-static struct cpg_name group_name_daemon;
-static struct cpg_name group_name_domain;
-static int cpg_fd_daemon;
-static int cpg_fd_domain;
-static struct protocol our_protocol;
-static struct list_head daemon_nodes;
-static struct cpg_address daemon_member[MAX_NODES];
-static int daemon_member_count;
-
-static void log_config(const struct cpg_name *group_name,
- const struct cpg_address *member_list,
- size_t member_list_entries,
- const struct cpg_address *left_list,
- size_t left_list_entries,
- const struct cpg_address *joined_list,
- size_t joined_list_entries)
-{
- char m_buf[128];
- char j_buf[32];
- char l_buf[32];
- size_t i, len, pos;
- int ret;
-
- memset(m_buf, 0, sizeof(m_buf));
- memset(j_buf, 0, sizeof(j_buf));
- memset(l_buf, 0, sizeof(l_buf));
-
- len = sizeof(m_buf);
- pos = 0;
- for (i = 0; i < member_list_entries; i++) {
- ret = snprintf(m_buf + pos, len - pos, " %d",
- member_list[i].nodeid);
- if (ret >= len - pos)
- break;
- pos += ret;
- }
-
- len = sizeof(j_buf);
- pos = 0;
- for (i = 0; i < joined_list_entries; i++) {
- ret = snprintf(j_buf + pos, len - pos, " %d",
- joined_list[i].nodeid);
- if (ret >= len - pos)
- break;
- pos += ret;
- }
-
- len = sizeof(l_buf);
- pos = 0;
- for (i = 0; i < left_list_entries; i++) {
- ret = snprintf(l_buf + pos, len - pos, " %d",
- left_list[i].nodeid);
- if (ret >= len - pos)
- break;
- pos += ret;
- }
-
- log_debug("%s conf %zu %zu %zu memb%s join%s left%s", group_name->value,
- member_list_entries, joined_list_entries, left_list_entries,
- m_buf, j_buf, l_buf);
-}
-
-static void log_ringid(cpg_handle_t handle,
- struct cpg_ring_id *ringid,
- const uint32_t *member_list,
- size_t member_list_entries)
-{
- char m_buf[128];
- size_t i, len, pos;
- int ret;
- const char *name = "unknown";
-
- if (handle == cpg_handle_domain)
- name = group_name_domain.value;
- else if (handle == cpg_handle_daemon)
- name = group_name_daemon.value;
-
- memset(m_buf, 0, sizeof(m_buf));
-
- len = sizeof(m_buf);
- pos = 0;
- for (i = 0; i < member_list_entries; i++) {
- ret = snprintf(m_buf + pos, len - pos, " %u",
- member_list[i]);
- if (ret >= len - pos)
- break;
- pos += ret;
- }
-
- log_debug("%s ring %u:%llu %zu memb%s",
- name, ringid->nodeid, (unsigned long long)ringid->seq,
- member_list_entries, m_buf);
-}
-
-static void fd_info_in(struct fd_info *fi)
-{
- fi->fd_info_size = le32_to_cpu(fi->fd_info_size);
- fi->id_info_size = le32_to_cpu(fi->id_info_size);
- fi->id_info_count = le32_to_cpu(fi->id_info_count);
- fi->started_count = le32_to_cpu(fi->started_count);
- fi->member_count = le32_to_cpu(fi->member_count);
- fi->joined_count = le32_to_cpu(fi->joined_count);
- fi->remove_count = le32_to_cpu(fi->remove_count);
- fi->failed_count = le32_to_cpu(fi->failed_count);
-}
-
-static void id_info_in(struct id_info *id)
-{
- id->nodeid = le32_to_cpu(id->nodeid);
- id->flags = le32_to_cpu(id->flags);
- id->fence_external_node = le32_to_cpu(id->fence_external_node);
- id->fence_master = le32_to_cpu(id->fence_master);
- id->fence_how = le32_to_cpu(id->fence_how);
- id->fence_time = le64_to_cpu(id->fence_time);
- id->fence_external_time = le64_to_cpu(id->fence_external_time);
-}
-
-static void ids_in(struct fd_info *fi, struct id_info *ids)
-{
- struct id_info *id;
- int i;
-
- id = ids;
- for (i = 0; i < fi->id_info_count; i++) {
- id_info_in(id);
- id = (struct id_info *)((char *)id + fi->id_info_size);
- }
-}
-
-static const char *msg_name(int type)
-{
- switch (type) {
- case FD_MSG_PROTOCOL:
- return "protocol";
- case FD_MSG_START:
- return "start";
- case FD_MSG_VICTIM_DONE:
- return "victim_done";
- case FD_MSG_COMPLETE:
- return "complete";
- case FD_MSG_EXTERNAL:
- return "external";
- default:
- return "unknown";
- }
-}
-
-static int _send_message(cpg_handle_t h, void *buf, int len, int type)
-{
- struct iovec iov;
- cpg_error_t error;
- int retries = 0;
-
- iov.iov_base = buf;
- iov.iov_len = len;
-
- retry:
- error = cpg_mcast_joined(h, CPG_TYPE_AGREED, &iov, 1);
- if (error == CPG_ERR_TRY_AGAIN) {
- retries++;
- usleep(1000);
- if (!(retries % 100))
- log_error("cpg_mcast_joined retry %d %s",
- retries, msg_name(type));
- goto retry;
- }
- if (error != CPG_OK) {
- log_error("cpg_mcast_joined error %d handle %llx %s",
- error, (unsigned long long)h, msg_name(type));
- return -1;
- }
-
- if (retries)
- log_debug("cpg_mcast_joined retried %d %s",
- retries, msg_name(type));
-
- return 0;
-}
-
-/* header fields caller needs to set: type, to_nodeid, flags, msgdata */
-
-static void fd_send_message(struct fd *fd, char *buf, int len)
-{
- struct fd_header *hd = (struct fd_header *) buf;
- int type = hd->type;
-
- hd->version[0] = cpu_to_le16(our_protocol.daemon_run[0]);
- hd->version[1] = cpu_to_le16(our_protocol.daemon_run[1]);
- hd->version[2] = cpu_to_le16(our_protocol.daemon_run[2]);
- hd->type = cpu_to_le16(hd->type);
- hd->nodeid = cpu_to_le32(our_nodeid);
- hd->to_nodeid = cpu_to_le32(hd->to_nodeid);
- hd->flags = cpu_to_le32(hd->flags);
- hd->msgdata = cpu_to_le32(hd->msgdata);
-
- _send_message(fd->cpg_handle, buf, len, type);
-}
-
-static struct member *find_memb(struct change *cg, int nodeid)
-{
- struct member *memb;
-
- list_for_each_entry(memb, &cg->members, list) {
- if (memb->nodeid == nodeid)
- return memb;
- }
- return NULL;
-}
-
-static struct fd *find_fd_handle(cpg_handle_t h)
-{
- struct fd *fd;
-
- list_for_each_entry(fd, &domains, list) {
- if (fd->cpg_handle == h)
- return fd;
- }
- return NULL;
-}
-
-static struct fd *find_fd_ci(int ci)
-{
- struct fd *fd;
-
- list_for_each_entry(fd, &domains, list) {
- if (fd->cpg_client == ci)
- return fd;
- }
- return NULL;
-}
-
-void free_cg(struct change *cg)
-{
- struct member *memb, *safe;
-
- list_for_each_entry_safe(memb, safe, &cg->members, list) {
- list_del(&memb->list);
- free(memb);
- }
- list_for_each_entry_safe(memb, safe, &cg->removed, list) {
- list_del(&memb->list);
- free(memb);
- }
- free(cg);
-}
-
-static struct node *get_node_victim(struct fd *fd, int nodeid)
-{
- struct node *node;
-
- list_for_each_entry(node, &fd->victims, list) {
- if (node->nodeid == nodeid)
- return node;
- }
- return NULL;
-}
-
-static struct node_history *get_node_history(struct fd *fd, int nodeid)
-{
- struct node_history *node;
-
- list_for_each_entry(node, &fd->node_history, list) {
- if (node->nodeid == nodeid)
- return node;
- }
- return NULL;
-}
-
-void node_history_init(struct fd *fd, int nodeid)
-{
- struct node_history *node;
-
- node = get_node_history(fd, nodeid);
- if (node)
- return;
-
- node = malloc(sizeof(struct node_history));
- if (!node)
- return;
- memset(node, 0, sizeof(struct node_history));
-
- node->nodeid = nodeid;
- list_add_tail(&node->list, &fd->node_history);
-}
-
-void node_history_cluster_add(int nodeid)
-{
- struct fd *fd;
- struct node_history *node;
-
- list_for_each_entry(fd, &domains, list) {
- node_history_init(fd, nodeid);
-
- node = get_node_history(fd, nodeid);
- if (!node) {
- log_error("node_history_cluster_add no nodeid %d",
- nodeid);
- return;
- }
-
- node->cluster_add_time = time(NULL);
- }
-}
-
-void node_history_cluster_remove(int nodeid)
-{
- struct fd *fd;
- struct node_history *node;
-
- list_for_each_entry(fd, &domains, list) {
- node = get_node_history(fd, nodeid);
- if (!node) {
- log_error("node_history_cluster_remove no nodeid %d",
- nodeid);
- return;
- }
-
- node->cluster_remove_time = time(NULL);
- }
-}
-
-static void node_history_start(struct fd *fd, int nodeid)
-{
- struct node_history *node;
-
- node = get_node_history(fd, nodeid);
- if (!node) {
- log_error("node_history_start no nodeid %d", nodeid);
- return;
- }
-
- node->add_time = time(NULL);
-}
-
-static void node_history_left(struct fd *fd, int nodeid, uint32_t seq)
-{
- struct node_history *node;
-
- node = get_node_history(fd, nodeid);
- if (!node) {
- log_error("node_history_left no nodeid %d", nodeid);
- return;
- }
-
- node->left_time = time(NULL);
- node->left_seq = seq;
-}
-
-static void node_history_fail(struct fd *fd, int nodeid, uint32_t seq)
-{
- struct node_history *node;
-
- node = get_node_history(fd, nodeid);
- if (!node) {
- log_error("node_history_fail no nodeid %d", nodeid);
- return;
- }
-
- node->fail_time = time(NULL);
- node->fail_seq = seq;
-
- node->check_quorum = 1;
-}
-
-/* The master node updates this info when it fences the victim, the other
- domain members update it when they receive the status message from the
- master. */
-
-void node_history_fence(struct fd *fd, int victim, int master, int how,
- uint64_t mastertime)
-{
- struct node_history *node;
-
- node = get_node_history(fd, victim);
- if (!node) {
- log_error("node_history_fence no nodeid %d", victim);
- return;
- }
-
- node->fence_master = master;
- node->fence_time = mastertime;
- node->fence_how = how;
-}
-
-/* When the fence_node command is run on a machine, it will first call
- libfence:fence_node(victim) to do the fencing. Afterward, it should call
- libfenced:fence_external(victim) to tell fenced what it's done, so fenced
- can avoid fencing the node a second time. This will result in a message
- being sent to all domain members which will update their node_history entry
- for the victim. The recover.c:fence_victims() code can check whether
- a victim has been externally fenced since the last add_time, and if so
- skip the fencing. This won't always work perfectly; a node might in some
- circumstances be fenced a second time by fenced. */
-
-static void node_history_fence_external(struct fd *fd, int nodeid, int from)
-{
- struct node_history *node;
-
- node = get_node_history(fd, nodeid);
- if (!node) {
- log_error("node_history_fence_external no nodeid %d", nodeid);
- return;
- }
-
- node->fence_external_time = time(NULL);
- node->fence_external_node = from;
-}
-
-static void save_history(struct fd *fd, struct fd_info *fi, struct id_info *ids)
-{
- struct node_history *node;
- struct id_info *id;
- int i;
-
- id = ids;
-
- for (i = 0; i < fi->id_info_count; i++) {
- /* create history entries for nodes that were domain members
- prior to our joining the domain */
- node_history_init(fd, id->nodeid);
-
- node = get_node_history(fd, id->nodeid);
- if (!node) {
- log_error("save_history no nodeid %d", id->nodeid);
- goto next;
- }
-
- if (!node->fence_time && id->fence_time) {
- node->fence_master = id->fence_master;
- node->fence_time = id->fence_time;
- node->fence_how = id->fence_how;
- log_debug("save_history %d master %d time %llu how %d",
- node->nodeid, node->fence_master,
- (unsigned long long)node->fence_time,
- node->fence_how);
- }
-
- if (!node->fence_external_time && id->fence_external_time) {
- node->fence_external_time = id->fence_external_time;
- node->fence_external_node = id->fence_external_node;
- log_debug("save_history %d ext node %d ext time %llu",
- node->nodeid, node->fence_external_node,
- (unsigned long long)node->fence_external_time);
- }
- next:
- id = (struct id_info *)((char *)id + fi->id_info_size);
- }
-}
-
-/* call this from libfenced:fenced_external() */
-
-void send_external(struct fd *fd, int victim)
-{
- struct fd_header *hd;
- char *buf;
- int len;
-
- len = sizeof(struct fd_header);
-
- buf = malloc(len);
- if (!buf) {
- log_error("send_external no mem len %d", len);
- return;
- }
- memset(buf, 0, len);
-
- hd = (struct fd_header *)buf;
- hd->type = FD_MSG_EXTERNAL;
- hd->msgdata = victim;
-
- log_debug("send_external victim nodeid %u", victim);
-
- fd_send_message(fd, buf, len);
-
- free(buf);
-}
-
-/* now, if the victim dies and the fence domain sees it fail,
- it will be added as an fd victim, but fence_victims() will
- call is_fenced_external() which will see that it's already
- fenced and bypass fencing it again */
-
-static void receive_external(struct fd *fd, struct fd_header *hd, int len)
-{
- log_debug("receive_external from %d len %d victim nodeid %d",
- hd->nodeid, len, hd->msgdata);
-
- node_history_fence_external(fd, hd->msgdata, hd->nodeid);
-}
-
-int is_fenced_external(struct fd *fd, int nodeid)
-{
- struct node_history *node;
-
- node = get_node_history(fd, nodeid);
- if (!node) {
- log_error("is_fenced_external no nodeid %d", nodeid);
- return 0;
- }
-
- if (node->fence_external_time > node->add_time)
- return 1;
- return 0;
-}
-
-/* completed victim must be removed from victims list before calling this
- because we count the number of entries on the victims list for remaining */
-
-void send_victim_done(struct fd *fd, int victim)
-{
- struct change *cg = list_first_entry(&fd->changes, struct change, list);
- struct fd_header *hd;
- struct id_info *id;
- struct node_history *node;
- char *buf;
- int len;
-
- len = sizeof(struct fd_header) + sizeof(struct id_info);
-
- buf = malloc(len);
- if (!buf) {
- log_error("send_victim_done no mem len %d", len);
- return;
- }
- memset(buf, 0, len);
-
- hd = (struct fd_header *)buf;
- hd->type = FD_MSG_VICTIM_DONE;
- hd->msgdata = cg->seq;
-
- if (fd->init_complete || fd->local_init_complete)
- hd->flags |= FD_MFLG_COMPLETE;
-
- node = get_node_history(fd, victim);
- if (!node) {
- log_error("send_victim_done no nodeid %d", victim);
- return;
- }
-
- id = (struct id_info *)(buf + sizeof(struct fd_header));
- id->nodeid = cpu_to_le32(victim);
- id->fence_master = cpu_to_le32(our_nodeid);
- id->fence_time = cpu_to_le64(node->fence_time);
- id->fence_how = cpu_to_le32(node->fence_how);
-
- log_debug("send_victim_done cg %u flags %x victim nodeid %d",
- cg->seq, hd->flags, victim);
-
- fd_send_message(fd, buf, len);
-
- free(buf);
-}
-
-/* The master needs to remove the victim upon receiving its own victim_done
- message, just like everyone else. Otherwise, when a partitioned node is
- remerged and then killed, the others will see it's already a victim, but
- the master won't see that confchg until after it's done fencing the
- victim for the initial partition. So when the master sees the second
- failure (due to the kill), the node won't be a victim already so it'll
- become a victim again. */
-
-static void receive_victim_done(struct fd *fd, struct fd_header *hd, int len)
-{
- struct node *node;
- struct node_history *nodeh;
- uint32_t seq = hd->msgdata;
- struct id_info *id;
-
- log_debug("receive_victim_done %d:%u flags %x len %d", hd->nodeid, seq,
- hd->flags, len);
-
- /* check that hd->nodeids is fd->master ? */
-
- id = (struct id_info *)((char *)hd + sizeof(struct fd_header));
- id_info_in(id);
-
- node = get_node_victim(fd, id->nodeid);
- if (!node) {
- /* see comment below about no node */
- log_debug("receive_victim_done %d:%u no victim nodeid %d",
- hd->nodeid, seq, id->nodeid);
- }
-
- log_debug("receive_victim_done %d:%u remove victim %d time %llu how %d",
- hd->nodeid, seq, id->nodeid,
- (unsigned long long)id->fence_time, id->fence_how);
-
- nodeh = get_node_history(fd, id->nodeid);
- if (!nodeh)
- log_error("receive_victim_done no node history %d", id->nodeid);
- else
- nodeh->fence_time_local = time(NULL);
-
- if (hd->nodeid == our_nodeid) {
- /* sanity check, I don't think this should happen;
- see comment in fence_victims() */
- if (node) {
- if (!node->local_victim_done)
- log_error("expect local_victim_done");
- node->local_victim_done = 0;
- }
- } else {
- /* save details of fencing operation from master, which
- master saves at the time it completes it */
- node_history_fence(fd, id->nodeid, id->fence_master,
- id->fence_how, id->fence_time);
- }
-
- /* we can have no node when reduce_victims() removes it, bz 678704 */
-
- if (node) {
- list_del(&node->list);
- free(node);
- }
-}
-
-/* we know that the quorum value here is consistent with the cpg events
- because the ringid's are in sync per the previous check_ringid_done */
-
-static int check_quorum_done(struct fd *fd)
-{
- if (!cluster_quorate) {
- log_debug("check_quorum not quorate");
- return 0;
- }
-
- log_debug("check_quorum done");
- return 1;
-}
-
-/* wait for cman ringid and cpg ringid to be the same so we know our
- information from each service is based on the same node state */
-
-static int check_ringid_done(struct fd *fd)
-{
- if (cluster_ringid_seq != (uint32_t)fd->cpg_ringid.seq) {
- log_debug("check_ringid cluster %u cpg %u:%llu",
- cluster_ringid_seq, fd->cpg_ringid.nodeid,
- (unsigned long long)fd->cpg_ringid.seq);
- return 0;
- }
-
- log_debug("check_ringid done cluster %u cpg %u:%llu",
- cluster_ringid_seq, fd->cpg_ringid.nodeid,
- (unsigned long long)fd->cpg_ringid.seq);
- return 1;
-}
-
-static int wait_conditions_done(struct fd *fd)
-{
- if (!check_ringid_done(fd))
- return 0;
- if (!check_quorum_done(fd))
- return 0;
- return 1;
-}
-
-static int wait_messages_done(struct fd *fd)
-{
- struct change *cg = list_first_entry(&fd->changes, struct change, list);
- struct member *memb;
- int need = 0, total = 0;
-
- list_for_each_entry(memb, &cg->members, list) {
- if (!memb->start)
- need++;
- total++;
- }
-
- if (need) {
- log_debug("wait_messages cg %u need %d of %d",
- cg->seq, need, total);
- return 0;
- }
-
- log_debug("wait_messages cg %u got all %d", cg->seq, total);
- return 1;
-}
-
-static void cleanup_changes(struct fd *fd)
-{
- struct change *cg = list_first_entry(&fd->changes, struct change, list);
- struct change *safe;
-
- list_del(&cg->list);
- if (fd->started_change)
- free_cg(fd->started_change);
- fd->started_change = cg;
-
- /* zero started_count means "never started" */
-
- fd->started_count++;
- if (!fd->started_count)
- fd->started_count++;
-
- list_for_each_entry_safe(cg, safe, &fd->changes, list) {
- list_del(&cg->list);
- free_cg(cg);
- }
-}
-
-static void set_master(struct fd *fd)
-{
- struct change *cg = list_first_entry(&fd->changes, struct change, list);
- struct member *memb;
- int low = 0, complete = 0;
-
- list_for_each_entry(memb, &cg->members, list) {
- if (!low || memb->nodeid < low)
- low = memb->nodeid;
-
- if (!(memb->start_flags & FD_MFLG_COMPLETE))
- continue;
-
- if (!complete || memb->nodeid < complete)
- complete = memb->nodeid;
- }
-
- log_debug("set_master from %d to %s node %d", fd->master,
- complete ? "complete" : "low",
- complete ? complete : low);
-
- fd->master = complete ? complete : low;
-}
-
-static struct id_info *get_id_struct(struct id_info *ids, int count, int size,
- int nodeid)
-{
- struct id_info *id = ids;
- int i;
-
- for (i = 0; i < count; i++) {
- if (id->nodeid == nodeid)
- return id;
- id = (struct id_info *)((char *)id + size);
- }
- return NULL;
-}
-
-/* do the change details in the message match the details of the given change */
-
-static int match_change(struct fd *fd, struct change *cg, struct fd_header *hd,
- struct fd_info *fi, struct id_info *ids)
-{
- struct id_info *id;
- struct member *memb;
- struct node_history *node;
- uint32_t seq = hd->msgdata;
- int i, members_mismatch;
-
- /* We can ignore messages if we're not in the list of members.
- The one known time this will happen is after we've joined
- the cpg, we can get messages for changes prior to the change
- in which we're added. */
-
- id = get_id_struct(ids, fi->id_info_count, fi->id_info_size,our_nodeid);
-
- if (!id || !(id->flags & IDI_NODEID_IS_MEMBER)) {
- log_debug("match_change %d:%u skip cg %u we are not in members",
- hd->nodeid, seq, cg->seq);
- return 0;
- }
-
- memb = find_memb(cg, hd->nodeid);
- if (!memb) {
- log_debug("match_change %d:%u skip cg %u sender not member",
- hd->nodeid, seq, cg->seq);
- return 0;
- }
-
- if (memb->start) {
- log_debug("match_change %d:%u skip cg %u already start",
- hd->nodeid, seq, cg->seq);
- return 0;
- }
-
- /* a node's start can't match a change if the node joined the cluster
- more recently than the change was created */
-
- node = get_node_history(fd, hd->nodeid);
- if (!node) {
- log_debug("match_change %d:%u skip cg %u no node history",
- hd->nodeid, seq, cg->seq);
- return 0;
- }
-
- if (node->cluster_add_time > cg->create_time) {
- log_debug("match_change %d:%u skip cg %u created %llu "
- "cluster add %llu", hd->nodeid, seq, cg->seq,
- (unsigned long long)cg->create_time,
- (unsigned long long)node->cluster_add_time);
- return 0;
- }
-
- /* this start message couldn't have been sent for a cg preceding
- a confchg when the sending node failed or left */
-
- if ((node->fail_seq > cg->seq) || (node->left_seq > cg->seq)) {
- log_debug("match_change %d:%u skip cg %u fail cg %u left cg %u",
- hd->nodeid, seq, cg->seq,
- node->fail_seq, node->left_seq);
- return 0;
- }
-
- /* if we matched the last start message from this node against our
- cg N, then don't match this stsart message against an earlier cg */
-
- if (node->last_match_seq > cg->seq) {
- log_debug("match_change %d:%u skip cg %u last matched cg %u",
- hd->nodeid, seq, cg->seq, node->last_match_seq);
- return 0;
- }
-
- /* verify this is the right change by matching the counts
- and the nodeids of the current members */
-
- if (fi->member_count != cg->member_count ||
- fi->joined_count != cg->joined_count ||
- fi->remove_count != cg->remove_count ||
- fi->failed_count != cg->failed_count) {
- log_debug("match_change %d:%u skip cg %u expect counts "
- "%d %d %d %d", hd->nodeid, seq, cg->seq,
- cg->member_count, cg->joined_count,
- cg->remove_count, cg->failed_count);
- return 0;
- }
-
- members_mismatch = 0;
- id = ids;
-
- for (i = 0; i < fi->id_info_count; i++) {
- if (id->flags & IDI_NODEID_IS_MEMBER) {
- memb = find_memb(cg, id->nodeid);
- if (!memb) {
- log_debug("match_change %d:%u skip cg %u "
- "no memb %d", hd->nodeid, seq,
- cg->seq, id->nodeid);
- members_mismatch = 1;
- break;
- }
- }
- id = (struct id_info *)((char *)id + fi->id_info_size);
- }
-
- if (members_mismatch)
- return 0;
-
- node->last_match_seq = cg->seq;
-
- log_debug("match_change %d:%u matches cg %u", hd->nodeid, seq, cg->seq);
- return 1;
-}
-
-/* Unfortunately, there's no really simple way to match a message with the
- specific change that it was sent for. We hope that by passing all the
- details of the change in the message, we will be able to uniquely match the
- it to the correct change. */
-
-/* A start message will usually be for the first (current) change on our list.
- In some cases it will be for a non-current change, and we can ignore it:
-
- 1. A,B,C get confchg1 adding C
- 2. C sends start for confchg1
- 3. A,B,C get confchg2 adding D
- 4. A,B,C,D recv start from C for confchg1 - ignored
- 5. C,D send start for confchg2
- 6. A,B send start for confchg2
- 7. A,B,C,D recv all start messages for confchg2, and start kernel
-
- In step 4, how do the nodes know whether the start message from C is
- for confchg1 or confchg2? Hopefully by comparing the counts and members. */
-
-/* fails to handle partition, merge, kill, failing/manual fence, rejoin.
- a. m=A,B,C,D
- b. m=A/B,C,D partition, node B fencing node A, manual, or agent failing
- c. m=A,B,C,D merge, nodes B,C,D kill cman on node A
- d. m=B,C,D
- e. m=A,B,C,D clean rejoin by node A
- f. node B quits fencing retries on node A and sends victim_done/MEMBER/A
-
- The problem is that node A in step e receives node B's start message
- from step c and wrongly thinks it's for step e (member and join lists
- are the same m=A,B,C,D j=A). Node B sends the start message for step c
- so late because it was busy retrying fencing until node A cleanly rejoined
- in step e, then moved on to process cpg events c, d and e.
-
- Second problem with this test (not related to change matching) is node B
- gets stuck on cman is_member checks for the failure of node A due to the
- kill. It's waiting for B to become a non-member in cman due to the failure,
- but B has rejoined since that past failure and won't go away again.
-
- Possible solution to both problmes:
- Wait for cpg and cman to be in sync with each other (matching ringid's
- from both api's?) in wait_conditions.
-
- a) To replace quorum_done check. (it would be ok for cman ringid to
- be > cpg ringid for this check but not for other). This ensures that
- cman is not lagging behind cpg. Waits for cman to catch up with cpg.
-
- b) To avoid sending start for an old cpg confchg. If cman ringid
- is > cpg ringid, then return 0 for conditions_done so we won't send
- start and will wait until the most recent cpg confchg (matching the
- current cman one) to send a start. Waits for cpg to catch up with cman.
-
- Final solution is the patch adding check_ringid_done() that waits for
- cman and cpg to both be on the same ringid before going ahead to check
- quorum and send starts.
-*/
-
-static struct change *find_change(struct fd *fd, struct fd_header *hd,
- struct fd_info *fi, struct id_info *ids)
-{
- struct change *cg;
- struct change *cg1 = NULL, *cg2 = NULL;
-
- list_for_each_entry_reverse(cg, &fd->changes, list) {
- if (!match_change(fd, cg, hd, fi, ids))
- continue;
-
- if (!(hd->flags & FD_MFLG_DUPLICATE_CG))
- return cg;
-
- /* this start message is for the second of two matching cg's */
-
- if (!cg1) {
- cg1 = cg;
- log_debug("find_change %d:%u match1 %u look for dup",
- hd->nodeid, hd->msgdata, cg1->seq);
- continue;
- } else {
- cg2 = cg;
- log_debug("find_change %d:%u match1 %u match2 %u",
- hd->nodeid, hd->msgdata, cg1->seq, cg2->seq);
- break;
- }
- }
-
- if (cg1 && cg2)
- return cg2;
- if (cg1)
- return cg1;
-
- log_debug("find_change %d:%u no match", hd->nodeid, hd->msgdata);
- return NULL;
-}
-
-static int is_added(struct fd *fd, int nodeid)
-{
- struct change *cg;
- struct member *memb;
-
- list_for_each_entry(cg, &fd->changes, list) {
- memb = find_memb(cg, nodeid);
- if (memb && memb->added)
- return 1;
- }
- return 0;
-}
-
-static void receive_start(struct fd *fd, struct fd_header *hd, int len)
-{
- struct change *cg;
- struct member *memb;
- struct fd_info *fi;
- struct id_info *ids;
- uint32_t seq = hd->msgdata;
- int added;
-
- log_debug("receive_start %d:%u len %d", hd->nodeid, seq, len);
-
- fi = (struct fd_info *)((char *)hd + sizeof(struct fd_header));
- ids = (struct id_info *)((char *)fi + sizeof(struct fd_info));
-
- fd_info_in(fi);
- ids_in(fi, ids);
-
- cg = find_change(fd, hd, fi, ids);
- if (!cg)
- return;
-
- memb = find_memb(cg, hd->nodeid);
- if (!memb) {
- /* this should never happen since match_change checks it */
- log_error("receive_start no member %d", hd->nodeid);
- return;
- }
-
- memb->start_flags = hd->flags;
-
- added = is_added(fd, hd->nodeid);
-
- if (added && fi->started_count && fd->started_count) {
- log_error("receive_start %d:%u add node with started_count %u",
- hd->nodeid, seq, fi->started_count);
-
- /* This is how we deal with cpg's that are partitioned and
- then merge back together. When the merge happens, the
- cpg on each side will see nodes from the other side being
- added, and neither side will have zero started_count. So,
- both sides will ignore start messages from the other side.
- This causes the the domain on each side to continue waiting
- for the missing start messages indefinately. To unblock
- things, all nodes from one side of the former partition
- need to fail. */
-
- /* This method of detecting a merge of a partitioned cpg
- assumes a joining node won't ever see an existing node
- as "added" under normal circumstances. */
-
- /* The fd->started_count condition is needed for the case
- where a node begins partitioned, has never started, and then
- is merged with other nodes that have started. We don't
- want this unstarted node to reject the started ones even
- though it sees them as "added". */
-
- memb->disallowed = 1;
- return;
- }
-
- node_history_start(fd, hd->nodeid);
- memb->start = 1;
-
- /* save any fencing history from this message that we don't have */
- save_history(fd, fi, ids);
-}
-
-static void receive_complete(struct fd *fd, struct fd_header *hd, int len)
-{
- struct fd_info *fi;
- struct id_info *ids, *id;
- uint32_t seq = hd->msgdata;
- struct node *node, *safe;
-
- log_debug("receive_complete %d:%u len %d", hd->nodeid, seq, len);
-
- if (fd->init_complete)
- return;
-
- fi = (struct fd_info *)((char *)hd + sizeof(struct fd_header));
- ids = (struct id_info *)((char *)fi + sizeof(struct fd_info));
-
- fd_info_in(fi);
- ids_in(fi, ids);
-
- id = get_id_struct(ids, fi->id_info_count, fi->id_info_size,our_nodeid);
-
- if (!id || !(id->flags & IDI_NODEID_IS_MEMBER)) {
- log_debug("receive_complete %d:%u we are not in members",
- hd->nodeid, seq);
- return;
- }
-
- fd->init_complete = 1;
-
- /* we may have victims from init which we can clear now */
- list_for_each_entry_safe(node, safe, &fd->victims, list) {
- log_debug("receive_complete clear victim nodeid %d init %d",
- node->nodeid, node->init_victim);
-
- if (node->init_victim) {
- list_del(&node->list);
- free(node);
- }
- }
-}
-
-static int count_ids(struct fd *fd)
-{
- struct node_history *node;
- int count = 0;
-
- list_for_each_entry(node, &fd->node_history, list)
- count++;
-
- return count;
-}
-
-static void send_info(struct fd *fd, struct change *cg, int type,
- uint32_t flags)
-{
- struct fd_header *hd;
- struct fd_info *fi;
- struct id_info *id;
- struct node_history *node;
- char *buf;
- uint32_t idflags;
- int len, id_count;
-
- id_count = count_ids(fd);
-
- len = sizeof(struct fd_header) + sizeof(struct fd_info) +
- id_count * sizeof(struct id_info);
-
- buf = malloc(len);
- if (!buf) {
- log_error("send_info len %d no mem", len);
- return;
- }
- memset(buf, 0, len);
-
- hd = (struct fd_header *)buf;
- fi = (struct fd_info *)(buf + sizeof(*hd));
- id = (struct id_info *)(buf + sizeof(*hd) + sizeof(*fi));
-
- /* fill in header (fd_send_message handles part of header) */
-
- hd->type = type;
- hd->msgdata = cg->seq;
- hd->flags = flags;
-
- if (cg->we_joined)
- hd->flags |= FD_MFLG_JOINING;
- if (fd->init_complete || fd->local_init_complete)
- hd->flags |= FD_MFLG_COMPLETE;
-
- /* fill in fd_info */
-
- fi->fd_info_size = cpu_to_le32(sizeof(struct fd_info));
- fi->id_info_size = cpu_to_le32(sizeof(struct id_info));
- fi->id_info_count = cpu_to_le32(id_count);
- fi->started_count = cpu_to_le32(fd->started_count);
- fi->member_count = cpu_to_le32(cg->member_count);
- fi->joined_count = cpu_to_le32(cg->joined_count);
- fi->remove_count = cpu_to_le32(cg->remove_count);
- fi->failed_count = cpu_to_le32(cg->failed_count);
-
- /* fill in id_info entries */
-
- list_for_each_entry(node, &fd->node_history, list) {
- idflags = 0;
- if (find_memb(cg, node->nodeid))
- idflags = IDI_NODEID_IS_MEMBER;
-
- id->flags = cpu_to_le32(idflags);
- id->nodeid = cpu_to_le32(node->nodeid);
- id->fence_external_node= cpu_to_le32(node->fence_external_node);
- id->fence_master = cpu_to_le32(node->fence_master);
- id->fence_how = cpu_to_le32(node->fence_how);
- id->fence_time = cpu_to_le64(node->fence_time);
- id->fence_external_time= cpu_to_le64(node->fence_external_time);
- id++;
- }
-
- log_debug("send_%s %d:%u flags %x started %u m %d j %d r %d f %d",
- type == FD_MSG_START ? "start" : "complete", our_nodeid,
- cg->seq, hd->flags, fd->started_count, cg->member_count,
- cg->joined_count, cg->remove_count, cg->failed_count);
-
- fd_send_message(fd, buf, len);
-
- free(buf);
-}
-
-static int same_members(struct change *cg1, struct change *cg2)
-{
- struct member *memb;
-
- list_for_each_entry(memb, &cg1->members, list) {
- if (!find_memb(cg2, memb->nodeid))
- return 0;
- }
- return 1;
-}
-
-static void send_start(struct fd *fd)
-{
- struct change *cg = list_first_entry(&fd->changes, struct change, list);
- struct change *cgtmp;
- uint32_t flags = 0;
-
- /* look for a previous matching cg that we don't want others to
- confuse for this one */
-
- list_for_each_entry(cgtmp, &fd->changes, list) {
- if (cgtmp->sent_start)
- continue;
-
- if (cgtmp->seq < cg->seq &&
- cgtmp->member_count == cg->member_count &&
- cgtmp->joined_count == cg->joined_count &&
- cgtmp->remove_count == cg->remove_count &&
- cgtmp->failed_count == cg->failed_count &&
- same_members(cgtmp, cg)) {
- log_debug("duplicate old cg %u new cg %u",
- cgtmp->seq, cg->seq);
- flags = FD_MFLG_DUPLICATE_CG;
- }
- }
-
- cg->sent_start = 1;
-
- send_info(fd, cg, FD_MSG_START, flags);
-}
-
-/* same content as a start message, a new (incomplete) node will look for
- a complete message that shows it as a member, when it sees one it can
- clear any init_victims and set init_complete for future cycles */
-
-static void send_complete(struct fd *fd)
-{
- struct change *cg = list_first_entry(&fd->changes, struct change, list);
-
- send_info(fd, cg, FD_MSG_COMPLETE, 0);
-}
-
-/* FIXME: better to just look in victims list for any nodes with init_victim? */
-
-static int nodes_added(struct fd *fd)
-{
- struct change *cg;
-
- list_for_each_entry(cg, &fd->changes, list) {
- if (cg->joined_count)
- return 1;
- }
- return 0;
-}
-
-/* If we're being added by the current change, we'll have an empty victims
- list, while other previous members may already have nodes in their
- victims list. So, we need to assume that any node in cluster.conf that's
- not a cluster member when we're added to the fd is already a victim.
- We can go back on that assumption, and clear out any presumed victims, when
- we see a message from a previous member saying that are no current victims.*/
-
-static void add_victims(struct fd *fd, struct change *cg)
-{
- struct member *memb;
- struct node *node;
-
- list_for_each_entry(memb, &cg->removed, list) {
- if (!memb->failed)
- continue;
- if (is_victim(fd, memb->nodeid)) {
- /* Only one scenario I know of where this happens:
- when a partitioned cpg merges and then the
- disallowed node is killed. The original
- partition makes the node a victim, and killing
- it after a merge will find it already a victim. */
- log_debug("add_victims node %d already victim",
- memb->nodeid);
- continue;
- }
- node = get_new_node(fd, memb->nodeid);
- if (!node)
- return;
- list_add(&node->list, &fd->victims);
- log_debug("add_victims node %d", node->nodeid);
-
- /*
- * If we haven't completed a start cycle yet, set
- * init_victim on any failed node so that receive_complete
- * will clear it. This is a hack for one specific scenario:
- *
- * - node 2 joins domain, blocks in startup fencing
- * - node 1 joins domain, waiting for messages in start cycle
- * - partition between 1,2
- * - 1 adds victim 2
- * (and sets init_victim below since 1 hasn't completed
- * a start cycle yet)
- * - partition removed
- * - node 2 completes startup fencing
- * - 2 gets confchg for partition
- * - 2 adds victim 1 (due to partition)
- * - 2 gets confchg for merge
- * - 2 does join for 1 (due to merge), begins start cycle
- * - start cycle adding node 1 finishes, 2 sends complete
- * - 2 reduces victim 1
- * - 1 receives complete for its join start cycle,
- * and clears victim 2 because we've set init_victim here
- */
-
- if (!fd->started_count) {
- log_debug("add_victims node %d set init_victim",
- node->nodeid);
- node->init_victim = 1;
- }
- }
-}
-
-/* with start messages from all members, we can pick which one should be master
- and do the fencing (low nodeid with state, "COMPLETE"). as the master
- successfully fences each victim, it sends a status message such that all
- members remove the node from their victims list.
-
- after all victims have been dealt following a change (or set of changes),
- the master sends a complete message that indicates the members of the group
- for the change it has completed processing. when a joining node sees this
- complete message and sees itself as a member, it knows it can clear all
- init_victims from startup init, and it sets init_complete so it will
- volunteer to be master in the next round by setting COMPLETE flag.
-
- once the master begins fencing victims, it won't process any new changes
- until it's done. the non-master members will process changes while the
- master is fencing, but will wait for the master to catch up in
- WAIT_MESSAGES. if the master fails, the others will no longer wait for it.*/
-
-static void apply_changes(struct fd *fd)
-{
- struct change *cg;
-
- if (list_empty(&fd->changes))
- return;
- cg = list_first_entry(&fd->changes, struct change, list);
-
- switch (cg->state) {
-
- case CGST_WAIT_CONDITIONS:
- if (wait_conditions_done(fd)) {
- send_start(fd);
- cg->state = CGST_WAIT_MESSAGES;
- }
- break;
-
- case CGST_WAIT_MESSAGES:
- if (wait_messages_done(fd)) {
- our_protocol.dr_ver.flags |= PV_STATEFUL;
- set_master(fd);
- cg->state = CGST_WAIT_FENCING; /* for queries */
-
- if (fd->master == our_nodeid) {
- delay_fencing(fd, nodes_added(fd));
- fence_victims(fd);
- send_complete(fd);
- fd->local_init_complete = 1;
- } else {
- defer_fencing(fd);
- }
-
- cleanup_changes(fd);
- fd->joining_group = 0;
- }
- break;
-
- default:
- log_error("apply_changes invalid state %d", cg->state);
- }
-}
-
-void process_fd_changes(void)
-{
- struct fd *fd, *safe;
-
- list_for_each_entry_safe(fd, safe, &domains, list) {
- if (!list_empty(&fd->changes))
- apply_changes(fd);
- }
-}
-
-static int add_change(struct fd *fd,
- const struct cpg_address *member_list,
- size_t member_list_entries,
- const struct cpg_address *left_list,
- size_t left_list_entries,
- const struct cpg_address *joined_list,
- size_t joined_list_entries,
- struct change **cg_out)
-{
- struct change *cg;
- struct member *memb;
- int i, error;
-
- cg = malloc(sizeof(struct change));
- if (!cg)
- goto fail_nomem;
- memset(cg, 0, sizeof(struct change));
- INIT_LIST_HEAD(&cg->members);
- INIT_LIST_HEAD(&cg->removed);
- cg->seq = ++fd->change_seq;
- cg->state = CGST_WAIT_CONDITIONS;
- cg->create_time = time(NULL);
-
- cg->member_count = member_list_entries;
- cg->joined_count = joined_list_entries;
- cg->remove_count = left_list_entries;
-
- for (i = 0; i < member_list_entries; i++) {
- memb = malloc(sizeof(struct member));
- if (!memb)
- goto fail_nomem;
- memset(memb, 0, sizeof(struct member));
- memb->nodeid = member_list[i].nodeid;
- list_add_tail(&memb->list, &cg->members);
- }
-
- for (i = 0; i < left_list_entries; i++) {
- memb = malloc(sizeof(struct member));
- if (!memb)
- goto fail_nomem;
- memset(memb, 0, sizeof(struct member));
- memb->nodeid = left_list[i].nodeid;
- if (left_list[i].reason == CPG_REASON_NODEDOWN ||
- left_list[i].reason == CPG_REASON_PROCDOWN) {
- memb->failed = 1;
- cg->failed_count++;
- }
- list_add_tail(&memb->list, &cg->removed);
-
- if (memb->failed)
- node_history_fail(fd, memb->nodeid, cg->seq);
- else
- node_history_left(fd, memb->nodeid, cg->seq);
-
- log_debug("add_change cg %u remove nodeid %d reason %d",
- cg->seq, memb->nodeid, left_list[i].reason);
-
- if (left_list[i].reason == CPG_REASON_PROCDOWN)
- kick_node_from_cluster(memb->nodeid);
- }
-
- for (i = 0; i < joined_list_entries; i++) {
- memb = find_memb(cg, joined_list[i].nodeid);
- if (!memb) {
- log_error("no member %d", joined_list[i].nodeid);
- error = -ENOENT;
- goto fail;
- }
- memb->added = 1;
-
- if (memb->nodeid == our_nodeid)
- cg->we_joined = 1;
- else
- node_history_init(fd, memb->nodeid);
-
- log_debug("add_change cg %u joined nodeid %d", cg->seq,
- memb->nodeid);
- }
-
- if (cg->we_joined)
- list_for_each_entry(memb, &cg->members, list)
- node_history_init(fd, memb->nodeid);
-
- log_debug("add_change cg %u m %d j %d r %d f %d",
- cg->seq, cg->member_count, cg->joined_count,
- cg->remove_count, cg->failed_count);
-
- list_add(&cg->list, &fd->changes);
- *cg_out = cg;
- return 0;
-
- fail_nomem:
- log_error("no memory");
- error = -ENOMEM;
- fail:
- free_cg(cg);
- return error;
-}
-
-/* add a victim for each node in complete list (represents all nodes in
- cluster.conf) that is not a cman member (and not already a victim) */
-
-static void add_victims_init(struct fd *fd, struct change *cg)
-{
- struct node *node, *safe;
-
- list_for_each_entry_safe(node, safe, &fd->complete, list) {
- list_del(&node->list);
-
- if (!is_cluster_member_reread(node->nodeid) &&
- !find_memb(cg, node->nodeid) &&
- !is_victim(fd, node->nodeid)) {
- node->init_victim = 1;
- list_add(&node->list, &fd->victims);
- log_debug("add_victims_init nodeid %d", node->nodeid);
- } else {
- free(node);
- }
- }
-}
-
-static int we_left(const struct cpg_address *left_list,
- size_t left_list_entries)
-{
- int i;
-
- for (i = 0; i < left_list_entries; i++) {
- if (left_list[i].nodeid == our_nodeid)
- return 1;
- }
- return 0;
-}
-
-static void confchg_cb_domain(cpg_handle_t handle,
- const struct cpg_name *group_name,
- const struct cpg_address *member_list,
- size_t member_list_entries,
- const struct cpg_address *left_list,
- size_t left_list_entries,
- const struct cpg_address *joined_list,
- size_t joined_list_entries)
-{
- struct fd *fd;
- struct change *cg;
- int rv;
-
- log_config(group_name, member_list, member_list_entries,
- left_list, left_list_entries,
- joined_list, joined_list_entries);
-
- fd = find_fd_handle(handle);
- if (!fd) {
- log_error("confchg_cb no fence domain for cpg %s",
- group_name->value);
- return;
- }
-
- if (fd->leaving_group && we_left(left_list, left_list_entries)) {
- /* we called cpg_leave(), and this should be the final
- cpg callback we receive */
- log_debug("confchg for our leave");
- cpg_finalize(fd->cpg_handle);
- client_dead(fd->cpg_client);
- list_del(&fd->list);
- free_fd(fd);
- return;
- }
-
- rv = add_change(fd, member_list, member_list_entries,
- left_list, left_list_entries,
- joined_list, joined_list_entries, &cg);
- if (rv)
- return;
-
- /* failed nodes in this change become victims */
-
- add_victims(fd, cg);
-
- /* As a joining domain member with no previous state, we need to
- assume non-member nodes are already victims; these initial victims
- are cleared if we get a "complete" message from the master.
- But, if we're the master, we do end up fencing these init nodes. */
-
- if (cg->we_joined)
- add_victims_init(fd, cg);
-
- apply_changes(fd);
-}
-
-static void fd_header_in(struct fd_header *hd)
-{
- hd->version[0] = le16_to_cpu(hd->version[0]);
- hd->version[1] = le16_to_cpu(hd->version[1]);
- hd->version[2] = le16_to_cpu(hd->version[2]);
- hd->type = le16_to_cpu(hd->type);
- hd->nodeid = le32_to_cpu(hd->nodeid);
- hd->to_nodeid = le32_to_cpu(hd->to_nodeid);
- hd->global_id = le32_to_cpu(hd->global_id);
- hd->flags = le32_to_cpu(hd->flags);
- hd->msgdata = le32_to_cpu(hd->msgdata);
-}
-
-static void deliver_cb_domain(cpg_handle_t handle,
- const struct cpg_name *group_name,
- uint32_t nodeid, uint32_t pid,
- void *data, size_t len)
-{
- struct fd *fd;
- struct fd_header *hd;
-
- fd = find_fd_handle(handle);
- if (!fd) {
- log_error("deliver_cb no fd for cpg %s", group_name->value);
- return;
- }
-
- if (len < sizeof(*hd)) {
- log_error("deliver_cb short message %zd", len);
- return;
- }
-
- hd = (struct fd_header *)data;
- fd_header_in(hd);
-
- if (hd->version[0] != our_protocol.daemon_run[0] ||
- hd->version[1] != our_protocol.daemon_run[1]) {
- log_error("reject message from %d version %u.%u.%u vs %u.%u.%u",
- nodeid, hd->version[0], hd->version[1],
- hd->version[2], our_protocol.daemon_run[0],
- our_protocol.daemon_run[1],
- our_protocol.daemon_run[2]);
- return;
- }
-
- if (hd->nodeid != nodeid) {
- log_error("bad msg nodeid %d %d", hd->nodeid, nodeid);
- return;
- }
-
- switch (hd->type) {
- case FD_MSG_START:
- receive_start(fd, hd, len);
- break;
- case FD_MSG_VICTIM_DONE:
- receive_victim_done(fd, hd, len);
- break;
- case FD_MSG_COMPLETE:
- receive_complete(fd, hd, len);
- break;
- case FD_MSG_EXTERNAL:
- receive_external(fd, hd, len);
- break;
- default:
- log_error("unknown msg type %d", hd->type);
- }
-
- apply_changes(fd);
-}
-
-/* save ringid to compare with cman's.
- also save member_list to double check with cman's member list?
- they should match */
-
-static void totem_cb_domain(cpg_handle_t handle,
- struct cpg_ring_id ring_id,
- uint32_t member_list_entries,
- const uint32_t *member_list)
-{
- struct fd *fd;
-
- log_ringid(handle, &ring_id, member_list, member_list_entries);
-
- fd = find_fd_handle(handle);
- if (!fd) {
- log_error("totem_cb no fence domain for handle");
- return;
- }
-
- fd->cpg_ringid.nodeid = ring_id.nodeid;
- fd->cpg_ringid.seq = ring_id.seq;
-
- apply_changes(fd);
-}
-
-static cpg_model_v1_data_t cpg_callbacks_domain = {
- .cpg_deliver_fn = deliver_cb_domain,
- .cpg_confchg_fn = confchg_cb_domain,
- .cpg_totem_confchg_fn = totem_cb_domain,
- .flags = CPG_MODEL_V1_DELIVER_INITIAL_TOTEM_CONF,
-};
-
-static void process_cpg_domain(int ci)
-{
- struct fd *fd;
- cpg_error_t error;
-
- fd = find_fd_ci(ci);
- if (!fd) {
- log_error("process_cpg_domain no fence domain for ci %d", ci);
- return;
- }
-
- error = cpg_dispatch(fd->cpg_handle, CPG_DISPATCH_ALL);
- if (error != CPG_OK) {
- log_error("cpg_dispatch error %d", error);
- return;
- }
-}
-
-int fd_join(struct fd *fd)
-{
- cpg_error_t error;
- struct cpg_name name;
- int i = 0, ci;
-
- error = cpg_model_initialize(&cpg_handle_domain, CPG_MODEL_V1,
- (cpg_model_data_t *)&cpg_callbacks_domain,
- NULL);
- if (error != CPG_OK) {
- log_error("cpg_model_initialize error %d", error);
- goto fail_free;
- }
-
- cpg_fd_get(cpg_handle_domain, &cpg_fd_domain);
-
- ci = client_add(cpg_fd_domain, process_cpg_domain, NULL);
-
- list_add(&fd->list, &domains);
- fd->cpg_handle = cpg_handle_domain;
- fd->cpg_client = ci;
- fd->cpg_fd = cpg_fd_domain;
- fd->joining_group = 1;
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "fenced:%s", fd->name);
- name.length = strlen(name.value) + 1;
- memcpy(&group_name_domain, &name, sizeof(struct cpg_name));
-
- log_debug("cpg_join %s ...", name.value);
- retry:
- error = cpg_join(cpg_handle_domain, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- sleep(1);
- if (!(++i % 10))
- log_error("cpg_join error retrying");
- goto retry;
- }
- if (error != CPG_OK) {
- log_error("cpg_join error %d", error);
- goto fail;
- }
-
- return 0;
-
- fail:
- list_del(&fd->list);
- client_dead(ci);
- cpg_finalize(cpg_handle_domain);
- fail_free:
- free(fd);
- return error;
-}
-
-int fd_leave(struct fd *fd)
-{
- cpg_error_t error;
- struct cpg_name name;
- int i = 0;
-
- fd->leaving_group = 1;
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "fenced:%s", fd->name);
- name.length = strlen(name.value) + 1;
-
- log_debug("cpg_leave %s ...", name.value);
- retry:
- error = cpg_leave(fd->cpg_handle, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- sleep(1);
- if (!(++i % 10))
- log_error("cpg_leave error retrying");
- goto retry;
- }
- if (error != CPG_OK)
- log_error("cpg_leave error %d", error);
-
- return 0;
-}
-
-static struct node_daemon *get_node_daemon(int nodeid)
-{
- struct node_daemon *node;
-
- list_for_each_entry(node, &daemon_nodes, list) {
- if (node->nodeid == nodeid)
- return node;
- }
- return NULL;
-}
-
-static void add_node_daemon(int nodeid)
-{
- struct node_daemon *node;
-
- if (get_node_daemon(nodeid))
- return;
-
- node = malloc(sizeof(struct node_daemon));
- if (!node) {
- log_error("add_node_daemon no mem");
- return;
- }
- memset(node, 0, sizeof(struct node_daemon));
- node->nodeid = nodeid;
- list_add_tail(&node->list, &daemon_nodes);
-}
-
-static void pv_in(struct protocol_version *pv)
-{
- pv->major = le16_to_cpu(pv->major);
- pv->minor = le16_to_cpu(pv->minor);
- pv->patch = le16_to_cpu(pv->patch);
- pv->flags = le16_to_cpu(pv->flags);
-}
-
-static void pv_out(struct protocol_version *pv)
-{
- pv->major = cpu_to_le16(pv->major);
- pv->minor = cpu_to_le16(pv->minor);
- pv->patch = cpu_to_le16(pv->patch);
- pv->flags = cpu_to_le16(pv->flags);
-}
-
-static void protocol_in(struct protocol *proto)
-{
- pv_in(&proto->dm_ver);
- pv_in(&proto->dr_ver);
-}
-
-static void protocol_out(struct protocol *proto)
-{
- pv_out(&proto->dm_ver);
- pv_out(&proto->dr_ver);
-}
-
-/* go through member list saved in last confchg, see if we have received a
- proto message from each */
-
-static int all_protocol_messages(void)
-{
- struct node_daemon *node;
- int i;
-
- if (!daemon_member_count)
- return 0;
-
- for (i = 0; i < daemon_member_count; i++) {
- node = get_node_daemon(daemon_member[i].nodeid);
- if (!node) {
- log_error("all_protocol_messages no node %d",
- daemon_member[i].nodeid);
- return 0;
- }
-
- if (!node->proto.daemon_max[0])
- return 0;
- }
- return 1;
-}
-
-static int pick_min_protocol(struct protocol *proto)
-{
- uint16_t mind[4];
- struct node_daemon *node;
- int i;
-
- memset(&mind, 0, sizeof(mind));
-
- /* first choose the minimum major */
-
- for (i = 0; i < daemon_member_count; i++) {
- node = get_node_daemon(daemon_member[i].nodeid);
- if (!node) {
- log_error("pick_min_protocol no node %d",
- daemon_member[i].nodeid);
- return -1;
- }
-
- if (!mind[0] || node->proto.daemon_max[0] < mind[0])
- mind[0] = node->proto.daemon_max[0];
- }
-
- if (!mind[0]) {
- log_error("pick_min_protocol zero major number");
- return -1;
- }
-
- /* second pick the minimum minor with the chosen major */
-
- for (i = 0; i < daemon_member_count; i++) {
- node = get_node_daemon(daemon_member[i].nodeid);
- if (!node)
- continue;
-
- if (mind[0] == node->proto.daemon_max[0]) {
- if (!mind[1] || node->proto.daemon_max[1] < mind[1])
- mind[1] = node->proto.daemon_max[1];
- }
- }
-
- if (!mind[1]) {
- log_error("pick_min_protocol zero minor number");
- return -1;
- }
-
- /* third pick the minimum patch with the chosen major.minor */
-
- for (i = 0; i < daemon_member_count; i++) {
- node = get_node_daemon(daemon_member[i].nodeid);
- if (!node)
- continue;
-
- if (mind[0] == node->proto.daemon_max[0] &&
- mind[1] == node->proto.daemon_max[1]) {
- if (!mind[2] || node->proto.daemon_max[2] < mind[2])
- mind[2] = node->proto.daemon_max[2];
- }
- }
-
- if (!mind[2]) {
- log_error("pick_min_protocol zero patch number");
- return -1;
- }
-
- memcpy(&proto->daemon_run, &mind, sizeof(mind));
- return 0;
-}
-
-static void receive_protocol(struct fd_header *hd, int len)
-{
- struct protocol *p;
- struct node_daemon *node;
-
- p = (struct protocol *)((char *)hd + sizeof(struct fd_header));
- protocol_in(p);
-
- if (len < sizeof(struct fd_header) + sizeof(struct protocol)) {
- log_error("receive_protocol invalid len %d from %d",
- len, hd->nodeid);
- return;
- }
-
- /* zero is an invalid version value */
-
- if (!p->daemon_max[0] || !p->daemon_max[1] || !p->daemon_max[2]) {
- log_error("receive_protocol invalid max value from %d "
- "daemon %u.%u.%u", hd->nodeid,
- p->daemon_max[0], p->daemon_max[1], p->daemon_max[2]);
- return;
- }
-
- /* the run values will be zero until a version is set, after
- which none of the run values can be zero */
-
- if (p->daemon_run[0] && (!p->daemon_run[1] || !p->daemon_run[2])) {
- log_error("receive_protocol invalid run value from %d "
- "daemon %u.%u.%u", hd->nodeid,
- p->daemon_run[0], p->daemon_run[1], p->daemon_run[2]);
- return;
- }
-
- /* save this node's proto so we can tell when we've got all, and
- use it to select a minimum protocol from all */
-
- node = get_node_daemon(hd->nodeid);
- if (!node) {
- log_error("receive_protocol no node %d", hd->nodeid);
- return;
- }
-
- if (!node->is_member) {
- log_error("receive_protocol node %d not member", hd->nodeid);
- return;
- }
-
- log_debug("receive_protocol from %d max %u.%u.%u.%x run %u.%u.%u.%x",
- hd->nodeid,
- p->daemon_max[0], p->daemon_max[1],
- p->daemon_max[2], p->daemon_max[3],
- p->daemon_run[0], p->daemon_run[1],
- p->daemon_run[2], p->daemon_run[3]);
- log_debug("daemon node %d max %u.%u.%u.%x run %u.%u.%u.%x",
- hd->nodeid,
- node->proto.daemon_max[0], node->proto.daemon_max[1],
- node->proto.daemon_max[2], node->proto.daemon_max[3],
- node->proto.daemon_run[0], node->proto.daemon_run[1],
- node->proto.daemon_run[2], node->proto.daemon_run[3]);
- log_debug("daemon node %d join %llu left %llu local quorum %llu",
- hd->nodeid,
- (unsigned long long)node->join_time,
- (unsigned long long)node->left_time,
- (unsigned long long)quorate_time);
-
- /* checking zero node->daemon_max[0] is a way to tell if we've received
- an acceptable (non-stateful) proto message from the node since we
- saw it join the daemon cpg */
-
- if (hd->nodeid != our_nodeid &&
- !node->proto.daemon_max[0] &&
- (p->dr_ver.flags & PV_STATEFUL) &&
- (our_protocol.dr_ver.flags & PV_STATEFUL)) {
-
- log_debug("daemon node %d stateful merge", hd->nodeid);
-
- if (cluster_quorate && node->left_time &&
- quorate_time < node->left_time) {
- log_debug("daemon node %d kill due to stateful merge",
- hd->nodeid);
- if (!node->killed)
- kick_node_from_cluster(hd->nodeid);
- node->killed = 1;
- }
-
- /* don't save p->proto into node->proto; we need to come
- through here based on zero daemon_max[0] for other proto
- messages like this one from the same node */
-
- return;
- }
-
- memcpy(&node->proto, p, sizeof(struct protocol));
-
- /* if we have zero run values, and this msg has non-zero run values,
- then adopt them as ours; otherwise save this proto message */
-
- if (our_protocol.daemon_run[0])
- return;
-
- if (p->daemon_run[0]) {
- our_protocol.daemon_run[0] = p->daemon_run[0];
- our_protocol.daemon_run[1] = p->daemon_run[1];
- our_protocol.daemon_run[2] = p->daemon_run[2];
- log_debug("run protocol from nodeid %d", hd->nodeid);
- }
-}
-
-static void send_protocol(struct protocol *proto)
-{
- struct fd_header *hd;
- struct protocol *pr;
- char *buf;
- int len;
-
- len = sizeof(struct fd_header) + sizeof(struct protocol);
- buf = malloc(len);
- if (!buf) {
- log_error("send_protocol no mem %d", len);
- return;
- }
- memset(buf, 0, len);
-
- hd = (struct fd_header *)buf;
- pr = (struct protocol *)(buf + sizeof(*hd));
-
- hd->type = cpu_to_le16(FD_MSG_PROTOCOL);
- hd->nodeid = cpu_to_le32(our_nodeid);
-
- memcpy(pr, proto, sizeof(struct protocol));
- protocol_out(pr);
-
- _send_message(cpg_handle_daemon, buf, len, FD_MSG_PROTOCOL);
-}
-
-int set_protocol(void)
-{
- struct protocol proto;
- struct pollfd pollfd;
- int sent_proposal = 0;
- int rv;
-
- memset(&pollfd, 0, sizeof(pollfd));
- pollfd.fd = cpg_fd_daemon;
- pollfd.events = POLLIN;
-
- while (1) {
- if (our_protocol.daemon_run[0])
- break;
-
- if (!sent_proposal && all_protocol_messages()) {
- /* propose a protocol; look through info from all
- nodes and pick the min and propose that */
-
- sent_proposal = 1;
-
- /* copy our max values */
- memcpy(&proto, &our_protocol, sizeof(struct protocol));
-
- rv = pick_min_protocol(&proto);
- if (rv < 0)
- return rv;
-
- log_debug("set_protocol member_count %d propose "
- "daemon %u.%u.%u", daemon_member_count,
- proto.daemon_run[0], proto.daemon_run[1],
- proto.daemon_run[2]);
-
- send_protocol(&proto);
- }
-
- /* only process messages/events from daemon cpg until protocol
- is established */
-
- rv = poll(&pollfd, 1, -1);
- if (rv == -1 && errno == EINTR) {
- if (daemon_quit)
- return -1;
- continue;
- }
- if (rv < 0) {
- log_error("set_protocol poll errno %d", errno);
- return -1;
- }
-
- if (pollfd.revents & POLLIN)
- process_cpg_daemon(0);
- if (pollfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
- log_error("set_protocol poll revents %u",
- pollfd.revents);
- return -1;
- }
- }
-
- if (our_protocol.daemon_run[0] != our_protocol.daemon_max[0] ||
- our_protocol.daemon_run[1] > our_protocol.daemon_max[1]) {
- log_error("incompatible daemon protocol run %u.%u.%u max %u.%u.%u",
- our_protocol.daemon_run[0],
- our_protocol.daemon_run[1],
- our_protocol.daemon_run[2],
- our_protocol.daemon_max[0],
- our_protocol.daemon_max[1],
- our_protocol.daemon_max[2]);
- return -1;
- }
-
- log_debug("daemon run %u.%u.%u max %u.%u.%u",
- our_protocol.daemon_run[0],
- our_protocol.daemon_run[1],
- our_protocol.daemon_run[2],
- our_protocol.daemon_max[0],
- our_protocol.daemon_max[1],
- our_protocol.daemon_max[2]);
-
- send_protocol(&our_protocol);
- return 0;
-}
-
-/* process_cpg_daemon(), setup_cpg_daemon(), close_cpg_daemon() are for the
- "daemon" cpg which tracks the presence of other daemons; it's not the
- fence domain cpg. Joining this cpg tells others that we don't have
- uncontrolled dlm/gfs kernel state and they can skip fencing us if we're
- a victim. (We have to check for that uncontrolled state before calling
- setup_cpg_daemon, obviously.) */
-
-static void deliver_cb_daemon(cpg_handle_t handle,
- const struct cpg_name *group_name,
- uint32_t nodeid, uint32_t pid,
- void *data, size_t len)
-{
- struct fd_header *hd;
-
- if (len < sizeof(*hd)) {
- log_error("deliver_cb short message %zd", len);
- return;
- }
-
- hd = (struct fd_header *)data;
- fd_header_in(hd);
-
- switch (hd->type) {
- case FD_MSG_PROTOCOL:
- receive_protocol(hd, len);
- break;
- default:
- log_error("deliver_cb_daemon unknown msg type %d", hd->type);
- }
-}
-
-static int in_daemon_member_list(int nodeid)
-{
- int i;
-
- for (i = 0; i < daemon_member_count; i++) {
- if (daemon_member[i].nodeid == nodeid)
- return 1;
- }
- return 0;
-}
-
-static void confchg_cb_daemon(cpg_handle_t handle,
- const struct cpg_name *group_name,
- const struct cpg_address *member_list,
- size_t member_list_entries,
- const struct cpg_address *left_list,
- size_t left_list_entries,
- const struct cpg_address *joined_list,
- size_t joined_list_entries)
-{
- struct node_daemon *node;
- int i;
-
- log_config(group_name, member_list, member_list_entries,
- left_list, left_list_entries,
- joined_list, joined_list_entries);
-
- if (joined_list_entries)
- send_protocol(&our_protocol);
-
- memset(&daemon_member, 0, sizeof(daemon_member));
- daemon_member_count = member_list_entries;
-
- for (i = 0; i < member_list_entries; i++) {
- daemon_member[i] = member_list[i];
- /* add struct for nodes we've not seen before */
- add_node_daemon(member_list[i].nodeid);
- }
-
- list_for_each_entry(node, &daemon_nodes, list) {
- if (in_daemon_member_list(node->nodeid)) {
- if (node->is_member)
- continue;
-
- /* node joined daemon cpg */
- node->is_member = 1;
- node->join_time = time(NULL);
- } else {
- if (!node->is_member)
- continue;
-
- /* node left daemon cpg */
- node->is_member = 0;
- node->killed = 0;
- memset(&node->proto, 0, sizeof(struct protocol));
- node->left_time = time(NULL);
- }
- }
-}
-
-static void totem_cb_daemon(cpg_handle_t handle,
- struct cpg_ring_id ring_id,
- uint32_t member_list_entries,
- const uint32_t *member_list)
-{
- log_ringid(handle, &ring_id, member_list, member_list_entries);
-}
-
-static cpg_model_v1_data_t cpg_callbacks_daemon = {
- .cpg_deliver_fn = deliver_cb_daemon,
- .cpg_confchg_fn = confchg_cb_daemon,
- .cpg_totem_confchg_fn = totem_cb_daemon,
- .flags = CPG_MODEL_V1_DELIVER_INITIAL_TOTEM_CONF,
-};
-
-void process_cpg_daemon(int ci)
-{
- cpg_error_t error;
-
- error = cpg_dispatch(cpg_handle_daemon, CPG_DISPATCH_ALL);
- if (error != CPG_OK)
- log_error("daemon cpg_dispatch error %d", error);
-}
-
-/* For a new properly started node, it will join the daemon cpg then send a
- proto message indicating it's not stateful. For a node merged after a
- partition, it will join the daemon cpg and then send a proto message
- indicating it's stateful. To skip fencing a node we need to know it's
- joining after starting cleanly, so we need to see the daemon cpg joined
- followed by a proto message without the STATEFUL flag. */
-
-int is_clean_daemon_member(int nodeid)
-{
- struct node_daemon *node;
-
- /* process confchg's and protocol messages for daemon cpg,
- need to dispatch here because this is called from fence_victims()
- outside the poll() loop */
-
- cpg_dispatch(cpg_handle_daemon, CPG_DISPATCH_ALL);
-
- node = get_node_daemon(nodeid);
- if (node && node->is_member) {
- /* have we received a non-stateful proto message from it?
- if so then daemon_max[0] will be non-zero */
- if (node->proto.daemon_max[0]) {
- /* assert !(node->proto.dr_ver.flags & PV_STATEFUL) ? */
- log_debug("daemon_member %d is clean", nodeid);
- return 1;
- } else {
- log_debug("daemon_member %d zero proto", nodeid);
- return 0;
- }
- }
- /* log_debug("daemon_member %d not member", nodeid); */
- return 0;
-}
-
-int setup_cpg_daemon(void)
-{
- cpg_error_t error;
- struct cpg_name name;
- int i = 0;
-
- INIT_LIST_HEAD(&daemon_nodes);
-
- memset(&our_protocol, 0, sizeof(our_protocol));
- our_protocol.daemon_max[0] = 1;
- our_protocol.daemon_max[1] = 1;
- our_protocol.daemon_max[2] = 1;
-
- error = cpg_model_initialize(&cpg_handle_daemon, CPG_MODEL_V1,
- (cpg_model_data_t *)&cpg_callbacks_daemon,
- NULL);
- if (error != CPG_OK) {
- log_error("daemon cpg_model_initialize error %d", error);
- goto ret;
- }
-
- cpg_fd_get(cpg_handle_daemon, &cpg_fd_daemon);
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "fenced:daemon");
- name.length = strlen(name.value) + 1;
- memcpy(&group_name_daemon, &name, sizeof(struct cpg_name));
-
- log_debug("cpg_join %s ...", name.value);
- retry:
- error = cpg_join(cpg_handle_daemon, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- sleep(1);
- if (!(++i % 10))
- log_error("daemon cpg_join error retrying");
- goto retry;
- }
- if (error != CPG_OK) {
- log_error("daemon cpg_join error %d", error);
- goto fail;
- }
-
- log_debug("setup_cpg_daemon %d", cpg_fd_daemon);
- return cpg_fd_daemon;
-
- fail:
- cpg_finalize(cpg_handle_daemon);
- ret:
- return -1;
-}
-
-void close_cpg_daemon(void)
-{
- struct fd *fd;
- cpg_error_t error;
- struct cpg_name name;
- int i = 0;
-
- if (!cpg_handle_daemon)
- return;
- if (cluster_down)
- goto fin;
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "fenced:daemon");
- name.length = strlen(name.value) + 1;
-
- log_debug("cpg_leave %s ...", name.value);
- retry:
- error = cpg_leave(cpg_handle_daemon, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- sleep(1);
- if (!(++i % 10))
- log_error("daemon cpg_leave error retrying");
- goto retry;
- }
- if (error != CPG_OK)
- log_error("daemon cpg_leave error %d", error);
- fin:
- list_for_each_entry(fd, &domains, list) {
- if (fd->cpg_handle)
- cpg_finalize(fd->cpg_handle);
- }
- cpg_finalize(cpg_handle_daemon);
-}
-
-int set_node_info(struct fd *fd, int nodeid, struct fenced_node *nodeinfo)
-{
- struct node_history *node;
- struct member *memb;
- struct change *cg;
-
- nodeinfo->nodeid = nodeid;
- nodeinfo->victim = is_victim(fd, nodeid);
-
- if (list_empty(&fd->changes))
- cg = fd->started_change;
- else
- cg = list_first_entry(&fd->changes, struct change, list);
-
- if (cg) {
- memb = find_memb(cg, nodeid);
- if (memb)
- nodeinfo->member = memb->disallowed ? -1 : 1;
- }
-
- node = get_node_history(fd, nodeid);
- if (node) {
- nodeinfo->last_fenced_master = node->fence_master;
- nodeinfo->last_fenced_how = node->fence_how;
- nodeinfo->last_fenced_time = node->fence_time_local;
- }
-
- return 0;
-}
-
-int set_domain_info(struct fd *fd, struct fenced_domain *domain)
-{
- struct change *cg;
-
- if (list_empty(&fd->changes)) {
- if (fd->started_change)
- domain->member_count = fd->started_change->member_count;
- } else {
- cg = list_first_entry(&fd->changes, struct change, list);
- domain->member_count = cg->member_count;
- domain->state = cg->state;
- }
-
- domain->master_nodeid = fd->master;
- domain->victim_count = list_count(&fd->victims);
- domain->current_victim = fd->current_victim;
-
- return 0;
-}
-
-int set_domain_nodes(struct fd *fd, int option, int *node_count,
- struct fenced_node **nodes_out)
-{
- struct change *cg = fd->started_change;
- struct fenced_node *nodes = NULL, *n;
- struct node_history *nh;
- struct member *memb;
- int count = 0;
-
- if (option == FENCED_NODES_MEMBERS) {
- if (!cg)
- goto out;
- count = cg->member_count;
-
- nodes = malloc(count * sizeof(struct fenced_node));
- if (!nodes)
- return -ENOMEM;
- memset(nodes, 0, count * sizeof(struct fenced_node));
-
- n = nodes;
- list_for_each_entry(memb, &cg->members, list)
- set_node_info(fd, memb->nodeid, n++);
- }
-
- else if (option == FENCED_NODES_ALL) {
- list_for_each_entry(nh, &fd->node_history, list)
- count++;
-
- nodes = malloc(count * sizeof(struct fenced_node));
- if (!nodes)
- return -ENOMEM;
- memset(nodes, 0, count * sizeof(struct fenced_node));
-
- n = nodes;
- list_for_each_entry(nh, &fd->node_history, list)
- set_node_info(fd, nh->nodeid, n++);
- }
- out:
- *node_count = count;
- *nodes_out = nodes;
- return 0;
-}
-
diff --git a/fence/fenced/dbus.c b/fence/fenced/dbus.c
deleted file mode 100644
index 9d7be2f..0000000
--- a/fence/fenced/dbus.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include "fd.h"
-#include "config.h"
-
-#ifdef DBUS
-#include <dbus/dbus.h>
-
-#define DBUS_FENCE_NAME "com.redhat.cluster.fence"
-#define DBUS_FENCE_IFACE "com.redhat.cluster.fence"
-#define DBUS_FENCE_PATH "/com/redhat/cluster/fence"
-
-static DBusConnection *bus = NULL;
-
-void fd_dbus_init(void)
-{
- if (!(bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL))) {
- log_debug("failed to get dbus connection");
- } else {
- log_debug("connected to dbus %s", dbus_bus_get_unique_name(bus));
- }
-}
-
-void fd_dbus_exit(void)
-{
- if (bus) {
- dbus_connection_close(bus);
- dbus_connection_unref(bus);
- }
- bus = NULL;
-}
-
-void fd_dbus_send(const char *nodename, int nodeid, int result)
-{
- DBusMessage *msg = NULL;
-
- if (bus && !dbus_connection_read_write(bus, 1)) {
- log_debug("disconnected from dbus");
- fd_dbus_exit();
- }
-
- if (!bus) {
- fd_dbus_init();
- }
-
- if (!bus) {
- goto out;
- }
-
- if (!(msg = dbus_message_new_signal(DBUS_FENCE_PATH,
- DBUS_FENCE_IFACE,
- "FenceNode"))) {
- log_error("failed to create dbus signal");
- goto out;
- }
-
- if (!dbus_message_append_args(msg,
- DBUS_TYPE_STRING, &nodename,
- DBUS_TYPE_INT32, &nodeid,
- DBUS_TYPE_INT32, &result,
- DBUS_TYPE_INVALID)) {
- log_error("failed to append args to dbus signal");
- goto out;
- }
-
- dbus_connection_send(bus, msg, NULL);
- dbus_connection_flush(bus);
-
-out:
- if (msg) {
- dbus_message_unref(msg);
- }
-}
-
-#else
-
-void fd_dbus_init(void)
-{
-}
-
-void fd_dbus_exit(void)
-{
-}
-
-void fd_dbus_send(const char *nodename, int nodeid, int result)
-{
-}
-
-#endif /* DBUS */
diff --git a/fence/fenced/fd.h b/fence/fenced/fd.h
deleted file mode 100644
index 3032369..0000000
--- a/fence/fenced/fd.h
+++ /dev/null
@@ -1,299 +0,0 @@
-#ifndef __FD_DOT_H__
-#define __FD_DOT_H__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <signal.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <stdint.h>
-#include <time.h>
-#include <sched.h>
-#include <limits.h>
-#include <dirent.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/poll.h>
-#include <sys/select.h>
-#include <sys/time.h>
-#include <sys/file.h>
-
-#include <openais/saAis.h>
-#include <corosync/cpg.h>
-#include <liblogthread.h>
-
-#include "list.h"
-#include "linux_endian.h"
-#include "libfence.h"
-#include "libfenced.h"
-#include "fenced.h"
-
-/* Max name length for a group, pointless since we only ever create the
- "default" group. Regardless, set arbitrary max to match dlm's
- DLM_LOCKSPACE_LEN 64. The libcpg limit is larger at 128; we prefix
- the fence domain name with "fenced:" to create the cpg name. */
-
-#define MAX_GROUPNAME_LEN 64
-
-/* Max name length for a node. This should match libcman's
- CMAN_MAX_NODENAME_LEN which is 255. */
-
-#define MAX_NODENAME_LEN 255
-
-/* Maximum members of the fence domain, or cluster. Should match
- CPG_MEMBERS_MAX in openais/cpg.h. */
-
-#define MAX_NODES 128
-
-/* Max string length printed on a line, for debugging/dump output. */
-
-#define MAXLINE 256
-
-/* group_mode */
-
-#define GROUP_LIBGROUP 2
-#define GROUP_LIBCPG 3
-
-extern int daemon_debug_opt;
-extern int daemon_quit;
-extern int cluster_down;
-extern struct list_head domains;
-extern int cluster_quorate;
-extern int cluster_quorate_from_last_update;
-extern uint32_t cluster_ringid_seq;
-extern uint64_t quorate_time;
-extern int our_nodeid;
-extern char our_name[MAX_NODENAME_LEN+1];
-extern char daemon_debug_buf[256];
-extern char dump_buf[FENCED_DUMP_SIZE];
-extern int dump_point;
-extern int dump_wrap;
-extern int group_mode;
-extern int two_node_mode;
-
-extern void daemon_dump_save(void);
-
-#define log_level(lvl, fmt, args...) \
-do { \
- snprintf(daemon_debug_buf, 255, "%ld " fmt "\n", time(NULL), ##args); \
- daemon_dump_save(); \
- logt_print(lvl, fmt "\n", ##args); \
- if (daemon_debug_opt) \
- fprintf(stderr, "%s", daemon_debug_buf); \
-} while (0)
-
-#define log_debug(fmt, args...) log_level(LOG_DEBUG, fmt, ##args)
-#define log_error(fmt, args...) log_level(LOG_ERR, fmt, ##args)
-
-#define FD_MSG_PROTOCOL 1
-#define FD_MSG_START 2
-#define FD_MSG_VICTIM_DONE 3
-#define FD_MSG_COMPLETE 4
-#define FD_MSG_EXTERNAL 5
-
-#define FD_MFLG_JOINING 1 /* accompanies start, we are joining */
-#define FD_MFLG_COMPLETE 2 /* accompanies start, we have complete info */
-#define FD_MFLG_DUPLICATE_CG 4
-
-struct fd_header {
- uint16_t version[3];
- uint16_t type; /* FD_MSG_ */
- uint32_t nodeid; /* sender */
- uint32_t to_nodeid; /* recipient, 0 for all */
- uint32_t global_id; /* global unique id for this domain */
- uint32_t flags; /* FD_MFLG_ */
- uint32_t msgdata; /* in-header payload depends on MSG type */
- uint32_t pad1;
- uint64_t pad2;
-};
-
-#define CGST_WAIT_CONDITIONS 1
-#define CGST_WAIT_MESSAGES 2
-#define CGST_WAIT_FENCING 3 /* for queries */
-
-struct change {
- struct list_head list;
- struct list_head members;
- struct list_head removed; /* nodes removed by this change */
- int member_count;
- int joined_count;
- int remove_count;
- int failed_count;
- int state; /* CGST_ */
- int we_joined;
- int sent_start;
- uint32_t seq; /* just used as a reference when debugging */
- uint64_t create_time;
-};
-
-#define VIC_DONE_AGENT 1
-#define VIC_DONE_MEMBER 2
-#define VIC_DONE_OVERRIDE 3
-#define VIC_DONE_EXTERNAL 4
-
-struct node_history {
- struct list_head list;
- int nodeid;
- int check_quorum;
- uint64_t add_time;
- uint64_t left_time;
- uint64_t fail_time;
- uint64_t fence_time;
- uint64_t fence_time_local;
- uint64_t fence_external_time;
- uint64_t cluster_add_time;
- uint64_t cluster_remove_time;
- int fence_external_node;
- int fence_master;
- int fence_how; /* VIC_DONE_ */
- uint32_t last_match_seq;
- uint32_t fail_seq;
- uint32_t left_seq;
-};
-
-struct node {
- struct list_head list;
- int nodeid;
- int init_victim;
- int local_victim_done;
- char name[MAX_NODENAME_LEN+1];
-};
-
-struct fd {
- struct list_head list;
- char name[MAX_GROUPNAME_LEN+1];
-
- /* libcpg domain membership */
-
- cpg_handle_t cpg_handle;
- int cpg_client;
- int cpg_fd;
- uint32_t change_seq;
- uint32_t started_count;
- struct change *started_change;
- struct list_head changes;
- struct list_head node_history;
- int init_complete;
- int local_init_complete;
- struct cpg_ring_id cpg_ringid;
-
- /* general domain membership */
-
- int master;
- int joining_group;
- int leaving_group;
- int current_victim; /* for queries */
- struct list_head victims;
- struct list_head complete;
-
- /* libgroup domain membership */
-
- int last_stop;
- int last_start;
- int last_finish;
- int first_recovery;
- int prev_count;
- struct list_head prev;
- struct list_head leaving;
-};
-
-/* config.c */
-
-int setup_ccs(void);
-void close_ccs(void);
-void reread_ccs(void);
-void read_ccs_name(const char *path, char *name);
-void read_ccs_yesno(const char *path, int *yes, int *no);
-void read_ccs_int(const char *path, int *config_val);
-int read_ccs(struct fd *fd);
-
-/* cpg.c */
-
-void process_cpg_daemon(int ci);
-int setup_cpg_daemon(void);
-void close_cpg_daemon(void);
-int set_protocol(void);
-void free_cg(struct change *cg);
-void node_history_init(struct fd *fd, int nodeid);
-void node_history_fence(struct fd *fd, int victim, int master, int how,
- uint64_t mastertime);
-void send_external(struct fd *fd, int victim);
-int is_fenced_external(struct fd *fd, int nodeid);
-void send_victim_done(struct fd *fd, int victim);
-void process_fd_changes(void);
-int fd_join(struct fd *fd);
-int fd_leave(struct fd *fd);
-int set_node_info(struct fd *fd, int nodeid, struct fenced_node *node);
-int set_domain_info(struct fd *fd, struct fenced_domain *domain);
-int set_domain_nodes(struct fd *fd, int option, int *node_count,
- struct fenced_node **nodes);
-int is_clean_daemon_member(int nodeid);
-void node_history_cluster_add(int nodeid);
-void node_history_cluster_remove(int nodeid);
-
-/* group.c */
-
-void process_groupd(int ci);
-int setup_groupd(void);
-void close_groupd(void);
-int fd_join_group(struct fd *fd);
-int fd_leave_group(struct fd *fd);
-int set_node_info_group(struct fd *fd, int nodeid, struct fenced_node *node);
-int set_domain_info_group(struct fd *fd, struct fenced_domain *domain);
-int set_domain_nodes_group(struct fd *fd, int option, int *node_count,
- struct fenced_node **nodes);
-int set_group_mode(void);
-
-/* main.c */
-
-void client_dead(int ci);
-int client_add(int fd, void (*workfn)(int ci), void (*deadfn)(int ci));
-void free_fd(struct fd *fd);
-struct fd *find_fd(char *name);
-void query_lock(void);
-void query_unlock(void);
-void cluster_dead(int ci);
-
-/* member_cman.c */
-
-void process_cluster(int ci);
-int setup_cluster(void);
-void close_cluster(void);
-int is_cluster_member_reread(int nodeid);
-char *nodeid_to_name(int nodeid);
-int name_to_nodeid(char *name);
-struct node *get_new_node(struct fd *fd, int nodeid);
-void kick_node_from_cluster(int nodeid);
-void set_cman_dirty(void);
-int get_member_fd(void);
-
-/* recover.c */
-
-void free_node_list(struct list_head *head);
-void add_complete_node(struct fd *fd, int nodeid);
-int list_count(struct list_head *head);
-int is_victim(struct fd *fd, int nodeid);
-void delay_fencing(struct fd *fd, int node_join);
-void defer_fencing(struct fd *fd);
-void fence_victims(struct fd *fd);
-
-/* logging.c */
-
-void init_logging(void);
-void setup_logging(void);
-void close_logging(void);
-
-/* dbus.c */
-
-void fd_dbus_init(void);
-void fd_dbus_exit(void);
-void fd_dbus_send(const char *nodename, int nodeid, int result);
-
-#endif /* __FD_DOT_H__ */
-
diff --git a/fence/fenced/fenced.h b/fence/fenced/fenced.h
deleted file mode 100644
index fb7d951..0000000
--- a/fence/fenced/fenced.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef __FENCED_DOT_H__
-#define __FENCED_DOT_H__
-
-/* This defines the interface between fenced and libfenced, and should
- only be used by libfenced. */
-
-/* should match the same in fd.h */
-#define MAX_NODENAME_LEN 255
-
-#define FENCED_SOCK_PATH "fenced_sock"
-#define FENCED_QUERY_SOCK_PATH "fenced_query_sock"
-
-#define FENCED_MAGIC 0x0FE11CED
-#define FENCED_VERSION 0x00010001
-
-#define FENCED_CMD_JOIN 1
-#define FENCED_CMD_LEAVE 2
-#define FENCED_CMD_DUMP_DEBUG 3
-#define FENCED_CMD_EXTERNAL 4
-#define FENCED_CMD_NODE_INFO 5
-#define FENCED_CMD_DOMAIN_INFO 6
-#define FENCED_CMD_DOMAIN_NODES 7
-
-struct fenced_header {
- unsigned int magic;
- unsigned int version;
- unsigned int command;
- unsigned int option;
- unsigned int len;
- int data; /* embedded command-specific data, for convenience */
- int unused1;
- int unsued2;
-};
-
-#endif
-
diff --git a/fence/fenced/group.c b/fence/fenced/group.c
deleted file mode 100644
index d9ddd4e..0000000
--- a/fence/fenced/group.c
+++ /dev/null
@@ -1,489 +0,0 @@
-#include "fd.h"
-#include "config.h"
-#include "libgroup.h"
-
-#define DO_STOP 1
-#define DO_START 2
-#define DO_FINISH 3
-#define DO_TERMINATE 4
-#define DO_SETID 5
-
-#define GROUPD_TIMEOUT 10 /* seconds */
-
-/* save all the params from callback functions here because we can't
- do the processing within the callback function itself */
-
-static group_handle_t gh;
-static int cb_action;
-static char cb_name[MAX_GROUPNAME_LEN+1];
-static int cb_event_nr;
-static int cb_id;
-static int cb_type;
-static int cb_member_count;
-static int cb_members[MAX_NODES];
-
-
-static void stop_cbfn(group_handle_t h, void *private, char *name)
-{
- cb_action = DO_STOP;
- strcpy(cb_name, name);
-}
-
-static void start_cbfn(group_handle_t h, void *private, char *name,
- int event_nr, int type, int member_count, int *members)
-{
- int i;
-
- cb_action = DO_START;
- strcpy(cb_name, name);
- cb_event_nr = event_nr;
- cb_type = type;
- cb_member_count = member_count;
-
- for (i = 0; i < member_count; i++)
- cb_members[i] = members[i];
-}
-
-static void finish_cbfn(group_handle_t h, void *private, char *name,
- int event_nr)
-{
- cb_action = DO_FINISH;
- strcpy(cb_name, name);
- cb_event_nr = event_nr;
-}
-
-static void terminate_cbfn(group_handle_t h, void *private, char *name)
-{
- cb_action = DO_TERMINATE;
- strcpy(cb_name, name);
-}
-
-static void setid_cbfn(group_handle_t h, void *private, char *name,
- int unsigned id)
-{
- cb_action = DO_SETID;
- strcpy(cb_name, name);
- cb_id = id;
-}
-
-group_callbacks_t callbacks = {
- stop_cbfn,
- start_cbfn,
- finish_cbfn,
- terminate_cbfn,
- setid_cbfn
-};
-
-static char *str_members(void)
-{
- static char mbuf[MAXLINE];
- int i, len = 0;
-
- memset(mbuf, 0, MAXLINE);
-
- for (i = 0; i < cb_member_count; i++)
- len += sprintf(mbuf+len, "%d ", cb_members[i]);
- return mbuf;
-}
-
-static int id_in_nodeids(int nodeid, int count, int *nodeids)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- if (nodeid == nodeids[i])
- return 1;
- }
- return 0;
-}
-
-static int next_complete_nodeid(struct fd *fd, int gt)
-{
- struct node *node;
- int low = -1;
-
- /* find lowest node id in fd_complete greater than gt,
- if none, return -1 */
-
- list_for_each_entry(node, &fd->complete, list) {
- if (node->nodeid <= gt)
- continue;
-
- if (low == -1)
- low = node->nodeid;
- else if (node->nodeid < low)
- low = node->nodeid;
- }
- return low;
-}
-
-static void set_master(struct fd *fd)
-{
- struct node *node;
- int low = -1;
-
- /* Find the lowest nodeid common to fd->fd_prev (newest member list)
- * and fd->fd_complete (last complete member list). */
-
- for (;;) {
- low = next_complete_nodeid(fd, low);
- if (low == -1)
- break;
-
- list_for_each_entry(node, &fd->prev, list) {
- if (low != node->nodeid)
- continue;
- goto out;
- }
- }
-
- /* Special case: we're the first and only FD member */
-
- if (fd->prev_count == 1)
- low = our_nodeid;
-
- /* We end up returning -1 when we're not the only node and we've just
- joined. Because we've just joined we weren't in the last complete
- domain group and won't be chosen as master. We defer to someone who
- _was_ in the last complete group. All we know is it isn't us. */
-
- out:
- fd->master = low;
-}
-
-static void new_prev_nodes(struct fd *fd, int member_count, int *nodeids)
-{
- struct node *node;
- int i;
-
- for (i = 0; i < member_count; i++) {
- node = get_new_node(fd, nodeids[i]);
- list_add(&node->list, &fd->prev);
- }
-
- fd->prev_count = member_count;
-}
-
-static void _add_first_victims(struct fd *fd)
-{
- struct node *prev_node, *safe;
-
- /* complete list initialised in init_nodes() to all nodes from ccs */
- if (list_empty(&fd->complete))
- log_debug("first complete list empty warning");
-
- list_for_each_entry_safe(prev_node, safe, &fd->complete, list) {
- if (!is_cluster_member_reread(prev_node->nodeid)) {
- list_del(&prev_node->list);
- list_add(&prev_node->list, &fd->victims);
- log_debug("add first victim %s", prev_node->name);
- prev_node->init_victim = 1;
- }
- }
-}
-
-static void _add_victims(struct fd *fd, int start_type, int member_count,
- int *nodeids)
-{
- struct node *node, *safe;
-
- /* nodes which haven't completed leaving when a failure restart happens
- * are dead (and need fencing) or are still members */
-
- if (start_type == GROUP_NODE_FAILED) {
- list_for_each_entry_safe(node, safe, &fd->leaving, list) {
- list_del(&node->list);
- if (id_in_nodeids(node->nodeid, member_count, nodeids))
- list_add(&node->list, &fd->complete);
- else {
- list_add(&node->list, &fd->victims);
- log_debug("add victim %u, was leaving",
- node->nodeid);
- }
- }
- }
-
- /* nodes in last completed group but missing from fr_nodeids are added
- * to victims list or leaving list, depending on the type of start. */
-
- if (list_empty(&fd->complete))
- log_debug("complete list empty warning");
-
- list_for_each_entry_safe(node, safe, &fd->complete, list) {
- if (!id_in_nodeids(node->nodeid, member_count, nodeids)) {
- list_del(&node->list);
-
- if (start_type == GROUP_NODE_FAILED)
- list_add(&node->list, &fd->victims);
- else
- list_add(&node->list, &fd->leaving);
-
- log_debug("add node %u to list %u", node->nodeid,
- start_type);
- }
- }
-}
-
-static void add_victims(struct fd *fd, int start_type, int member_count,
- int *nodeids)
-{
- /* Reset things when the last stop aborted our first
- * start, i.e. there was no finish; we got a
- * start/stop/start immediately upon joining. */
-
- if (!fd->last_finish && fd->last_stop) {
- log_debug("revert aborted first start");
- fd->last_stop = 0;
- fd->first_recovery = 0;
- free_node_list(&fd->prev);
- free_node_list(&fd->victims);
- free_node_list(&fd->leaving);
- }
-
- log_debug("add_victims stop %d start %d finish %d",
- fd->last_stop, fd->last_start, fd->last_finish);
-
- if (!fd->first_recovery) {
- fd->first_recovery = 1;
- _add_first_victims(fd);
- } else
- _add_victims(fd, start_type, member_count, nodeids);
-
- /* "prev" is just a temporary list of node structs matching the list of
- nodeids from the start; these nodes are moved to the "complete" list
- in the finish callback, and will be used to compare against the
- next set of started nodes */
-
- free_node_list(&fd->prev);
- new_prev_nodes(fd, member_count, nodeids);
-}
-
-static void clear_victims(struct fd *fd)
-{
- struct node *node, *safe;
-
- if (fd->last_finish == fd->last_start) {
- free_node_list(&fd->leaving);
- free_node_list(&fd->victims);
- }
-
- /* Save a copy of this set of nodes which constitutes the latest
- * complete group. Any of these nodes missing in the next start will
- * either be leaving or victims. For the next recovery, the lowest
- * remaining nodeid in this group will be the master. */
-
- free_node_list(&fd->complete);
- list_for_each_entry_safe(node, safe, &fd->prev, list) {
- list_del(&node->list);
- list_add(&node->list, &fd->complete);
- }
-}
-
-void process_groupd(int ci)
-{
- struct fd *fd;
- int error = -EINVAL;
-
- group_dispatch(gh);
-
- if (!cb_action)
- goto out;
-
- fd = find_fd(cb_name);
- if (!fd)
- goto out;
-
- switch (cb_action) {
- case DO_STOP:
- log_debug("stop %s", cb_name);
- fd->last_stop = fd->last_start;
- group_stop_done(gh, cb_name);
- break;
-
- case DO_START:
- log_debug("start %s %d members %s", cb_name, cb_event_nr,
- str_members());
- fd->last_start = cb_event_nr;
-
- /* we don't get a start callback until there's quorum */
-
- add_victims(fd, cb_type, cb_member_count, cb_members);
- set_master(fd);
- if (fd->master == our_nodeid) {
- delay_fencing(fd, cb_type == GROUP_NODE_JOIN);
- fence_victims(fd);
- } else {
- defer_fencing(fd);
- }
-
- group_start_done(gh, cb_name, cb_event_nr);
- fd->joining_group = 0;
- break;
-
- case DO_FINISH:
- log_debug("finish %s %d", cb_name, cb_event_nr);
- fd->last_finish = cb_event_nr;
-
- /* we get terminate callback when all have started, which means
- that the low node has successfully fenced all victims */
- clear_victims(fd);
-
- break;
-
- case DO_TERMINATE:
- log_debug("terminate %s", cb_name);
- if (!fd->leaving_group)
- log_error("process_groupd terminate not leaving");
- list_del(&fd->list);
- free_fd(fd);
- break;
-
- case DO_SETID:
- break;
- default:
- error = -EINVAL;
- }
-
- cb_action = 0;
- out:
- return;
-}
-
-int setup_groupd(void)
-{
- int rv;
-
- gh = group_init(NULL, "fence", 0, &callbacks, GROUPD_TIMEOUT);
- if (!gh) {
- log_error("group_init error %p %d", gh, errno);
- return -ENOTCONN;
- }
- rv = group_get_fd(gh);
- if (rv < 0)
- log_error("group_get_fd error %d %d", rv, errno);
- return rv;
-}
-
-void close_groupd(void)
-{
- group_exit(gh);
-}
-
-int fd_join_group(struct fd *fd)
-{
- int rv;
-
- list_add(&fd->list, &domains);
- fd->joining_group = 1;
-
- rv = group_join(gh, fd->name);
- if (rv) {
- log_error("group_join error %d", rv);
- list_del(&fd->list);
- free(fd);
- return rv;
- }
- set_cman_dirty();
- return 0;
-}
-
-int fd_leave_group(struct fd *fd)
-{
- int rv;
-
- fd->leaving_group = 1;
-
- rv = group_leave(gh, fd->name);
- if (rv)
- log_error("group_leave error %d", rv);
-
- return rv;
-}
-
-int set_node_info_group(struct fd *fd, int nodeid, struct fenced_node *nodeinfo)
-{
- nodeinfo->nodeid = nodeid;
- nodeinfo->victim = is_victim(fd, nodeid);
- nodeinfo->member = id_in_nodeids(nodeid, cb_member_count, cb_members);
-
- /* FIXME: we don't keep track of last_fenced_* in this libgroup code,
- maybe just leave it out */
-
- return 0;
-}
-
-int set_domain_info_group(struct fd *fd, struct fenced_domain *domain)
-{
- domain->master_nodeid = fd->master;
- domain->victim_count = list_count(&fd->victims);
- domain->member_count = cb_member_count;
- domain->state = cb_action;
- domain->current_victim = fd->current_victim;
- return 0;
-}
-
-int set_domain_nodes_group(struct fd *fd, int option, int *node_count,
- struct fenced_node **nodes_out)
-{
- struct fenced_node *nodes = NULL, *nodep;
- int i;
-
- if (!cb_member_count)
- goto out;
-
- nodes = malloc(cb_member_count * sizeof(struct fenced_node));
- if (!nodes)
- return -ENOMEM;
- memset(nodes, 0, sizeof(*nodes));
-
- nodep = nodes;
- for (i = 0; i < cb_member_count; i++) {
- set_node_info_group(fd, cb_members[i], nodep++);
- }
- out:
- *node_count = cb_member_count;
- *nodes_out = nodes;
- return 0;
-}
-
-int set_group_mode(void)
-{
- int i = 0, rv, version, limit;
-
- while (1) {
- rv = group_get_version(&version);
-
- if (rv || version < 0) {
- /* we expect to get version of -EAGAIN while groupd
- is detecting the mode of everyone; don't retry
- as long if we're not getting anything back from
- groupd */
-
- log_debug("set_group_mode get_version %d ver %d",
- rv, version);
-
- limit = (version == -EAGAIN) ? 30 : 5;
-
- if (i++ > limit) {
- log_error("cannot get groupd compatibility "
- "mode rv %d ver %d", rv, version);
- return -1;
- }
- sleep(1);
- continue;
- }
-
-
- if (version == GROUP_LIBGROUP) {
- group_mode = GROUP_LIBGROUP;
- return 0;
- } else if (version == GROUP_LIBCPG) {
- group_mode = GROUP_LIBCPG;
- return 0;
- } else {
- log_error("set_group_mode invalid ver %d", version);
- return -1;
- }
- }
-}
-
diff --git a/fence/fenced/logging.c b/fence/fenced/logging.c
deleted file mode 100644
index 56a7e08..0000000
--- a/fence/fenced/logging.c
+++ /dev/null
@@ -1,92 +0,0 @@
-#include "fd.h"
-#include "config.h"
-#include "ccs.h"
-
-extern int ccs_handle;
-
-#define DAEMON_NAME "fenced"
-#define DEFAULT_LOG_MODE LOG_MODE_OUTPUT_FILE|LOG_MODE_OUTPUT_SYSLOG
-#define DEFAULT_SYSLOG_FACILITY SYSLOGFACILITY
-#define DEFAULT_SYSLOG_PRIORITY SYSLOGLEVEL
-#define DEFAULT_LOGFILE_PRIORITY LOG_INFO /* ? */
-#define DEFAULT_LOGFILE LOGDIR "/" DAEMON_NAME ".log"
-
-static int log_mode;
-static int syslog_facility;
-static int syslog_priority;
-static int logfile_priority;
-static char logfile[PATH_MAX];
-
-void init_logging(void)
-{
- log_mode = DEFAULT_LOG_MODE;
- syslog_facility = DEFAULT_SYSLOG_FACILITY;
- syslog_priority = DEFAULT_SYSLOG_PRIORITY;
- logfile_priority = DEFAULT_LOGFILE_PRIORITY;
- strcpy(logfile, DEFAULT_LOGFILE);
-
- /* logfile_priority is the only one of these options that
- can be controlled from command line or environment variable */
-
- if (cfgd_debug_logfile)
- logfile_priority = LOG_DEBUG;
-
- log_debug("logging mode %d syslog f %d p %d logfile p %d %s",
- log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-
- logt_init(DAEMON_NAME, log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-}
-
-#define DEFAULT_LOGFILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
-
-void setup_logging(void)
-{
- struct stat buf;
- int rv;
-
- ccs_read_logging(ccs_handle, DAEMON_NAME,
- &cfgd_debug_logfile, &log_mode,
- &syslog_facility, &syslog_priority,
- &logfile_priority, logfile);
-
- log_debug("logging mode %d syslog f %d p %d logfile p %d %s",
- log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-
- logt_conf(DAEMON_NAME, log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-
- /*
- * Previously fenced.log was created with mode 666,
- * so fix it to be 644.
- */
-
- rv = stat(logfile, &buf);
- if (rv)
- return;
-
- log_debug("logfile cur mode %lo", (unsigned long)buf.st_mode);
-
- if ((buf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) == DEFAULT_LOGFILE_MODE)
- return;
-
- rv = chmod(logfile, DEFAULT_LOGFILE_MODE);
- if (rv) {
- log_error("chmod error %d", errno);
- return;
- }
-
- rv = stat(logfile, &buf);
- if (rv)
- return;
-
- log_debug("logfile new mode %lo", (unsigned long)buf.st_mode);
-}
-
-void close_logging(void)
-{
- logt_exit();
-}
-
diff --git a/fence/fenced/main.c b/fence/fenced/main.c
deleted file mode 100644
index 360e73e..0000000
--- a/fence/fenced/main.c
+++ /dev/null
@@ -1,1092 +0,0 @@
-#include "fd.h"
-#include "config.h"
-#include <pthread.h>
-#include "copyright.cf"
-
-#define LOCKFILE_NAME "/var/run/fenced.pid"
-#define CLIENT_NALLOC 32
-
-static int client_maxi;
-static int client_size = 0;
-static struct client *client = NULL;
-static struct pollfd *pollfd = NULL;
-static pthread_t query_thread;
-static pthread_mutex_t query_mutex;
-static struct list_head controlled_entries;
-static char default_name[8];
-
-struct client {
- int fd;
- void *workfn;
- void *deadfn;
-};
-
-static int do_read(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- while (off < count) {
- rv = read(fd, (char *)buf + off, count - off);
- if (rv == 0)
- return -1;
- if (rv == -1 && errno == EINTR)
- continue;
- if (rv == -1)
- return -1;
- off += rv;
- }
- return 0;
-}
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, (char *)buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0) {
- return rv;
- }
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-static void client_alloc(void)
-{
- int i;
-
- if (!client) {
- client = malloc(CLIENT_NALLOC * sizeof(struct client));
- pollfd = malloc(CLIENT_NALLOC * sizeof(struct pollfd));
- } else {
- client = realloc(client, (client_size + CLIENT_NALLOC) *
- sizeof(struct client));
- pollfd = realloc(pollfd, (client_size + CLIENT_NALLOC) *
- sizeof(struct pollfd));
- if (!pollfd)
- log_error("can't alloc for pollfd");
- }
- if (!client || !pollfd)
- log_error("can't alloc for client array");
-
- for (i = client_size; i < client_size + CLIENT_NALLOC; i++) {
- client[i].workfn = NULL;
- client[i].deadfn = NULL;
- client[i].fd = -1;
- pollfd[i].fd = -1;
- pollfd[i].revents = 0;
- }
- client_size += CLIENT_NALLOC;
-}
-
-void client_dead(int ci)
-{
- close(client[ci].fd);
- client[ci].workfn = NULL;
- client[ci].fd = -1;
- pollfd[ci].fd = -1;
-}
-
-int client_add(int fd, void (*workfn)(int ci), void (*deadfn)(int ci))
-{
- int i;
-
- if (!client)
- client_alloc();
- again:
- for (i = 0; i < client_size; i++) {
- if (client[i].fd == -1) {
- client[i].workfn = workfn;
- if (deadfn)
- client[i].deadfn = deadfn;
- else
- client[i].deadfn = client_dead;
- client[i].fd = fd;
- pollfd[i].fd = fd;
- pollfd[i].events = POLLIN;
- if (i > client_maxi)
- client_maxi = i;
- return i;
- }
- }
-
- client_alloc();
- goto again;
-}
-
-static void sigterm_handler(int sig)
-{
- daemon_quit = 1;
-}
-
-static struct fd *create_fd(char *name)
-{
- struct fd *fd;
-
- if (strlen(name) > MAX_GROUPNAME_LEN)
- return NULL;
-
- fd = malloc(sizeof(struct fd));
- if (!fd)
- return NULL;
-
- memset(fd, 0, sizeof(struct fd));
- strcpy(fd->name, name);
-
- INIT_LIST_HEAD(&fd->changes);
- INIT_LIST_HEAD(&fd->node_history);
- INIT_LIST_HEAD(&fd->victims);
- INIT_LIST_HEAD(&fd->complete);
- INIT_LIST_HEAD(&fd->prev);
- INIT_LIST_HEAD(&fd->leaving);
-
- return fd;
-}
-
-void free_fd(struct fd *fd)
-{
- struct change *cg, *cg_safe;
- struct node_history *nodeh, *nodeh_safe;
-
- list_for_each_entry_safe(cg, cg_safe, &fd->changes, list) {
- list_del(&cg->list);
- free_cg(cg);
- }
- if (fd->started_change)
- free_cg(fd->started_change);
-
- list_for_each_entry_safe(nodeh, nodeh_safe, &fd->node_history, list) {
- list_del(&nodeh->list);
- free(nodeh);
- }
-
- free_node_list(&fd->victims);
- free_node_list(&fd->complete);
- free_node_list(&fd->prev);
- free_node_list(&fd->leaving);
-
- free(fd);
-}
-
-struct fd *find_fd(char *name)
-{
- struct fd *fd;
-
- list_for_each_entry(fd, &domains, list) {
- if (strlen(name) == strlen(fd->name) &&
- !strncmp(fd->name, name, strlen(name)))
- return fd;
- }
- return NULL;
-}
-
-/* We don't require cman dirty/disallowed to detect and handle cpg merges after
- a partition, because we already do that with started_count checks and our
- own disallowed flag. We also don't require cman dirty/disallowed to deal
- with correctly skipping victims that rejoin the cluster. If a victim
- joins the fenced:daemon cpg and sends a proto message without the STATEFUL
- flag, then we safely skip fencing it. This is what happens when the node
- starts cleanly. If a node is added back after a partition, we see it join
- the fenced:daemon cpg and it send a proto message with the STATEFUL flag set.
- In this case it remains a victim and we will continue with fencing it. */
-
-static int do_join(char *name)
-{
- struct fd *fd;
- int rv;
-
- fd = find_fd(name);
- if (fd) {
- log_debug("join error: domain %s exists", name);
- rv = -EEXIST;
- goto out;
- }
-
- fd = create_fd(name);
- if (!fd) {
- rv = -ENOMEM;
- goto out;
- }
-
- rv = read_ccs(fd);
- if (rv) {
- free(fd);
- goto out;
- }
-
- if (group_mode == GROUP_LIBGROUP)
- rv = fd_join_group(fd);
- else
- rv = fd_join(fd);
- out:
- return rv;
-}
-
-static int do_leave(char *name)
-{
- struct fd *fd;
- int rv;
-
- fd = find_fd(name);
- if (!fd)
- return -EINVAL;
-
- if (group_mode == GROUP_LIBGROUP)
- rv = fd_leave_group(fd);
- else
- rv = fd_leave(fd);
-
- return rv;
-}
-
-static int do_external(char *name, char *extra, int extra_len)
-{
- struct fd *fd;
- int rv = 0;
-
- fd = find_fd(name);
- if (!fd)
- return -EINVAL;
-
- if (group_mode == GROUP_LIBGROUP)
- rv = -ENOSYS;
- else
- send_external(fd, name_to_nodeid(extra));
-
- return rv;
-}
-
-static void init_header(struct fenced_header *h, int cmd, int result,
- int extra_len)
-{
- memset(h, 0, sizeof(struct fenced_header));
-
- h->magic = FENCED_MAGIC;
- h->version = FENCED_VERSION;
- h->len = sizeof(struct fenced_header) + extra_len;
- h->command = cmd;
- h->data = result;
-}
-
-/* combines a header and the data and sends it back to the client in
- a single do_write() call */
-
-static void do_reply(int f, int cmd, int result, char *buf, int buflen)
-{
- char *reply;
- int reply_len;
-
- reply_len = sizeof(struct fenced_header) + buflen;
- reply = malloc(reply_len);
- if (!reply)
- return;
- memset(reply, 0, reply_len);
-
- init_header((struct fenced_header *)reply, cmd, result, buflen);
-
- if (buf && buflen)
- memcpy(reply + sizeof(struct fenced_header), buf, buflen);
-
- do_write(f, reply, reply_len);
-
- free(reply);
-}
-
-static void query_dump_debug(int f)
-{
- struct fenced_header h;
- int extra_len;
- int len;
-
- /* in the case of dump_wrap, extra_len will go in two writes,
- first the log tail, then the log head */
- if (dump_wrap)
- extra_len = FENCED_DUMP_SIZE;
- else
- extra_len = dump_point;
-
- init_header(&h, FENCED_CMD_DUMP_DEBUG, 0, extra_len);
- do_write(f, &h, sizeof(h));
-
- if (dump_wrap) {
- len = FENCED_DUMP_SIZE - dump_point;
- do_write(f, dump_buf + dump_point, len);
- len = dump_point;
- } else
- len = dump_point;
-
- /* NUL terminate the debug string */
- dump_buf[dump_point] = '\0';
-
- do_write(f, dump_buf, len);
-}
-
-static void query_node_info(int f, int data_nodeid)
-{
- struct fd *fd;
- struct fenced_node node;
- int nodeid, rv;
-
- fd = find_fd(default_name);
- if (!fd) {
- rv = -ENOENT;
- goto out;
- }
-
- if (data_nodeid == FENCED_NODEID_US)
- nodeid = our_nodeid;
- else
- nodeid = data_nodeid;
-
- if (group_mode == GROUP_LIBGROUP)
- rv = set_node_info_group(fd, nodeid, &node);
- else
- rv = set_node_info(fd, nodeid, &node);
- out:
- do_reply(f, FENCED_CMD_NODE_INFO, rv, (char *)&node, sizeof(node));
-}
-
-static void query_domain_info(int f)
-{
- struct fd *fd;
- struct fenced_domain domain;
- int rv;
-
- fd = find_fd(default_name);
- if (!fd) {
- rv = -ENOENT;
- goto out;
- }
-
- memset(&domain, 0, sizeof(domain));
- domain.group_mode = group_mode;
-
- if (group_mode == GROUP_LIBGROUP)
- rv = set_domain_info_group(fd, &domain);
- else
- rv = set_domain_info(fd, &domain);
- out:
- do_reply(f, FENCED_CMD_DOMAIN_INFO, rv, (char *)&domain, sizeof(domain));
-}
-
-static void query_domain_nodes(int f, int option, int max)
-{
- struct fd *fd;
- int node_count = 0;
- struct fenced_node *nodes = NULL;
- int rv, result;
-
- fd = find_fd(default_name);
- if (!fd) {
- result = -ENOENT;
- node_count = 0;
- goto out;
- }
-
- if (group_mode == GROUP_LIBGROUP)
- rv = set_domain_nodes_group(fd, option, &node_count, &nodes);
- else
- rv = set_domain_nodes(fd, option, &node_count, &nodes);
-
- if (rv < 0) {
- result = rv;
- node_count = 0;
- goto out;
- }
-
- /* node_count is the number of structs copied/returned; the caller's
- max may be less than that, in which case we copy as many as they
- asked for and return -E2BIG */
-
- if (node_count > max) {
- result = -E2BIG;
- node_count = max;
- } else {
- result = node_count;
- }
- out:
- do_reply(f, FENCED_CMD_DOMAIN_NODES, result,
- (char *)nodes, node_count * sizeof(struct fenced_node));
-
- if (nodes)
- free(nodes);
-}
-
-static void process_connection(int ci)
-{
- struct fenced_header h;
- char *extra = NULL;
- int rv, extra_len;
-
-
- rv = do_read(client[ci].fd, &h, sizeof(h));
- if (rv < 0) {
- log_debug("connection %d read error %d", ci, rv);
- goto out;
- }
-
- if (h.magic != FENCED_MAGIC) {
- log_debug("connection %d magic error %x", ci, h.magic);
- goto out;
- }
-
- if ((h.version & 0xFFFF0000) != (FENCED_VERSION & 0xFFFF0000)) {
- log_debug("connection %d version error %x", ci, h.version);
- goto out;
- }
-
- if (h.len > sizeof(h)) {
- extra_len = h.len - sizeof(h);
- extra = malloc(extra_len);
- if (!extra) {
- log_error("process_connection no mem %d", extra_len);
- goto out;
- }
- memset(extra, 0, extra_len);
-
- rv = do_read(client[ci].fd, extra, extra_len);
- if (rv < 0) {
- log_debug("connection %d extra read error %d", ci, rv);
- goto out;
- }
- }
-
- switch (h.command) {
- case FENCED_CMD_JOIN:
- do_join(default_name);
- break;
- case FENCED_CMD_LEAVE:
- do_leave(default_name);
- break;
- case FENCED_CMD_EXTERNAL:
- do_external(default_name, extra, extra_len);
- break;
- case FENCED_CMD_DUMP_DEBUG:
- case FENCED_CMD_NODE_INFO:
- case FENCED_CMD_DOMAIN_INFO:
- case FENCED_CMD_DOMAIN_NODES:
- log_error("process_connection query on wrong socket");
- break;
- default:
- log_error("process_connection %d unknown command %d",
- ci, h.command);
- }
- out:
- if (extra)
- free(extra);
- client_dead(ci);
-}
-
-static void process_listener(int ci)
-{
- int fd, i;
-
- fd = accept(client[ci].fd, NULL, NULL);
- if (fd < 0) {
- log_error("process_listener: accept error %d %d", fd, errno);
- return;
- }
-
- i = client_add(fd, process_connection, NULL);
-
- log_debug("client connection %d fd %d", i, fd);
-}
-
-static int setup_listener(const char *sock_path)
-{
- struct sockaddr_un addr;
- socklen_t addrlen;
- int rv, s;
-
- /* we listen for new client connections on socket s */
-
- s = socket(AF_LOCAL, SOCK_STREAM, 0);
- if (s < 0) {
- log_error("socket error %d %d", s, errno);
- return s;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- strcpy(&addr.sun_path[1], sock_path);
- addrlen = sizeof(sa_family_t) + strlen(addr.sun_path+1) + 1;
-
- rv = bind(s, (struct sockaddr *) &addr, addrlen);
- if (rv < 0) {
- log_error("bind error %d %d", rv, errno);
- close(s);
- return rv;
- }
-
- rv = listen(s, 5);
- if (rv < 0) {
- log_error("listen error %d %d", rv, errno);
- close(s);
- return rv;
- }
- return s;
-}
-
-void query_lock(void)
-{
- pthread_mutex_lock(&query_mutex);
-}
-
-void query_unlock(void)
-{
- pthread_mutex_unlock(&query_mutex);
-}
-
-/* This is a thread, so we have to be careful, don't call log_ functions.
- We need a thread to process queries because the main thread will block
- for long periods when running fence agents. */
-
-static void *process_queries(void *arg)
-{
- struct fenced_header h;
- int f, rv, s;
-
- rv = setup_listener(FENCED_QUERY_SOCK_PATH);
- if (rv < 0)
- return NULL;
-
- s = rv;
-
- for (;;) {
- f = accept(s, NULL, NULL);
- if (f < 0)
- return NULL;
-
- rv = do_read(f, &h, sizeof(h));
- if (rv < 0) {
- goto out;
- }
-
- if (h.magic != FENCED_MAGIC) {
- goto out;
- }
-
- if ((h.version & 0xFFFF0000) != (FENCED_VERSION & 0xFFFF0000)) {
- goto out;
- }
-
- query_lock();
-
- switch (h.command) {
- case FENCED_CMD_DUMP_DEBUG:
- query_dump_debug(f);
- break;
- case FENCED_CMD_NODE_INFO:
- query_node_info(f, h.data);
- break;
- case FENCED_CMD_DOMAIN_INFO:
- query_domain_info(f);
- break;
- case FENCED_CMD_DOMAIN_NODES:
- query_domain_nodes(f, h.option, h.data);
- break;
- default:
- break;
- }
- query_unlock();
-
- out:
- close(f);
- }
-}
-
-static int setup_queries(void)
-{
- int rv;
-
- pthread_mutex_init(&query_mutex, NULL);
-
- rv = pthread_create(&query_thread, NULL, process_queries, NULL);
- if (rv < 0) {
- log_error("can't create query thread");
- return rv;
- }
- return 0;
-}
-
-struct controlled_entry {
- struct list_head list;
- char path[PATH_MAX+1];
-};
-
-static void register_controlled_dir(const char *path)
-{
- struct controlled_entry *ce;
-
- ce = malloc(sizeof(struct controlled_entry));
- if (!ce)
- return;
- memset(ce, 0, sizeof(struct controlled_entry));
- strncpy(ce->path, path, PATH_MAX);
- list_add(&ce->list, &controlled_entries);
-}
-
-static int ignore_nolock(char *sysfs_dir, char *table)
-{
- char path[PATH_MAX];
- char buf[32];
- int fd, rv;
-
- memset(path, 0, PATH_MAX);
-
- snprintf(path, PATH_MAX, "%s/%s/lock_module/proto_name",
- sysfs_dir, table);
-
- /* lock_nolock doesn't create the "lock_module" dir at all,
- so we'll fail to open this */
-
- fd = open(path, O_RDONLY);
- if (fd < 0)
- return 1;
-
- memset(buf, 0, sizeof(buf));
-
- rv = read(fd, buf, sizeof(buf));
- close(fd);
- if (rv < 0)
- return 1;
-
- if (!strncmp(buf, "lock_nolock", 11))
- return 1;
-
- return 0;
-}
-
-static int check_controlled_dir(char *path)
-{
- DIR *d;
- struct dirent *de;
- int count = 0;
-
- d = opendir(path);
- if (!d)
- return 0;
-
- while ((de = readdir(d))) {
- if (de->d_name[0] == '.')
- continue;
-
- if (strstr(path, "fs/gfs") && ignore_nolock(path, de->d_name))
- continue;
-
- log_error("found uncontrolled entry %s/%s", path, de->d_name);
- count++;
- }
- closedir(d);
-
- return count;
-}
-
-/* Joining the "fenced:daemon" cpg (in setup_cpg_daemon()) tells fenced on other
- nodes that we are in a "clean state", and don't need fencing. So, if
- we're a pending fence victim on another node, they'll skip fencing us
- once we start fenced and join the "daemon" cpg (it's not the fence domain
- cpg which we join when fence_tool join is run). This "daemon" cpg is just
- to notify others that we have no uncontrolled gfs/dlm objects.
- (Conceptually, we could use the fence domain cpg for this purpose instead,
- but that would require processing domain membership changes during
- fence_victims(), which would be a major change in the way the daemon works.)
-
- So, if we (the local node) are *not* in a clean state, we don't join the
- daemon cpg and we exit; we still need to be fenced. If we are starting
- up and find that instances of gfs/dlm in the kernel have been previously
- abandoned, that's an unclean, unreset state, and we still need fencing. */
-
-static int check_uncontrolled_entries(void)
-{
- struct controlled_entry *ce;
- int count = 0;
-
- list_for_each_entry(ce, &controlled_entries, list) {
- if (strncmp(ce->path, "-", 1))
- goto skip_default;
- }
-
- /* the default dirs to check */
- register_controlled_dir("/sys/kernel/dlm");
- register_controlled_dir("/sys/fs/gfs2");
- register_controlled_dir("/sys/fs/gfs");
-
- skip_default:
- list_for_each_entry(ce, &controlled_entries, list)
- count += check_controlled_dir(ce->path);
-
- if (count)
- return -1;
- return 0;
-}
-
-void cluster_dead(int ci)
-{
- if (!cluster_down)
- log_error("cluster is down, exiting");
- daemon_quit = 1;
- cluster_down = 1;
-}
-
-static void loop(void)
-{
- int rv, i;
- int cluster_fd_pos;
- void (*workfn) (int ci);
- void (*deadfn) (int ci);
-
- rv = setup_queries();
- if (rv < 0)
- goto out;
-
- rv = setup_listener(FENCED_SOCK_PATH);
- if (rv < 0)
- goto out;
- client_add(rv, process_listener, NULL);
-
- rv = cluster_fd_pos = setup_cluster();
- if (rv < 0)
- goto out;
- client_add(rv, process_cluster, cluster_dead);
-
- rv = setup_ccs();
- if (rv < 0)
- goto out;
-
- setup_logging();
-
- rv = check_uncontrolled_entries();
- if (rv < 0)
- goto out;
-
- rv = setup_cpg_daemon();
- if (rv < 0)
- goto out;
- client_add(rv, process_cpg_daemon, cluster_dead);
-
- group_mode = GROUP_LIBCPG;
-
- if (cfgd_groupd_compat) {
- rv = setup_groupd();
- if (rv < 0)
- goto out;
- client_add(rv, process_groupd, cluster_dead);
-
- switch (cfgd_groupd_compat) {
- case 1:
- group_mode = GROUP_LIBGROUP;
- rv = 0;
- break;
- case 2:
- rv = set_group_mode();
- break;
- default:
- log_error("inval groupd_compat %d", cfgd_groupd_compat);
- rv = -1;
- break;
- }
- if (rv < 0)
- goto out;
- }
- log_debug("group_mode %d compat %d", group_mode, cfgd_groupd_compat);
-
- if (group_mode == GROUP_LIBCPG) {
- rv = set_protocol();
- if (rv < 0)
- goto out;
- }
-
- for (;;) {
- /* We need to re-get the cluster FD each time */
- pollfd[cluster_fd_pos].fd = get_member_fd();
- rv = poll(pollfd, client_maxi + 1, -1);
- if (rv == -1 && errno == EINTR) {
- if (daemon_quit && list_empty(&domains))
- goto out;
- daemon_quit = 0;
- continue;
- }
- if (rv < 0) {
- log_error("poll errno %d", errno);
- goto out;
- }
-
- query_lock();
-
- for (i = 0; i <= client_maxi; i++) {
- if (client[i].fd < 0)
- continue;
- if (pollfd[i].revents & POLLIN) {
- workfn = client[i].workfn;
- workfn(i);
- }
- if (pollfd[i].revents & (POLLERR | POLLHUP | POLLNVAL)) {
- deadfn = client[i].deadfn;
- deadfn(i);
- }
- }
- query_unlock();
-
- if (daemon_quit)
- break;
- }
- out:
- if (cfgd_groupd_compat)
- close_groupd();
- close_cpg_daemon();
- close_logging();
- close_ccs();
- close_cluster();
-
- if (!list_empty(&domains))
- log_error("domain abandoned");
-}
-
-static void lockfile(void)
-{
- int fd, error;
- struct flock lock;
- char buf[33];
-
- memset(buf, 0, 33);
-
- fd = open(LOCKFILE_NAME, O_CREAT|O_WRONLY,
- S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
- if (fd < 0) {
- 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, "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 print_usage(void)
-{
- printf("Usage:\n");
- printf("\n");
- printf("fenced [options]\n");
- printf("\n");
- printf("Options:\n");
- printf("\n");
- printf(" -D Enable debugging to stderr and don't fork\n");
- printf(" -L Enable debugging to log file\n");
- printf(" -g <num> groupd compatibility mode, 0 off, 1 on, 2 detect (default %d)\n", DEFAULT_GROUPD_COMPAT);
- printf(" 0: use libcpg, no backward compat, best performance\n");
- printf(" 1: use libgroup for compat with cluster2/rhel5\n");
- printf(" 2: use groupd to detect old, or mode 1, nodes that\n"
- " require compat, use libcpg if none found\n");
- printf(" -r <path> Register a directory that needs to be empty for\n");
- printf(" the daemon to start. \"-\" to skip default directories\n");
- printf(" /sys/fs/gfs, /sys/fs/gfs2, /sys/kernel/dlm\n");
- printf(" -c All nodes are in a clean state to start; do no startup fencing\n");
- printf(" -s Skip startup fencing of nodes with no defined fence methods\n");
- printf(" -j <secs> Post-join fencing delay (default %d)\n", DEFAULT_POST_JOIN_DELAY);
- printf(" -f <secs> Post-fail fencing delay (default %d)\n", DEFAULT_POST_FAIL_DELAY);
- printf(" -R <secs> Override time (default %d)\n", DEFAULT_OVERRIDE_TIME);
- printf(" -q Disable dbus signals\n");
- printf(" -O <path> Override path (default %s)\n", DEFAULT_OVERRIDE_PATH);
- printf(" -h Print this help, then exit\n");
- printf(" -V Print program version information, then exit\n");
- printf("\n");
- printf("Command line values override those in " DEFAULT_CONFIG_DIR "/" DEFAULT_CONFIG_FILE ".\n");
- printf("For an unbounded delay use <secs> value of -1.\n");
- printf("\n");
-}
-
-#define OPTION_STRING "Lg:cj:f:Dn:O:hVSse:r:q"
-
-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':
- daemon_debug_opt = 1;
- break;
-
- case 'L':
- optd_debug_logfile = 1;
- cfgd_debug_logfile = 1;
- break;
-
- case 'g':
- optd_groupd_compat = 1;
- cfgd_groupd_compat = atoi(optarg);
- break;
-
- case 'c':
- optd_clean_start = 1;
- cfgd_clean_start = 1;
- break;
-
- case 's':
- optd_skip_undefined = 1;
- cfgd_skip_undefined = 1;
- break;
-
- case 'j':
- optd_post_join_delay = 1;
- cfgd_post_join_delay = atoi(optarg);
- break;
-
- case 'f':
- optd_post_fail_delay = 1;
- cfgd_post_fail_delay = atoi(optarg);
- break;
-
- case 'R':
- optd_override_time = 1;
- cfgd_override_time = atoi(optarg);
- if (cfgd_override_time < 3)
- cfgd_override_time = 3;
- break;
-
- case 'O':
- optd_override_path = 1;
- cfgd_override_path = strdup(optarg);
- break;
-
- case 'q':
- optd_disable_dbus = 1;
- cfgd_disable_dbus = 1;
- break;
-
- case 'r':
- register_controlled_dir(optarg);
- break;
-
- case 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case 'V':
- printf("fenced %s (built %s %s)\n", RELEASE_VERSION,
- __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- break;
-
- case ':':
- case '?':
- fprintf(stderr, "Please use '-h' for usage.\n");
- exit(EXIT_FAILURE);
- break;
-
- case EOF:
- cont = 0;
- break;
-
- default:
- fprintf(stderr, "unknown option: %c", optchar);
- exit(EXIT_FAILURE);
- };
- }
-
- if (getenv("FENCED_DEBUG")) {
- optd_debug_logfile = 1;
- cfgd_debug_logfile = 1;
- }
-}
-
-int main(int argc, char **argv)
-{
- INIT_LIST_HEAD(&domains);
- INIT_LIST_HEAD(&controlled_entries);
-
- strcpy(default_name, "default");
-
- read_arguments(argc, argv);
-
- if (!daemon_debug_opt) {
- if (daemon(0, 0) < 0) {
- perror("main: cannot fork");
- exit(EXIT_FAILURE);
- }
- }
- lockfile();
- init_logging();
- log_level(LOG_INFO, "fenced %s started", RELEASE_VERSION);
- signal(SIGTERM, sigterm_handler);
-
- if (!cfgd_disable_dbus) {
- fd_dbus_init();
- }
-
- loop();
-
- fd_dbus_exit();
- unlink(LOCKFILE_NAME);
- return 0;
-}
-
-void daemon_dump_save(void)
-{
- int len, i;
-
- len = strlen(daemon_debug_buf);
-
- for (i = 0; i < len; i++) {
- dump_buf[dump_point++] = daemon_debug_buf[i];
-
- if (dump_point == FENCED_DUMP_SIZE) {
- dump_point = 0;
- dump_wrap = 1;
- }
- }
-}
-
-int daemon_debug_opt;
-int daemon_quit;
-int cluster_down;
-struct list_head domains;
-int cluster_quorate;
-int cluster_quorate_from_last_update;
-uint32_t cluster_ringid_seq;
-uint64_t quorate_time;
-int our_nodeid;
-char our_name[MAX_NODENAME_LEN+1];
-char daemon_debug_buf[256];
-char dump_buf[FENCED_DUMP_SIZE];
-int dump_point;
-int dump_wrap;
-int group_mode;
-int two_node_mode;
-
diff --git a/fence/fenced/member_cman.c b/fence/fenced/member_cman.c
deleted file mode 100644
index 859bbf0..0000000
--- a/fence/fenced/member_cman.c
+++ /dev/null
@@ -1,416 +0,0 @@
-#include "fd.h"
-#include "config.h"
-#include <arpa/inet.h>
-#include <libcman.h>
-
-#define BUFLEN MAX_NODENAME_LEN+1
-
-static cman_handle_t ch;
-static cman_handle_t ch_admin;
-static cman_node_t old_nodes[MAX_NODES];
-static int old_node_count;
-static cman_node_t cman_nodes[MAX_NODES];
-static int cman_node_count;
-
-void set_cman_dirty(void)
-{
- int rv;
-
- rv = cman_set_dirty(ch_admin);
- if (rv)
- log_error("cman_set_dirty error %d", rv);
-}
-
-void kick_node_from_cluster(int nodeid)
-{
- if (!nodeid) {
- log_error("telling cman to shut down cluster locally");
- cman_shutdown(ch_admin, CMAN_SHUTDOWN_ANYWAY);
- } else {
-
- /* in a two_node cluster where both nodes maintain quorum
- * by themselves during a partition+merge, both will kick
- * the other, which can leave both dead and unfenced.
- * this delay should help */
-
- if (two_node_mode && our_nodeid > nodeid) {
- log_debug("kick_node_from_cluster %d delay", nodeid);
- sleep(5);
- }
-
- log_error("telling cman to remove nodeid %d from cluster",
- nodeid);
- cman_kill_node(ch_admin, nodeid);
- }
-}
-
-static cman_node_t *get_node(cman_node_t *node_list, int count, int nodeid)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- if (node_list[i].cn_nodeid == nodeid)
- return &node_list[i];
- }
- return NULL;
-}
-
-static int is_member(cman_node_t *node_list, int count, int nodeid)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- if (node_list[i].cn_nodeid == nodeid)
- return node_list[i].cn_member;
- }
- return 0;
-}
-
-static int is_old_member(int nodeid)
-{
- return is_member(old_nodes, old_node_count, nodeid);
-}
-
-static int is_cluster_member(int nodeid)
-{
- return is_member(cman_nodes, cman_node_count, nodeid);
-}
-
-static int name_equal(char *name1, char *name2)
-{
- char name3[BUFLEN], name4[BUFLEN];
- char addr1[INET6_ADDRSTRLEN];
- int i, len1, len2;
-
- len1 = strlen(name1);
- len2 = strlen(name2);
-
- if (len1 == len2 && !strncmp(name1, name2, len1))
- return 1;
-
- /*
- * If the names are IP addresses then don't compare
- * what is in front of the dots.
- */
- if (inet_pton(AF_INET, name1, addr1) == 0)
- return 0;
-
- if (inet_pton(AF_INET6, name1, addr1) == 0)
- return 0;
-
- memset(name3, 0, BUFLEN);
- memset(name4, 0, BUFLEN);
-
- for (i = 0; i < BUFLEN && i < len1; i++) {
- if (name1[i] != '.')
- name3[i] = name1[i];
- else
- break;
- }
-
- for (i = 0; i < BUFLEN && i < len2; i++) {
- if (name2[i] != '.')
- name4[i] = name2[i];
- else
- break;
- }
-
- len1 = strlen(name3);
- len2 = strlen(name4);
-
- if (len1 == len2 && !strncmp(name3, name4, len1))
- return 1;
-
- return 0;
-}
-
-static cman_node_t *find_cman_node_name(char *name)
-{
- int i;
-
- for (i = 0; i < cman_node_count; i++) {
- if (name_equal(cman_nodes[i].cn_name, name))
- return &cman_nodes[i];
- }
- return NULL;
-}
-
-static cman_node_t *find_cman_node(int nodeid)
-{
- int i;
-
- for (i = 0; i < cman_node_count; i++) {
- if (cman_nodes[i].cn_nodeid == nodeid)
- return &cman_nodes[i];
- }
- return NULL;
-}
-
-char *nodeid_to_name(int nodeid)
-{
- cman_node_t *cn;
-
- cn = find_cman_node(nodeid);
- if (cn)
- return cn->cn_name;
-
- return NULL;
-}
-
-int name_to_nodeid(char *name)
-{
- cman_node_t *cn;
-
- cn = find_cman_node_name(name);
- if (cn)
- return cn->cn_nodeid;
-
- return -1;
-}
-
-static void update_cluster(void)
-{
- cman_cluster_t info;
- cman_node_t *old;
- int quorate = cluster_quorate;
- int removed = 0, added = 0;
- int i, rv;
-
- rv = cman_get_cluster(ch, &info);
- if (rv < 0) {
- log_error("cman_get_cluster error %d %d", rv, errno);
- return;
- }
- cluster_ringid_seq = info.ci_generation;
-
- cluster_quorate = cman_is_quorate(ch);
-
- if (!quorate && cluster_quorate)
- quorate_time = time(NULL);
-
- old_node_count = cman_node_count;
- memcpy(&old_nodes, &cman_nodes, sizeof(old_nodes));
-
- cman_node_count = 0;
- memset(&cman_nodes, 0, sizeof(cman_nodes));
- rv = cman_get_nodes(ch, MAX_NODES, &cman_node_count, cman_nodes);
- if (rv < 0) {
- log_error("cman_get_nodes error %d %d", rv, errno);
- return;
- }
-
- for (i = 0; i < old_node_count; i++) {
- if (old_nodes[i].cn_member &&
- !is_cluster_member(old_nodes[i].cn_nodeid)) {
-
- log_debug("cluster node %d removed seq %u",
- old_nodes[i].cn_nodeid, cluster_ringid_seq);
-
- node_history_cluster_remove(old_nodes[i].cn_nodeid);
- removed++;
- }
- }
-
- for (i = 0; i < cman_node_count; i++) {
- if (cman_nodes[i].cn_member &&
- !is_old_member(cman_nodes[i].cn_nodeid)) {
-
- log_debug("cluster node %d added seq %u",
- cman_nodes[i].cn_nodeid, cluster_ringid_seq);
-
- node_history_cluster_add(cman_nodes[i].cn_nodeid);
- added++;
- } else {
- /* look for any nodes that were members of both
- * old and new but have a new incarnation number
- * from old to new, indicating they left and rejoined
- * in between */
-
- old = get_node(old_nodes, old_node_count, cman_nodes[i].cn_nodeid);
-
- if (!old)
- continue;
- if (cman_nodes[i].cn_incarnation == old->cn_incarnation)
- continue;
-
- log_debug("cluster node %d removed and added seq %u "
- "old %u new %u",
- cman_nodes[i].cn_nodeid, cluster_ringid_seq,
- old->cn_incarnation,
- cman_nodes[i].cn_incarnation);
-
- node_history_cluster_remove(cman_nodes[i].cn_nodeid);
- removed++;
-
- node_history_cluster_add(cman_nodes[i].cn_nodeid);
- added++;
- }
- }
-
- if (removed) {
- cluster_quorate_from_last_update = 0;
- } else if (added) {
- if (!quorate && cluster_quorate)
- cluster_quorate_from_last_update = 1;
- else
- cluster_quorate_from_last_update = 0;
- }
-}
-
-/* Note: in fence delay loop we aren't processing callbacks so won't
- have done an update_cluster() in response to a cman callback */
-
-int is_cluster_member_reread(int nodeid)
-{
- int rv;
-
- update_cluster();
-
- rv = is_cluster_member(nodeid);
- if (rv)
- return 1;
-
- /* log_debug("cman_member %d not member", nodeid); */
- return 0;
-}
-
-static void cman_callback(cman_handle_t h, void *private, int reason, int arg)
-{
- int quorate = cluster_quorate;
-
- switch (reason) {
- case CMAN_REASON_TRY_SHUTDOWN:
- if (list_empty(&domains))
- cman_replyto_shutdown(ch, 1);
- else {
- log_debug("no to cman shutdown");
- cman_replyto_shutdown(ch, 0);
- }
- break;
- case CMAN_REASON_STATECHANGE:
- update_cluster();
-
- /* domain may have been waiting for quorum */
- if (!quorate && cluster_quorate && (group_mode == GROUP_LIBCPG))
- process_fd_changes();
- break;
-
- case CMAN_REASON_CONFIG_UPDATE:
- setup_logging();
- reread_ccs();
- break;
- }
-}
-
-void process_cluster(int ci)
-{
- int rv;
-
- rv = cman_dispatch(ch, CMAN_DISPATCH_ALL);
- if (rv == -1 && errno == EHOSTDOWN)
- cluster_dead(0);
-}
-
-int setup_cluster(void)
-{
- cman_node_t node;
- int rv, fd;
- int init = 0, active = 0;
-
- retry_init:
- ch_admin = cman_admin_init(NULL);
- if (!ch_admin) {
- if (init++ < 2) {
- sleep(1);
- goto retry_init;
- }
- log_error("cman_admin_init error %d", errno);
- return -ENOTCONN;
- }
-
- ch = cman_init(NULL);
- if (!ch) {
- log_error("cman_init error %d", errno);
- cman_finish(ch_admin);
- return -ENOTCONN;
- }
-
- retry_active:
- rv = cman_is_active(ch);
- if (!rv) {
- if (active++ < 2) {
- sleep(1);
- goto retry_active;
- }
- log_error("cman_is_active error %d", errno);
- cman_finish(ch);
- cman_finish(ch_admin);
- return -ENOTCONN;
- }
-
- rv = cman_start_notification(ch, cman_callback);
- if (rv < 0) {
- log_error("cman_start_notification error %d %d", rv, errno);
- cman_finish(ch);
- cman_finish(ch_admin);
- return rv;
- }
-
- update_cluster();
-
- fd = cman_get_fd(ch);
-
- /* FIXME: wait here for us to be a member of the cluster */
- memset(&node, 0, sizeof(node));
- rv = cman_get_node(ch, CMAN_NODEID_US, &node);
- if (rv < 0) {
- log_error("cman_get_node us error %d %d", rv, errno);
- cman_finish(ch);
- cman_finish(ch_admin);
- fd = rv;
- goto out;
- }
-
- memset(our_name, 0, sizeof(our_name));
- strncpy(our_name, node.cn_name, CMAN_MAX_NODENAME_LEN);
- our_nodeid = node.cn_nodeid;
-
- log_debug("our_nodeid %d our_name %s", our_nodeid, our_name);
- out:
- return fd;
-}
-
-void close_cluster(void)
-{
- cman_finish(ch);
- cman_finish(ch_admin);
-}
-
-int get_member_fd()
-{
- return cman_get_fd(ch);
-}
-
-struct node *get_new_node(struct fd *fd, int nodeid)
-{
- cman_node_t cn;
- struct node *node;
- int rv;
-
- node = malloc(sizeof(*node));
- if (!node)
- return NULL;
- memset(node, 0, sizeof(struct node));
-
- node->nodeid = nodeid;
-
- memset(&cn, 0, sizeof(cn));
- rv = cman_get_node(ch, nodeid, &cn);
- if (rv < 0)
- log_debug("get_new_node %d no cman node %d", nodeid, rv);
- else
- strncpy(node->name, cn.cn_name, MAX_NODENAME_LEN);
-
- return node;
-}
-
diff --git a/fence/fenced/recover.c b/fence/fenced/recover.c
deleted file mode 100644
index 0b5e2b2..0000000
--- a/fence/fenced/recover.c
+++ /dev/null
@@ -1,477 +0,0 @@
-#include "fd.h"
-#include "config.h"
-
-void free_node_list(struct list_head *head)
-{
- struct node *node;
-
- while (!list_empty(head)) {
- node = list_entry(head->next, struct node, list);
- list_del(&node->list);
- free(node);
- }
-}
-
-void add_complete_node(struct fd *fd, int nodeid)
-{
- struct node *node;
-
- node = get_new_node(fd, nodeid);
- list_add(&node->list, &fd->complete);
-
- if (group_mode == GROUP_LIBGROUP)
- return;
-
- node_history_init(fd, nodeid);
-}
-
-int list_count(struct list_head *head)
-{
- struct list_head *tmp;
- int count = 0;
-
- list_for_each(tmp, head)
- count++;
- return count;
-}
-
-int is_victim(struct fd *fd, int nodeid)
-{
- struct node *node;
-
- list_for_each_entry(node, &fd->victims, list) {
- if (node->nodeid == nodeid)
- return 1;
- }
- return 0;
-}
-
-static void victim_done(struct fd *fd, int victim, int how)
-{
- if (group_mode == GROUP_LIBGROUP)
- return;
-
- node_history_fence(fd, victim, our_nodeid, how, time(NULL));
- send_victim_done(fd, victim);
-}
-
-/* This routine should probe other indicators to check if victims
- can be reduced. Right now we just check if the victim has rejoined the
- cluster. */
-
-static int reduce_victims(struct fd *fd)
-{
- struct node *node, *safe;
- int num_victims;
-
- num_victims = list_count(&fd->victims);
-
- list_for_each_entry_safe(node, safe, &fd->victims, list) {
- if (is_cluster_member_reread(node->nodeid) &&
- is_clean_daemon_member(node->nodeid)) {
- log_debug("reduce victim %s", node->name);
- victim_done(fd, node->nodeid, VIC_DONE_MEMBER);
- list_del(&node->list);
- free(node);
- num_victims--;
- }
- }
-
- return num_victims;
-}
-
-static inline void close_override(int *fd, const char *path)
-{
- unlink(path);
- if (fd) {
- if (*fd >= 0)
- close(*fd);
- *fd = -1;
- }
-}
-
-static int open_override(const char *path)
-{
- int ret;
- mode_t om;
-
- om = umask(077);
- ret = mkfifo(path, (S_IRUSR | S_IWUSR));
- umask(om);
-
- if (ret < 0)
- return -1;
- return open(path, O_RDONLY | O_NONBLOCK);
-}
-
-static int check_override(int ofd, char *nodename, int timeout)
-{
- char buf[128];
- fd_set rfds;
- struct timeval tv = {0, 0};
- int ret, x, rv;
-
- query_unlock();
-
- if (ofd < 0 || !nodename || !strlen(nodename)) {
- sleep(timeout);
- rv = 0;
- goto out;
- }
-
- FD_ZERO(&rfds);
- FD_SET(ofd, &rfds);
- tv.tv_usec = 0;
- tv.tv_sec = timeout;
-
- ret = select(ofd + 1, &rfds, NULL, NULL, &tv);
- if (ret < 0) {
- log_debug("check_override select: %s", strerror(errno));
- rv = -1;
- goto out;
- }
-
- if (ret == 0) {
- rv = 0;
- goto out;
- }
-
- memset(buf, 0, sizeof(buf));
- ret = read(ofd, buf, sizeof(buf) - 1);
- if (ret < 0) {
- log_debug("check_override read: %s", strerror(errno));
- rv = -1;
- goto out;
- }
-
- /* chop off control characters */
- for (x = 0; x < ret; x++) {
- if (buf[x] < 0x20) {
- buf[x] = 0;
- break;
- }
- }
-
- if (!strcasecmp(nodename, buf)) {
- /* Case insensitive, but not as nice as, say, name_equal
- in the other file... */
- rv = 1;
- goto out;
- }
-
- rv = 0;
- out:
- query_lock();
- return rv;
-}
-
-static int fence_check_pid(void)
-{
- char buf[16];
- int fd, rv, pid = 0;
-
- fd = open(DEFAULT_FENCE_CHECK_PID_PATH, O_RDONLY);
- if (fd < 0)
- return 0;
-
- rv = flock(fd, LOCK_EX | LOCK_NB);
- if (!rv) {
- flock(fd, LOCK_UN);
- goto out;
- }
-
- /* fence_check script is running, return its pid */
-
- memset(buf, 0, sizeof(buf));
-
- rv = read(fd, buf, sizeof(buf));
- if (rv <= 0)
- goto out;
-
- pid = atoi(buf);
- if (pid <= 0)
- pid = 0;
- out:
- close(fd);
- return pid;
-}
-
-/* If there are victims after a node has joined, it's a good indication that
- they may be joining the cluster shortly. If we delay a bit they might
- become members and we can avoid fencing them. This is only really an issue
- when the fencing method reboots the victims. Otherwise, the nodes should
- unfence themselves when they start up. */
-
-void delay_fencing(struct fd *fd, int node_join)
-{
- struct timeval first, last, start, now;
- int victim_count, last_count = 0, delay = 0, pid;
- struct node *node;
- const char *delay_type;
-
- if (list_empty(&fd->victims))
- return;
-
- gettimeofday(&first, NULL);
- gettimeofday(&start, NULL);
-
- if (cfgd_fence_check_delay) {
- for (;;) {
- pid = fence_check_pid();
- if (!pid)
- break;
-
- gettimeofday(&now, NULL);
- if (now.tv_sec - start.tv_sec >= cfgd_fence_check_delay)
- break;
-
- log_debug("delay fencing for fence_check_pid %d", pid);
- sleep(1);
- }
-
- if (pid) {
- kill(pid, SIGTERM);
- log_error("kill fence_check_pid %d delay %d",
- pid, cfgd_fence_check_delay);
- }
- }
-
- if (node_join || cluster_quorate_from_last_update) {
- delay = cfgd_post_join_delay;
- delay_type = "post_join_delay";
- } else {
- delay = cfgd_post_fail_delay;
- delay_type = "post_fail_delay";
- }
-
- log_debug("delay %s %d quorate_from_last_update %d",
- delay_type, delay, cluster_quorate_from_last_update);
-
- if (delay == 0)
- goto out;
-
- for (;;) {
- query_unlock();
- sleep(1);
- query_lock();
-
- victim_count = reduce_victims(fd);
-
- if (victim_count == 0)
- break;
-
- if (victim_count < last_count) {
- gettimeofday(&start, NULL);
- if (delay > 0 && cfgd_post_join_delay > delay) {
- delay = cfgd_post_join_delay;
- delay_type = "post_join_delay (modified)";
- }
- }
-
- last_count = victim_count;
-
- /* negative delay means wait forever */
- if (delay == -1)
- continue;
-
- gettimeofday(&now, NULL);
- if (now.tv_sec - start.tv_sec >= delay)
- break;
- }
-
- gettimeofday(&last, NULL);
-
- log_debug("delay of %ds leaves %d victims",
- (int) (last.tv_sec - first.tv_sec), victim_count);
- out:
- list_for_each_entry(node, &fd->victims, list) {
- log_debug("%s not a cluster member after %d sec %s",
- node->name, delay, delay_type);
- }
-}
-
-void defer_fencing(struct fd *fd)
-{
- char *master_name;
-
- if (list_empty(&fd->victims))
- return;
-
- master_name = nodeid_to_name(fd->master);
-
- log_level(LOG_INFO, "fencing deferred to %s",
- master_name ? master_name : "unknown");
-}
-
-static const char *fe_str(int r)
-{
- switch (r) {
- case FE_AGENT_SUCCESS:
- return "success";
- case FE_AGENT_ERROR:
- return "error from agent";
- case FE_AGENT_FORK:
- return "error from fork";
- case FE_NO_CONFIG:
- return "error from ccs";
- case FE_NO_METHOD:
- return "error no method";
- case FE_NO_DEVICE:
- return "error no device";
- case FE_READ_AGENT:
- return "error config agent";
- case FE_READ_ARGS:
- return "error config args";
- case FE_READ_METHOD:
- return "error config method";
- case FE_READ_DEVICE:
- return "error config device";
- default:
- return "error unknown";
- }
-}
-
-#define FL_SIZE 32
-static struct fence_log flog[FL_SIZE];
-static struct fence_log prev_flog[FL_SIZE];
-
-void fence_victims(struct fd *fd)
-{
- struct node *node;
- int error, i, ll, flog_count, prev_flog_count;
- int override = -1;
- int cluster_member, cpg_member, ext;
- unsigned int limit, retries;
-
- list_for_each_entry(node, &fd->victims, list) {
- if (node->local_victim_done) {
- /* local_victim_done means we've successfully fenced
- this node and will remove it from victims list
- upon receipt of the victim_done message we sent */
-
- /* I don't believe fence_victims() can come across
- a node with local_victim_done set. That would
- mean: pass 1 through fence_victims() fences node A,
- send victim_done(A), return, process confchgs
- adding and removing A again, receive msgs for start
- cycle, but *not* receive victim_done(A) msg before
- coming through fence_victims() again. */
-
- log_error("skip local_victim_done node %d",
- node->nodeid);
- continue;
- }
-
- /* limit repeated logging of the same failure messages
- when retrying fencing */
-
- limit = 0;
- retries = 0;
- memset(&prev_flog, 0, sizeof(flog));
- prev_flog_count = 0;
-
- retry:
- if (retries > 2)
- limit = 1;
- if (limit && !(retries % 600))
- log_level(LOG_INFO, "fencing node %s still retrying",
- node->name);
-
- /* for queries */
- fd->current_victim = node->nodeid;
-
- cluster_member = is_cluster_member_reread(node->nodeid);
- cpg_member = is_clean_daemon_member(node->nodeid);
- if (group_mode == GROUP_LIBCPG)
- ext = is_fenced_external(fd, node->nodeid);
- else
- ext = 0;
-
- if ((cluster_member && cpg_member) || ext) {
- log_debug("averting fence of node %s "
- "cluster member %d cpg member %d external %d",
- node->name, cluster_member, cpg_member, ext);
-
- node->local_victim_done = 1;
- victim_done(fd, node->nodeid,
- ext ? VIC_DONE_EXTERNAL : VIC_DONE_MEMBER);
- continue;
- }
-
- memset(&flog, 0, sizeof(flog));
- flog_count = 0;
-
- if (!limit)
- log_level(LOG_INFO, "fencing node %s", node->name);
-
- query_unlock();
- error = fence_node(node->name, flog, FL_SIZE, &flog_count);
- query_lock();
-
- if (flog_count > FL_SIZE) {
- log_error("fence_node log overflow %d", flog_count);
- flog_count = FL_SIZE;
- }
-
- if (limit && error &&
- flog_count == prev_flog_count &&
- !memcmp(&flog, &prev_flog, sizeof(flog))) {
- goto skip_log_message;
- }
-
- memcpy(&prev_flog, &flog, sizeof(flog));
- prev_flog_count = flog_count;
-
- for (i = 0; i < flog_count; i++) {
- ll = (flog[i].error == FE_AGENT_SUCCESS) ? LOG_DEBUG:
- LOG_ERR;
- log_level(ll, "fence %s dev %d.%d agent %s result: %s",
- node->name,
- flog[i].method_num, flog[i].device_num,
- flog[i].agent_name[0] ?
- flog[i].agent_name : "none",
- fe_str(flog[i].error));
- }
-
- log_error("fence %s %s", node->name,
- error ? "failed" : "success");
-
- if (!cfgd_disable_dbus) {
- fd_dbus_send(node->name, node->nodeid, error);
- }
-
- skip_log_message:
- if (!error) {
- node->local_victim_done = 1;
- victim_done(fd, node->nodeid, VIC_DONE_AGENT);
- continue;
- }
-
- if (!cfgd_override_path) {
- query_unlock();
- sleep(5);
- query_lock();
- retries++;
- goto retry;
- }
-
- /* Check for manual intervention */
- override = open_override(cfgd_override_path);
- if (check_override(override, node->name,
- cfgd_override_time) > 0) {
- log_level(LOG_WARNING, "fence %s overridden by "
- "administrator intervention", node->name);
- node->local_victim_done = 1;
- victim_done(fd, node->nodeid, VIC_DONE_OVERRIDE);
- close_override(&override, cfgd_override_path);
- continue;
- } else {
- close_override(&override, cfgd_override_path);
- retries++;
- goto retry;
- }
- }
-
- fd->current_victim = 0;
-}
-
diff --git a/fence/include/linux_endian.h b/fence/include/linux_endian.h
deleted file mode 100644
index 43089d2..0000000
--- a/fence/include/linux_endian.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef __LINUX_ENDIAN_DOT_H__
-#define __LINUX_ENDIAN_DOT_H__
-
-
-#include <endian.h>
-#include <byteswap.h>
-
-
-/* I'm not sure which versions of alpha glibc/gcc are broken,
- so fix all of them. */
-#ifdef __alpha__
-#undef bswap_64
-static __inline__ unsigned long bswap_64(unsigned long x)
-{
- unsigned int h = x >> 32;
- unsigned int l = x;
-
- h = bswap_32(h);
- l = bswap_32(l);
-
- return ((unsigned long)l << 32) | h;
-}
-#endif /* __alpha__ */
-
-
-#if __BYTE_ORDER == __BIG_ENDIAN
-
-#define be16_to_cpu(x) (x)
-#define be32_to_cpu(x) (x)
-#define be64_to_cpu(x) (x)
-
-#define cpu_to_be16(x) (x)
-#define cpu_to_be32(x) (x)
-#define cpu_to_be64(x) (x)
-
-#define le16_to_cpu(x) (bswap_16((x)))
-#define le32_to_cpu(x) (bswap_32((x)))
-#define le64_to_cpu(x) (bswap_64((x)))
-
-#define cpu_to_le16(x) (bswap_16((x)))
-#define cpu_to_le32(x) (bswap_32((x)))
-#define cpu_to_le64(x) (bswap_64((x)))
-
-#endif /* __BYTE_ORDER == __BIG_ENDIAN */
-
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-#define be16_to_cpu(x) (bswap_16((x)))
-#define be32_to_cpu(x) (bswap_32((x)))
-#define be64_to_cpu(x) (bswap_64((x)))
-
-#define cpu_to_be16(x) (bswap_16((x)))
-#define cpu_to_be32(x) (bswap_32((x)))
-#define cpu_to_be64(x) (bswap_64((x)))
-
-#define le16_to_cpu(x) (x)
-#define le32_to_cpu(x) (x)
-#define le64_to_cpu(x) (x)
-
-#define cpu_to_le16(x) (x)
-#define cpu_to_le32(x) (x)
-#define cpu_to_le64(x) (x)
-
-#endif /* __BYTE_ORDER == __LITTLE_ENDIAN */
-
-
-#endif /* __LINUX_ENDIAN_DOT_H__ */
diff --git a/fence/include/list.h b/fence/include/list.h
deleted file mode 100644
index 8100cbc..0000000
--- a/fence/include/list.h
+++ /dev/null
@@ -1,336 +0,0 @@
-/* Copied from include/linux/list.h */
-
-#ifndef _LINUX_LIST_H
-#define _LINUX_LIST_H
-
-/**
- * container_of - cast a member of a structure out to the containing structure
- *
- * @ptr: the pointer to the member.
- * @type: the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-
-
-/*
- * These are non-NULL pointers that will result in page faults
- * under normal circumstances, used to verify that nobody uses
- * non-initialized list entries.
- */
-#define LIST_POISON1 ((void *) 0x00100100)
-#define LIST_POISON2 ((void *) 0x00200200)
-
-/*
- * Simple doubly linked list implementation.
- *
- * Some of the internal functions ("__xxx") are useful when
- * manipulating whole lists rather than single entries, as
- * sometimes we already know the next/prev entries and we can
- * generate better code by using them directly rather than
- * using the generic single-entry routines.
- */
-
-struct list_head {
- struct list_head *next, *prev;
-};
-
-#define LIST_HEAD_INIT(name) { &(name), &(name) }
-
-#define LIST_HEAD(name) \
- struct list_head name = LIST_HEAD_INIT(name)
-
-#define INIT_LIST_HEAD(ptr) do { \
- (ptr)->next = (ptr); (ptr)->prev = (ptr); \
-} while (0)
-
-/*
- * Insert a new entry between two known consecutive entries.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_add(struct list_head *new,
- struct list_head *prev,
- struct list_head *next)
-{
- next->prev = new;
- new->next = next;
- new->prev = prev;
- prev->next = new;
-}
-
-/**
- * list_add - add a new entry
- * @new: new entry to be added
- * @head: list head to add it after
- *
- * Insert a new entry after the specified head.
- * This is good for implementing stacks.
- */
-static inline void list_add(struct list_head *new, struct list_head *head)
-{
- __list_add(new, head, head->next);
-}
-
-/**
- * list_add_tail - add a new entry
- * @new: new entry to be added
- * @head: list head to add it before
- *
- * Insert a new entry before the specified head.
- * This is useful for implementing queues.
- */
-static inline void list_add_tail(struct list_head *new, struct list_head *head)
-{
- __list_add(new, head->prev, head);
-}
-
-/*
- * Delete a list entry by making the prev/next entries
- * point to each other.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_del(struct list_head * prev, struct list_head * next)
-{
- next->prev = prev;
- prev->next = next;
-}
-
-/**
- * list_del - deletes entry from list.
- * @entry: the element to delete from the list.
- * Note: list_empty on entry does not return true after this, the entry is
- * in an undefined state.
- */
-static inline void list_del(struct list_head *entry)
-{
- __list_del(entry->prev, entry->next);
- entry->next = LIST_POISON1;
- entry->prev = LIST_POISON2;
-}
-
-/**
- * list_del_init - deletes entry from list and reinitialize it.
- * @entry: the element to delete from the list.
- */
-static inline void list_del_init(struct list_head *entry)
-{
- __list_del(entry->prev, entry->next);
- INIT_LIST_HEAD(entry);
-}
-
-/**
- * list_move - delete from one list and add as another's head
- * @list: the entry to move
- * @head: the head that will precede our entry
- */
-static inline void list_move(struct list_head *list, struct list_head *head)
-{
- __list_del(list->prev, list->next);
- list_add(list, head);
-}
-
-/**
- * list_move_tail - delete from one list and add as another's tail
- * @list: the entry to move
- * @head: the head that will follow our entry
- */
-static inline void list_move_tail(struct list_head *list,
- struct list_head *head)
-{
- __list_del(list->prev, list->next);
- list_add_tail(list, head);
-}
-
-/**
- * list_empty - tests whether a list is empty
- * @head: the list to test.
- */
-static inline int list_empty(const struct list_head *head)
-{
- return head->next == head;
-}
-
-/**
- * list_empty_careful - tests whether a list is
- * empty _and_ checks that no other CPU might be
- * in the process of still modifying either member
- *
- * NOTE: using list_empty_careful() without synchronization
- * can only be safe if the only activity that can happen
- * to the list entry is list_del_init(). Eg. it cannot be used
- * if another CPU could re-list_add() it.
- *
- * @head: the list to test.
- */
-static inline int list_empty_careful(const struct list_head *head)
-{
- struct list_head *next = head->next;
- return (next == head) && (next == head->prev);
-}
-
-static inline void __list_splice(struct list_head *list,
- struct list_head *head)
-{
- struct list_head *first = list->next;
- struct list_head *last = list->prev;
- struct list_head *at = head->next;
-
- first->prev = head;
- head->next = first;
-
- last->next = at;
- at->prev = last;
-}
-
-/**
- * list_splice - join two lists
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- */
-static inline void list_splice(struct list_head *list, struct list_head *head)
-{
- if (!list_empty(list))
- __list_splice(list, head);
-}
-
-/**
- * list_splice_init - join two lists and reinitialise the emptied list.
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- *
- * The list at @list is reinitialised
- */
-static inline void list_splice_init(struct list_head *list,
- struct list_head *head)
-{
- if (!list_empty(list)) {
- __list_splice(list, head);
- INIT_LIST_HEAD(list);
- }
-}
-
-/**
- * list_entry - get the struct for this entry
- * @ptr: the &struct list_head pointer.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_struct within the struct.
- */
-#define list_entry(ptr, type, member) \
- container_of(ptr, type, member)
-
-/**
- * list_first_entry - get the first element from a list
- * @ptr: the list head to take the element from.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_struct within the struct.
- *
- * Note, that list is expected to be not empty.
- */
-#define list_first_entry(ptr, type, member) \
- list_entry((ptr)->next, type, member)
-
-/**
- * list_for_each - iterate over a list
- * @pos: the &struct list_head to use as a loop counter.
- * @head: the head for your list.
- */
-#define list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * __list_for_each - iterate over a list
- * @pos: the &struct list_head to use as a loop counter.
- * @head: the head for your list.
- *
- * This variant differs from list_for_each() in that it's the
- * simplest possible list iteration code, no prefetching is done.
- * Use this for code that knows the list to be very short (empty
- * or 1 entry) most of the time.
- */
-#define __list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * list_for_each_prev - iterate over a list backwards
- * @pos: the &struct list_head to use as a loop counter.
- * @head: the head for your list.
- */
-#define list_for_each_prev(pos, head) \
- for (pos = (head)->prev; pos != (head); pos = pos->prev)
-
-/**
- * list_for_each_safe - iterate over a list safe against removal of list entry
- * @pos: the &struct list_head to use as a loop counter.
- * @n: another &struct list_head to use as temporary storage
- * @head: the head for your list.
- */
-#define list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
-
-/**
- * list_for_each_entry - iterate over list of given type
- * @pos: the type * to use as a loop counter.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry(pos, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_reverse - iterate backwards over list of given type.
- * @pos: the type * to use as a loop counter.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry_reverse(pos, head, member) \
- for (pos = list_entry((head)->prev, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.prev, typeof(*pos), member))
-
-/**
- * list_prepare_entry - prepare a pos entry for use as a start point in
- * list_for_each_entry_continue
- * @pos: the type * to use as a start point
- * @head: the head of the list
- * @member: the name of the list_struct within the struct.
- */
-#define list_prepare_entry(pos, head, member) \
- ((pos) ? : list_entry(head, typeof(*pos), member))
-
-/**
- * list_for_each_entry_continue - iterate over list of given type
- * continuing after existing point
- * @pos: the type * to use as a loop counter.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry_continue(pos, head, member) \
- for (pos = list_entry(pos->member.next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @pos: the type * to use as a loop counter.
- * @n: another type * to use as temporary storage
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry_safe(pos, n, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member), \
- n = list_entry(pos->member.next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-
-#endif
diff --git a/fence/libfence/Makefile b/fence/libfence/Makefile
deleted file mode 100644
index 93bf45c..0000000
--- a/fence/libfence/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-TARGET= libfence
-
-SOMAJOR=4
-SOMINOR=0
-
-OBJS= agent.o
-
-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${ccsincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${ccslibdir} -lccs
-LDFLAGS += -L${libdir}
diff --git a/fence/libfence/agent.c b/fence/libfence/agent.c
deleted file mode 100644
index fac6c92..0000000
--- a/fence/libfence/agent.c
+++ /dev/null
@@ -1,1142 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <string.h>
-#include <errno.h>
-#include <time.h>
-#include <limits.h>
-
-#include "libfence.h"
-#include "ccs.h"
-
-#define MAX_METHODS 8
-#define MAX_DEVICES 8
-
-#define METHOD_NAME_PATH "/cluster/clusternodes/clusternode[@name=\"%s\"]/fence/method[%d]/@name"
-#define DEVICE_NAME_PATH "/cluster/clusternodes/clusternode[@name=\"%s\"]/fence/method[@name=\"%s\"]/device[%d]/@name"
-#define NODE_FENCE_ARGS_PATH "/cluster/clusternodes/clusternode[@name=\"%s\"]/fence/method[@name=\"%s\"]/device[%d]/@*"
-#define AGENT_NAME_PATH "/cluster/fencedevices/fencedevice[@name=\"%s\"]/@agent"
-#define FENCE_DEVICE_ARGS_PATH "/cluster/fencedevices/fencedevice[@name=\"%s\"]/@*"
-
-
-
-static int run_agent(char *agent, char *args, int *agent_result)
-{
- int pid, status, len;
- int pr_fd, pw_fd; /* parent read/write file descriptors */
- int cr_fd, cw_fd; /* child read/write file descriptors */
- int fd1[2];
- int fd2[2];
-
- cr_fd = cw_fd = pr_fd = pw_fd = -1;
-
- if (args == NULL || agent == NULL)
- goto fail;
- len = strlen(args);
-
- if (pipe(fd1))
- goto fail;
- pr_fd = fd1[0];
- cw_fd = fd1[1];
-
- if (pipe(fd2))
- goto fail;
- cr_fd = fd2[0];
- pw_fd = fd2[1];
-
- pid = fork();
- if (pid < 0) {
- *agent_result = FE_AGENT_FORK;
- goto fail;
- }
-
- if (pid) {
- /* parent */
- int ret;
-
- fcntl(pr_fd, F_SETFL, fcntl(pr_fd, F_GETFL, 0) | O_NONBLOCK);
-
- do {
- ret = write(pw_fd, args, len);
- } while (ret < 0 && errno == EINTR);
-
- if (ret != len)
- goto fail;
-
- close(pw_fd);
- waitpid(pid, &status, 0);
-
- if (!WIFEXITED(status) || WEXITSTATUS(status)) {
- *agent_result = FE_AGENT_ERROR;
- goto fail;
- } else {
- *agent_result = FE_AGENT_SUCCESS;
- }
- } else {
- /* child */
-
- close(1);
- if (dup(cw_fd) < 0)
- goto fail;
- close(2);
- if (dup(cw_fd) < 0)
- goto fail;
- close(0);
- if (dup(cr_fd) < 0)
- goto fail;
- /* keep cw_fd open so parent can report all errors. */
- close(pr_fd);
- close(cr_fd);
- close(pw_fd);
-
- execlp(agent, agent, NULL);
- exit(EXIT_FAILURE);
- }
-
- close(pr_fd);
- close(cw_fd);
- close(cr_fd);
- close(pw_fd);
- return 0;
-
- fail:
- close(pr_fd);
- close(cw_fd);
- close(cr_fd);
- close(pw_fd);
- return -1;
-}
-
-static int make_args(int cd, char *victim, char *method, int d,
- char *device, char **args_out)
-{
- char path[PATH_MAX];
- char *args, *str;
- int error, ret, cnt = 0;
- size_t len, pos;
-
- args = malloc(FENCE_AGENT_ARGS_MAX);
- if (!args)
- return -ENOMEM;
- memset(args, 0, FENCE_AGENT_ARGS_MAX);
-
- len = FENCE_AGENT_ARGS_MAX - 1;
- pos = 0;
-
- /* node-specific args for victim */
-
- memset(path, 0, PATH_MAX);
- sprintf(path, NODE_FENCE_ARGS_PATH, victim, method, d+1);
-
- for (;;) {
- error = ccs_get_list(cd, path, &str);
- if (error || !str)
- break;
- ++cnt;
-
- if (!strncmp(str, "name=", 5)) {
- free(str);
- continue;
- }
-
- ret = snprintf(args + pos, len - pos, "%s\n", str);
-
- free(str);
-
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- /* add nodename of victim to args */
-
- if (!strstr(args, "nodename=")) {
- ret = snprintf(args + pos, len - pos, "nodename=%s\n", victim);
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- /* device-specific args */
-
- memset(path, 0, PATH_MAX);
- sprintf(path, FENCE_DEVICE_ARGS_PATH, device);
-
- for (;;) {
- error = ccs_get_list(cd, path, &str);
- if (error || !str)
- break;
- ++cnt;
-
- if (!strncmp(str, "name=", 5)) {
- free(str);
- continue;
- }
-
- ret = snprintf(args + pos, len - pos, "%s\n", str);
-
- free(str);
-
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- if (cnt)
- error = 0;
- out:
- if (error) {
- free(args);
- args = NULL;
- }
-
- *args_out = args;
- return error;
-}
-
-/* return name of m'th method for nodes/<victim>/fence/ */
-
-static int get_method(int cd, char *victim, int m, char **method)
-{
- char path[PATH_MAX], *str = NULL;
- int error;
-
- memset(path, 0, PATH_MAX);
- sprintf(path, METHOD_NAME_PATH, victim, m+1);
-
- error = ccs_get(cd, path, &str);
- *method = str;
- return error;
-}
-
-/* return name of d'th device under nodes/<victim>/fence/<method>/ */
-
-static int get_device(int cd, char *victim, char *method, int d, char **device)
-{
- char path[PATH_MAX], *str = NULL;
- int error;
-
- memset(path, 0, PATH_MAX);
- sprintf(path, DEVICE_NAME_PATH, victim, method, d+1);
-
- error = ccs_get(cd, path, &str);
- *device = str;
- return error;
-}
-
-static int count_methods(int cd, char *victim)
-{
- char path[PATH_MAX], *name;
- int error, i;
-
- for (i = 0; i < MAX_METHODS; i++) {
- memset(path, 0, PATH_MAX);
- sprintf(path, METHOD_NAME_PATH, victim, i+1);
-
- error = ccs_get(cd, path, &name);
- if (error)
- break;
- free(name);
- }
- return i;
-}
-
-static int count_devices(int cd, char *victim, char *method)
-{
- char path[PATH_MAX], *name;
- int error, i;
-
- for (i = 0; i < MAX_DEVICES; i++) {
- memset(path, 0, PATH_MAX);
- sprintf(path, DEVICE_NAME_PATH, victim, method, i+1);
-
- error = ccs_get(cd, path, &name);
- if (error)
- break;
- free(name);
- }
- return i;
-}
-
-static int use_device(int cd, char *victim, char *method, int d,
- char *device, struct fence_log *lp)
-{
- char path[PATH_MAX], *agent, *args = NULL;
- int error;
-
- memset(path, 0, PATH_MAX);
- sprintf(path, AGENT_NAME_PATH, device);
-
- error = ccs_get(cd, path, &agent);
- if (error) {
- lp->error = FE_READ_AGENT;
- goto out;
- }
-
- strncpy(lp->agent_name, agent, FENCE_AGENT_NAME_MAX-1);
-
- error = make_args(cd, victim, method, d, device, &args);
- if (error) {
- lp->error = FE_READ_ARGS;
- goto out_agent;
- }
-
- strncpy(lp->agent_args, args, FENCE_AGENT_ARGS_MAX-1);
-
- error = run_agent(agent, args, &lp->error);
-
- free(args);
- out_agent:
- free(agent);
- out:
- return error;
-}
-
-int fence_node(char *victim, struct fence_log *log, int log_size,
- int *log_count)
-{
- struct fence_log stub;
- struct fence_log *lp = log;
- char *method = NULL, *device = NULL;
- char *victim_nodename = NULL;
- int num_methods, num_devices, m, d, cd, rv;
- int left = log_size;
- int error = -1;
- int count = 0;
-
- cd = ccs_connect();
- if (cd < 0) {
- if (lp && left) {
- lp->error = FE_NO_CONFIG;
- lp++;
- left--;
- }
- count++;
- error = -1;
- goto ret;
- }
-
- if (ccs_lookup_nodename(cd, victim, &victim_nodename) == 0)
- victim = victim_nodename;
-
- num_methods = count_methods(cd, victim);
- if (!num_methods) {
- if (lp && left) {
- lp->error = FE_NO_METHOD;
- lp++;
- left--;
- }
- count++;
- error = -2; /* No fencing */
- goto out;
- }
-
- for (m = 0; m < num_methods; m++) {
-
- rv = get_method(cd, victim, m, &method);
- if (rv) {
- if (lp && left) {
- lp->error = FE_READ_METHOD;
- lp->method_num = m;
- lp++;
- left--;
- }
- count++;
- error = -1;
- continue;
- }
-
- num_devices = count_devices(cd, victim, method);
- if (!num_devices) {
- if (lp && left) {
- lp->error = FE_NO_DEVICE;
- lp->method_num = m;
- lp++;
- left--;
- }
- count++;
- error = -1;
- continue;
- }
-
- for (d = 0; d < num_devices; d++) {
- rv = get_device(cd, victim, method, d, &device);
- if (rv) {
- if (lp && left) {
- lp->error = FE_READ_DEVICE;
- lp->method_num = m;
- lp->device_num = d;
- lp++;
- left--;
- }
- count++;
- error = -1;
- break;
- }
-
- /* every call to use_device generates a log entry,
- whether success or fail */
-
- error = use_device(cd, victim, method, d, device,
- (lp && left) ? lp : &stub);
- count++;
- if (lp && left) {
- /* error, name, args already set */
- lp->method_num = m;
- lp->device_num = d;
- lp++;
- left--;
- }
-
- if (error)
- break;
-
- free(device);
- device = NULL;
- }
-
- if (device)
- free(device);
-
- free(method);
-
- /* we return 0 for fencing success when use_device has
- returned zero for each device in this method */
-
- if (!error)
- break;
- }
-
- if (victim_nodename)
- free(victim_nodename);
- out:
- ccs_disconnect(cd);
- ret:
- if (log_count)
- *log_count = count;
- return error;
-}
-
-#define UN_DEVICE_NAME_PATH "/cluster/clusternodes/clusternode[@name=\"%s\"]/unfence/device[%d]/@name"
-#define UN_NODE_FENCE_ARGS_PATH "/cluster/clusternodes/clusternode[@name=\"%s\"]/unfence/device[%d]/@*"
-
-static int make_args_unfence(int cd, char *victim, int d,
- char *device, char **args_out)
-{
- char path[PATH_MAX];
- char *args, *str;
- int error, ret, cnt = 0;
- size_t len, pos;
-
- args = malloc(FENCE_AGENT_ARGS_MAX);
- if (!args)
- return -ENOMEM;
- memset(args, 0, FENCE_AGENT_ARGS_MAX);
-
- len = FENCE_AGENT_ARGS_MAX - 1;
- pos = 0;
-
- /* node-specific args for victim */
-
- memset(path, 0, PATH_MAX);
- sprintf(path, UN_NODE_FENCE_ARGS_PATH, victim, d+1);
-
- for (;;) {
- error = ccs_get_list(cd, path, &str);
- if (error || !str)
- break;
- ++cnt;
-
- if (!strncmp(str, "name=", 5)) {
- free(str);
- continue;
- }
-
- ret = snprintf(args + pos, len - pos, "%s\n", str);
-
- free(str);
-
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- /* add nodename of victim to args */
-
- if (!strstr(args, "nodename=")) {
- ret = snprintf(args + pos, len - pos, "nodename=%s\n", victim);
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- /* device-specific args */
-
- memset(path, 0, PATH_MAX);
- sprintf(path, FENCE_DEVICE_ARGS_PATH, device);
-
- for (;;) {
- error = ccs_get_list(cd, path, &str);
- if (error || !str)
- break;
- ++cnt;
-
- if (!strncmp(str, "name=", 5)) {
- free(str);
- continue;
- }
-
- ret = snprintf(args + pos, len - pos, "%s\n", str);
-
- free(str);
-
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- if (cnt)
- error = 0;
- out:
- if (error) {
- free(args);
- args = NULL;
- }
-
- *args_out = args;
- return error;
-}
-
-/* return name of d'th device under nodes/<victim>/unfence/ */
-
-static int get_device_unfence(int cd, char *victim, int d, char **device)
-{
- char path[PATH_MAX], *str = NULL;
- int error;
-
- memset(path, 0, PATH_MAX);
- sprintf(path, UN_DEVICE_NAME_PATH, victim, d+1);
-
- error = ccs_get(cd, path, &str);
- *device = str;
- return error;
-}
-
-static int count_devices_unfence(int cd, char *victim)
-{
- char path[PATH_MAX], *name;
- int error, i;
-
- for (i = 0; i < MAX_DEVICES; i++) {
- memset(path, 0, PATH_MAX);
- sprintf(path, UN_DEVICE_NAME_PATH, victim, i+1);
-
- error = ccs_get(cd, path, &name);
- if (error)
- break;
- free(name);
- }
- return i;
-}
-
-static int use_device_unfence(int cd, char *victim, int d,
- char *device, struct fence_log *lp)
-{
- char path[PATH_MAX], *agent, *args = NULL;
- int error;
-
- memset(path, 0, PATH_MAX);
- sprintf(path, AGENT_NAME_PATH, device);
-
- error = ccs_get(cd, path, &agent);
- if (error) {
- lp->error = FE_READ_AGENT;
- goto out;
- }
-
- strncpy(lp->agent_name, agent, FENCE_AGENT_NAME_MAX-1);
-
- error = make_args_unfence(cd, victim, d, device, &args);
- if (error) {
- lp->error = FE_READ_ARGS;
- goto out_agent;
- }
-
- strncpy(lp->agent_args, args, FENCE_AGENT_ARGS_MAX);
-
- error = run_agent(agent, args, &lp->error);
-
- free(args);
- out_agent:
- free(agent);
- out:
- return error;
-}
-
-int unfence_node(char *victim, struct fence_log *log, int log_size,
- int *log_count)
-{
- struct fence_log stub;
- struct fence_log *lp = log;
- char *device = NULL;
- char *victim_nodename = NULL;
- int num_devices, d, cd, rv;
- int left = log_size;
- int error = -1;
- int count = 0;
-
- cd = ccs_connect();
- if (cd < 0) {
- if (lp && left) {
- lp->error = FE_NO_CONFIG;
- lp++;
- left--;
- }
- count++;
- error = -1;
- goto ret;
- }
-
- if (ccs_lookup_nodename(cd, victim, &victim_nodename) == 0)
- victim = victim_nodename;
-
- /* return -2 if unfencing fails because there's no unfencing
- defined for the node */
-
- num_devices = count_devices_unfence(cd, victim);
- if (!num_devices) {
- if (lp && left) {
- lp->error = FE_NO_DEVICE;
- lp++;
- left--;
- }
- count++;
- error = -2;
- goto out;
- }
-
- /* try to unfence all devices even if some of them fail,
- but the final return value is 0 only if all succeed */
-
- error = 0;
-
- for (d = 0; d < num_devices; d++) {
- rv = get_device_unfence(cd, victim, d, &device);
- if (rv) {
- if (lp && left) {
- lp->error = FE_READ_DEVICE;
- lp->device_num = d;
- lp++;
- left--;
- }
- count++;
- error = -1;
- continue;
- }
-
- /* every call to use_device generates a log entry,
- whether success or fail */
-
- rv = use_device_unfence(cd, victim, d, device,
- (lp && left) ? lp : &stub);
- count++;
- if (lp && left) {
- /* error, name, args already set */
- lp->device_num = d;
- lp++;
- left--;
- }
-
- if (rv)
- error = -1;
-
- free(device);
- device = NULL;
- }
-
- if (victim_nodename)
- free(victim_nodename);
- out:
- ccs_disconnect(cd);
- ret:
- if (log_count)
- *log_count = count;
- return error;
-}
-
-/*
- * Returns:
- * < 0: internal error
- * 0: agent exited with 0
- * 1: agent exited with 1
- * 2: agent exited with 2
- */
-
-static int run_agent_status(char *agent, char *args, int *agent_result)
-{
- int pid, status, len, rv;
- int pw_fd = -1; /* parent write file descriptor */
- int cr_fd = -1; /* child read file descriptor */
- int pfd[2];
-
- if (args == NULL || agent == NULL) {
- rv = -1;
- goto fail;
- }
- len = strlen(args);
-
- if (pipe(pfd)) {
- rv = -errno;
- goto fail;
- }
- cr_fd = pfd[0];
- pw_fd = pfd[1];
-
- pid = fork();
- if (pid < 0) {
- rv = -errno;
- *agent_result = FE_AGENT_FORK;
- goto fail;
- }
-
- if (pid) {
- /* parent */
- int ret;
-
- do {
- ret = write(pw_fd, args, len);
- } while (ret < 0 && errno == EINTR);
-
- if (ret != len) {
- rv = -1;
- goto fail;
- }
-
- close(cr_fd);
- close(pw_fd);
-
- rv = waitpid(pid, &status, 0);
-
- if (rv < 0) {
- /* shouldn't happen */
- rv = -errno;
- goto out;
- }
-
- if (rv != pid) {
- /* shouldn't happen */
- rv = -1;
- goto out;
- }
-
- if (WIFEXITED(status)) {
- /* pid exited properly with an exit code */
- rv = WEXITSTATUS(status);
-
- if (rv == 0)
- *agent_result = FE_AGENT_STATUS_ON;
- else if (rv == 2)
- *agent_result = FE_AGENT_STATUS_OFF;
- else
- *agent_result = FE_AGENT_STATUS_ERROR;
- } else if (WIFSIGNALED(status)) {
- /* pid terminated due to a signal */
- rv = -1;
- *agent_result = FE_AGENT_STATUS_ERROR;
- } else {
- /* something else happened, not sure what */
- rv = -1;
- *agent_result = FE_AGENT_STATUS_ERROR;
- }
- goto out;
-
- } else {
- /* child */
- int c_stdout, c_stderr;
-
- /* redirect agent stdout/stderr to /dev/null */
- close(1);
- c_stdout = open("/dev/null", O_WRONLY);
- if (c_stdout < 0) {
- rv = -1;
- goto fail;
- }
- close(2);
- c_stderr = open("/dev/null", O_WRONLY);
- if (c_stderr < 0) {
- rv = -1;
- goto fail;
- }
-
- /* redirect agent stdin from parent */
- close(0);
- if (dup(cr_fd) < 0) {
- rv = -errno;
- goto fail;
- }
-
- close(cr_fd);
- close(pw_fd);
-
- execlp(agent, agent, NULL);
- exit(EXIT_FAILURE);
- }
- fail:
- close(cr_fd);
- close(pw_fd);
- out:
- return rv;
-}
-
-static int make_args_status(int cd, char *victim, char *method, int d,
- char *device, char **args_out)
-{
- char path[PATH_MAX];
- char *args, *str;
- int error, ret, cnt = 0;
- size_t len, pos;
-
- args = malloc(FENCE_AGENT_ARGS_MAX);
- if (!args)
- return -ENOMEM;
- memset(args, 0, FENCE_AGENT_ARGS_MAX);
-
- len = FENCE_AGENT_ARGS_MAX - 1;
- pos = 0;
-
- /* node-specific args for victim */
-
- memset(path, 0, PATH_MAX);
- sprintf(path, NODE_FENCE_ARGS_PATH, victim, method, d+1);
-
- for (;;) {
- error = ccs_get_list(cd, path, &str);
- if (error || !str)
- break;
- ++cnt;
-
- if (!strncmp(str, "name=", 5)) {
- free(str);
- continue;
- }
-
- if (!strncmp(str, "action=", 7)) {
- free(str);
- continue;
- }
-
- ret = snprintf(args + pos, len - pos, "%s\n", str);
-
- free(str);
-
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- /* add nodename of victim to args */
-
- if (!strstr(args, "nodename=")) {
- ret = snprintf(args + pos, len - pos, "nodename=%s\n", victim);
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- /* add action=status to args */
-
- ret = snprintf(args + pos, len - pos, "action=status\n");
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
-
- /* device-specific args */
-
- memset(path, 0, PATH_MAX);
- sprintf(path, FENCE_DEVICE_ARGS_PATH, device);
-
- for (;;) {
- error = ccs_get_list(cd, path, &str);
- if (error || !str)
- break;
- ++cnt;
-
- if (!strncmp(str, "name=", 5)) {
- free(str);
- continue;
- }
-
- ret = snprintf(args + pos, len - pos, "%s\n", str);
-
- free(str);
-
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- if (cnt)
- error = 0;
- out:
- if (error) {
- free(args);
- args = NULL;
- }
-
- *args_out = args;
- return error;
-}
-
-static int use_device_status(int cd, char *victim, char *method, int d,
- char *device, struct fence_log *lp)
-{
- char path[PATH_MAX], *agent, *args = NULL;
- int error;
-
- memset(path, 0, PATH_MAX);
- sprintf(path, AGENT_NAME_PATH, device);
-
- error = ccs_get(cd, path, &agent);
- if (error) {
- lp->error = FE_READ_AGENT;
- goto out;
- }
-
- strncpy(lp->agent_name, agent, FENCE_AGENT_NAME_MAX-1);
-
- error = make_args_status(cd, victim, method, d, device, &args);
- if (error) {
- lp->error = FE_READ_ARGS;
- goto out_agent;
- }
-
- strncpy(lp->agent_args, args, FENCE_AGENT_ARGS_MAX-1);
-
- error = run_agent_status(agent, args, &lp->error);
-
- free(args);
- out_agent:
- free(agent);
- out:
- return error;
-}
-
-/* We want to run status on each device in each method, and we need all
- to succeed in order for status as a whole to succeed. Agent success
- for status is being either "on" (exit 0) or "off" (exit 2). Agent
- failure for status is when the on/off state is unknown (exit 1),
- i.e. the agent failed to run or ran and cannot connect, or cannot get
- the on/off state for some reason.
-
- As soon as any one device in any method fails, we can quit and report
- failure (rv < 0) for status as a whole. If status of all devices is
- "on", then status as a whole returns 0. If status of all devices are
- "off", then status as a whole returns 2. If the status of all devices
- are mixed on/off, then status as a whole returns 0. */
-
-int fence_node_status(char *victim, struct fence_log *log, int log_size,
- int *log_count, int use_method_num)
-{
- struct fence_log stub;
- struct fence_log *lp = log;
- char *method = NULL, *device = NULL;
- char *victim_nodename = NULL;
- int num_methods, num_devices, m, d, cd, rv;
- int on_count = 0, off_count = 0;
- int left = log_size;
- int error = -1;
- int count = 0;
-
- cd = ccs_connect();
- if (cd < 0) {
- if (lp && left) {
- lp->error = FE_NO_CONFIG;
- lp++;
- left--;
- }
- count++;
- error = -1;
- goto ret;
- }
-
- if (ccs_lookup_nodename(cd, victim, &victim_nodename) == 0)
- victim = victim_nodename;
-
- num_methods = count_methods(cd, victim);
- if (!num_methods) {
- if (lp && left) {
- lp->error = FE_NO_METHOD;
- lp++;
- left--;
- }
- count++;
- error = -2; /* No fencing */
- goto out;
- }
-
- if (use_method_num && (use_method_num > num_methods)) {
- if (lp && left) {
- lp->error = FE_NUM_METHOD;
- lp++;
- left--;
- }
- count++;
- error = -2; /* No fencing */
- goto out;
- }
-
- for (m = 0; m < num_methods; m++) {
-
- if (use_method_num && (m + 1 != use_method_num))
- continue;
-
- rv = get_method(cd, victim, m, &method);
- if (rv) {
- if (lp && left) {
- lp->error = FE_READ_METHOD;
- lp->method_num = m;
- lp++;
- left--;
- }
- count++;
- error = -1;
- break;
- }
-
- num_devices = count_devices(cd, victim, method);
- if (!num_devices) {
- if (lp && left) {
- lp->error = FE_NO_DEVICE;
- lp->method_num = m;
- lp++;
- left--;
- }
- count++;
- continue;
- }
-
- for (d = 0; d < num_devices; d++) {
- rv = get_device(cd, victim, method, d, &device);
- if (rv) {
- if (lp && left) {
- lp->error = FE_READ_DEVICE;
- lp->method_num = m;
- lp->device_num = d;
- lp++;
- left--;
- }
- count++;
- error = -1;
- break;
- }
-
- /* every call to use_device generates a log entry,
- whether success or fail */
-
- error = use_device_status(cd, victim, method, d, device,
- (lp && left) ? lp : &stub);
- count++;
- if (lp && left) {
- /* error, name, args already set */
- lp->method_num = m;
- lp->device_num = d;
- lp++;
- left--;
- }
-
- /*
- * error values:
- * < 0: internal error from use_device_status,
- * internal error from run_agent_status,
- * run_agent_status failed to fork agent
- * 0: agent exited with 0 (success, status is on)
- * 2: agent exited with 2 (success, status is off)
- * 1: agent exited with 1 (error, status is unknown)
- */
-
- /* internal error: status fail */
- if (error < 0)
- break;
-
- /* agent error: status fail */
- if (error == 1) {
- error = -1;
- break;
- }
-
- if (!error) {
- /* agent success "on": status success */
- on_count++;
- } else if (error == 2) {
- /* agent success "off": status success */
- error = 0;
- off_count++;
- } else {
- /* some other error */
- error = -1;
- break;
- }
-
- free(device);
- device = NULL;
- }
-
- if (device)
- free(device);
-
- free(method);
-
- /* if any device failed in this method, return failure
- for the status */
-
- if (error)
- break;
- }
-
- if (error < 0)
- goto out;
-
- /* All devices are either on or off, none are unknown/inaccessible,
- so status as a whole is a success. Decide which of the two
- success values to return: 2 if all devices are off, or 0 if
- all devices are on, 0 if mixed on/off. */
-
- if (!on_count)
- error = 2;
- else
- error = 0;
-
- out:
- if (victim_nodename)
- free(victim_nodename);
-
- ccs_disconnect(cd);
- ret:
- if (log_count)
- *log_count = count;
- return error;
-}
-
diff --git a/fence/libfence/libfence.h b/fence/libfence/libfence.h
deleted file mode 100644
index 10d00f0..0000000
--- a/fence/libfence/libfence.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef _LIBFENCE_H_
-#define _LIBFENCE_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define FE_AGENT_SUCCESS 1 /* agent exited with EXIT_SUCCESS */
-#define FE_AGENT_ERROR 2 /* agent exited with EXIT_FAILURE */
-#define FE_AGENT_FORK 3 /* error forking agent */
-#define FE_NO_CONFIG 4 /* ccs_connect error */
-#define FE_NO_METHOD 5 /* zero methods defined */
-#define FE_NO_DEVICE 6 /* zero devices defined in method */
-#define FE_READ_AGENT 7 /* read (ccs) error on agent path */
-#define FE_READ_ARGS 8 /* read (ccs) error on node/dev args */
-#define FE_READ_METHOD 9 /* read (ccs) error on method */
-#define FE_READ_DEVICE 10 /* read (ccs) error on method/device */
-#define FE_NUM_METHOD 11 /* method number does not exist */
-#define FE_AGENT_STATUS_ON 12
-#define FE_AGENT_STATUS_OFF 13
-#define FE_AGENT_STATUS_ERROR 14
-
-#define FENCE_AGENT_NAME_MAX 256 /* including terminating \0 */
-#define FENCE_AGENT_ARGS_MAX 4096 /* including terminating \0 */
-
-struct fence_log {
- int error;
- int method_num;
- int device_num;
- char agent_name[FENCE_AGENT_NAME_MAX];
- char agent_args[FENCE_AGENT_ARGS_MAX];
-};
-
-int fence_node(char *name, struct fence_log *log, int log_size, int *log_count);
-
-int unfence_node(char *name, struct fence_log *log, int log_size,
- int *log_count);
-
-/*
- * use_method_num == 0: run status on all devices of all methods
- * use_method_num > 0: run status on all devices of given method number,
- * where first method is use_method_num = 1
- *
- * Returns 0 on success: status is successful on all devices of all methods
- * (or all devices of specified method). All devices are in the "on" state,
- * or some devices are on and some are off.
- *
- * Returns 2 on success: status is successful on all devices of all methods
- * (or all devices of a specified method). All devices are in the "off" state.
- *
- * Returns -2 if no fencing methods are defined for the node, or if
- * use_method_num was specified and the specified method number does
- * not exist.
- *
- * Returns -EXXX for other failures.
- */
-
-int fence_node_status(char *victim, struct fence_log *log, int log_size,
- int *log_count, int use_method_num);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/fence/libfence/libfence.pc.in b/fence/libfence/libfence.pc.in
deleted file mode 100644
index 300ddf4..0000000
--- a/fence/libfence/libfence.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: libfence
-Version: @VERSION@
-Description: Cluster Fencing library
-Requires:
-Libs: -L${libdir} -lfence
-Cflags: -I${includedir}
diff --git a/fence/libfenced/Makefile b/fence/libfenced/Makefile
deleted file mode 100644
index 17148e1..0000000
--- a/fence/libfenced/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-TARGET= libfenced
-
-OBJS= main.o
-
-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$(S)/../fenced
-CFLAGS += -I${incdir}
diff --git a/fence/libfenced/libfenced.h b/fence/libfenced/libfenced.h
deleted file mode 100644
index 8ddda65..0000000
--- a/fence/libfenced/libfenced.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * libfenced is a private library.
- *
- * If you think this library is installed on your cluster, you are wrong.
- * You have never seen it, it doesn't exist, you'll never talk about it
- * or ponder to use it.
- *
- * "You've got a nice noun there.
- * It'd be a shame if anything were to ... happen to it."
- *
- * The Godfather (aka fabbione)
- */
-
-#ifndef _LIBFENCED_H_
-#define _LIBFENCED_H_
-
-#define FENCED_DUMP_SIZE (1024 * 1024)
-
-/* for querying local node info */
-#define FENCED_NODEID_US 0
-
-struct fenced_node {
- int nodeid;
- int member;
- int victim;
- int last_fenced_master;
- int last_fenced_how;
- uint64_t last_fenced_time;
-};
-
-struct fenced_domain {
- int group_mode;
- int member_count;
- int victim_count;
- int master_nodeid;
- int current_victim;
- int state;
-};
-
-/* fenced_domain_nodes() types */
-#define FENCED_NODES_ALL 1
-#define FENCED_NODES_MEMBERS 2
-#define FENCED_NODES_VICTIMS 3
-
-int fenced_join(void);
-int fenced_leave(void);
-int fenced_dump_debug(char *buf);
-int fenced_external(char *name);
-int fenced_node_info(int nodeid, struct fenced_node *node);
-int fenced_domain_info(struct fenced_domain *domain);
-int fenced_domain_nodes(int type, int max, int *count, struct fenced_node *nodes);
-
-#endif
diff --git a/fence/libfenced/libfenced.pc.in b/fence/libfenced/libfenced.pc.in
deleted file mode 100644
index 208e6b3..0000000
--- a/fence/libfenced/libfenced.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: libfenced
-Version: @VERSION@
-Description: Private Fencing Comm. Library - DO NOT USE - see lib header
-Requires:
-Libs: -L${libdir} -lfenced
-Cflags: -I${includedir}
diff --git a/fence/libfenced/main.c b/fence/libfenced/main.c
deleted file mode 100644
index 9537953..0000000
--- a/fence/libfenced/main.c
+++ /dev/null
@@ -1,323 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include "fenced.h"
-#include "libfenced.h"
-
-static int do_read(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- while (off < count) {
- rv = read(fd, (char *)buf + off, count - off);
- if (rv == 0)
- return -1;
- if (rv == -1 && errno == EINTR)
- continue;
- if (rv == -1)
- return -1;
- off += rv;
- }
- return 0;
-}
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, (char *)buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0) {
- return rv;
- }
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-static int do_connect(const char *sock_path)
-{
- struct sockaddr_un sun;
- socklen_t addrlen;
- int rv, fd;
-
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (fd < 0)
- goto out;
-
- memset(&sun, 0, sizeof(sun));
- sun.sun_family = AF_UNIX;
- strcpy(&sun.sun_path[1], sock_path);
- addrlen = sizeof(sa_family_t) + strlen(sun.sun_path+1) + 1;
-
- rv = connect(fd, (struct sockaddr *) &sun, addrlen);
- if (rv < 0) {
- close(fd);
- fd = rv;
- }
- out:
- return fd;
-}
-
-static void init_header(struct fenced_header *h, int cmd, int extra_len)
-{
- memset(h, 0, sizeof(struct fenced_header));
-
- h->magic = FENCED_MAGIC;
- h->version = FENCED_VERSION;
- h->len = sizeof(struct fenced_header) + extra_len;
- h->command = cmd;
-}
-
-int fenced_join(void)
-{
- struct fenced_header h;
- int fd, rv;
-
- init_header(&h, FENCED_CMD_JOIN, 0);
-
- fd = do_connect(FENCED_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- close(fd);
- out:
- return rv;
-}
-
-int fenced_leave(void)
-{
- struct fenced_header h;
- int fd, rv;
-
- init_header(&h, FENCED_CMD_LEAVE, 0);
-
- fd = do_connect(FENCED_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- close(fd);
- out:
- return rv;
-}
-
-int fenced_external(char *name)
-{
- char msg[sizeof(struct fenced_header) + MAX_NODENAME_LEN + 1];
- struct fenced_header *hd = (struct fenced_header *)msg;
- int fd, rv;
- int namelen;
-
- memset(&msg, 0, sizeof(msg));
-
- init_header(hd, FENCED_CMD_EXTERNAL, MAX_NODENAME_LEN + 1);
-
- namelen = strlen(name);
- if (namelen > MAX_NODENAME_LEN)
- namelen = MAX_NODENAME_LEN;
- memcpy(msg + sizeof(struct fenced_header), name, namelen);
-
- fd = do_connect(FENCED_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, hd, sizeof(msg));
- close(fd);
- out:
- return rv;
-}
-
-int fenced_dump_debug(char *buf)
-{
- struct fenced_header h, *rh;
- char *reply;
- int reply_len;
- int fd, rv;
-
- init_header(&h, FENCED_CMD_DUMP_DEBUG, 0);
-
- reply_len = sizeof(struct fenced_header) + FENCED_DUMP_SIZE;
- reply = malloc(reply_len);
- if (!reply) {
- rv = -1;
- goto out;
- }
- memset(reply, 0, reply_len);
-
- fd = do_connect(FENCED_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- /* won't always get back the full reply_len */
- do_read(fd, reply, reply_len);
-
- rh = (struct fenced_header *)reply;
- rv = rh->data;
- if (rv < 0)
- goto out_close;
-
- memcpy(buf, (char *)reply + sizeof(struct fenced_header),
- FENCED_DUMP_SIZE);
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int fenced_node_info(int nodeid, struct fenced_node *node)
-{
- struct fenced_header h, *rh;
- char reply[sizeof(struct fenced_header) + sizeof(struct fenced_node)];
- int fd, rv;
-
- init_header(&h, FENCED_CMD_NODE_INFO, 0);
- h.data = nodeid;
-
- memset(reply, 0, sizeof(reply));
-
- fd = do_connect(FENCED_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- rv = do_read(fd, reply, sizeof(reply));
- if (rv < 0)
- goto out_close;
-
- rh = (struct fenced_header *)reply;
- rv = rh->data;
- if (rv < 0)
- goto out_close;
-
- memcpy(node, (char *)reply + sizeof(struct fenced_header),
- sizeof(struct fenced_node));
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int fenced_domain_info(struct fenced_domain *domain)
-{
- struct fenced_header h, *rh;
- char reply[sizeof(struct fenced_header) + sizeof(struct fenced_domain)];
- int fd, rv;
-
- init_header(&h, FENCED_CMD_DOMAIN_INFO, 0);
-
- memset(reply, 0, sizeof(reply));
-
- fd = do_connect(FENCED_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- rv = do_read(fd, reply, sizeof(reply));
- if (rv < 0)
- goto out_close;
-
- rh = (struct fenced_header *)reply;
- rv = rh->data;
- if (rv < 0)
- goto out_close;
-
- memcpy(domain, (char *)reply + sizeof(struct fenced_header),
- sizeof(struct fenced_domain));
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int fenced_domain_nodes(int type, int max, int *count, struct fenced_node *nodes)
-{
- struct fenced_header h, *rh;
- char *reply;
- int reply_len;
- int fd, rv, result, node_count;
-
- init_header(&h, FENCED_CMD_DOMAIN_NODES, 0);
- h.option = type;
- h.data = max;
-
- reply_len = sizeof(struct fenced_header) + (max * sizeof(struct fenced_node));
- reply = malloc(reply_len);
- if (!reply) {
- rv = -1;
- goto out;
- }
- memset(reply, 0, reply_len);
-
- fd = do_connect(FENCED_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- /* won't usually get back the full reply_len */
- do_read(fd, reply, reply_len);
-
- rh = (struct fenced_header *)reply;
- result = rh->data;
- if (result < 0 && result != -E2BIG) {
- rv = result;
- goto out_close;
- }
-
- if (result == -E2BIG) {
- *count = -E2BIG;
- node_count = max;
- } else {
- *count = result;
- node_count = result;
- }
- rv = 0;
-
- memcpy(nodes, (char *)reply + sizeof(struct fenced_header),
- node_count * sizeof(struct fenced_node));
- out_close:
- close(fd);
- out:
- return rv;
-}
-
diff --git a/fence/man/Makefile b/fence/man/Makefile
deleted file mode 100644
index 3c9aa44..0000000
--- a/fence/man/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-include ../../make/defines.mk
-
-MANTARGET = fenced.8 fence_node.8 fence_tool.8 fence_check.8
-
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-all:
-
-clean:
diff --git a/fence/man/fence_check.8 b/fence/man/fence_check.8
deleted file mode 100644
index 7fc221c..0000000
--- a/fence/man/fence_check.8
+++ /dev/null
@@ -1,65 +0,0 @@
-.TH "fence_check" "8" "September 2012" "" "fence configuration check"
-.SH "NAME"
-fence_check \- fence configuration check utility
-.SH "SYNOPSIS"
-\fBfence_check [\-h] [\-V] [\-d] [\-v] [\-e]
-.SH "DESCRIPTION"
-.PP
-The \fBfence_check\fP utility can be used to actively test the fence
-configuration for each node in the cluster, by issuing status commands
-instead of "reboot" "on" "off" commands on the configured fence
-methods/devices in cluster.conf.
-
-\fBfence_check\fP can also be very useful when executed via a cron job
-for regular monitoring of fence devices and to detect issues after
-cluster.conf changes.
-
-.SH "OPTIONS"
-.IP "\-h"
-Print help message, then exit.
-.IP "\-V"
-Print program version information, then exit.
-.IP "\-d"
-Disable output to logfile (default /var/log/cluster/fence_check.log).
-Useful in combination with \-e that could record sensitive data from
-cluster.conf.
-.IP "\-v"
-Enable verbose output of all actions taken during execution.
-Useful to debug issues with fence_check execution.
-Use of \-v does not include \-e.
-.IP "\-e"
-Produce detailed output, in case of failure, of the command used to test
-the fence device. Use of \-e does not include \-v.
-ATTENTION: IT MIGHT SHOW FENCE PASSWORDS IN LOG FILES! USE WITH CARE!
-.IP "\-f"
-Override checks and force execution. DO NOT USE ON PRODUCTION CLUSTERS!
-
-.SH "NOTES"
-\fBfence_check\fP can only be executed when the following conditions are met:
-
-\- cman is running on the node
-
-\- the node is quorate
-
-\- the node has joined the fence domain
-
-\- the node is in charge of fencing for the whole cluster
-
-\- no real fencing action is in progress
-
-\- no other \fBfence_check\fP operations are in progress.
-
-\fBfence_check\fP will perform all those checks prior starting a cluster wide
-fence status check. When used in combination with \-f, cman must be running
-on the node and no other processes must be performing a check at the same time.
-
-By default every run of \fBfence_check\fP is logged to logfile and to stdout.
-
-fence_check returns:
-
-0 - if execution completes
-1 - on generic execution errors (fatal)
-2 - if cman is not running (fatal)
-3 - node is not quorate/node is not part of fence domain/if node is not in charge of fencing/a real fencing operation is in progress (can be overridden)
-4 - if another \fBfence_check\fP is in progress (fatal)
-5 - if any of the fence status tests failed
diff --git a/fence/man/fence_node.8 b/fence/man/fence_node.8
deleted file mode 100644
index fe26198..0000000
--- a/fence/man/fence_node.8
+++ /dev/null
@@ -1,127 +0,0 @@
-.TH FENCE_NODE 8 2009-12-21 cluster cluster
-
-.SH NAME
-fence_node \- a utility to run fence agents
-
-.SH SYNOPSIS
-.B fence_node
-[OPTIONS]
-.I nodename
-
-.SH DESCRIPTION
-This utility runs a fence agent against
-.IR nodename .
-The agent and args are taken from the running cluster configuration based on
-.BR cluster.conf (5).
-
-.P
-.B fence_node
-is a wrapper around the libfence functions: fence_node() and unfence_node().
-These libfence functions use libccs to read the node fencing configuration,
-which means that corosync (with cman and ccs) must be running to use
-.BR fence_node (8).
-
-.P
-The
-.BR fenced (8)
-daemon is the main user of libfence:fence_node(), and the
-configuration details for that function are given in the
-.BR fenced (8)
-man page.
-
-.SS Fencing vs. Unfencing
-
-The main use for unfencing is with storage/SAN (non-power) agents.
-
-.P
-When using power-based fencing agents, the fencing action itself is
-supposed to turn a node back on after first turning the power off (this happens
-automatically with a "reboot" action, and needs to be configured
-explicitly as "off" + "on" otherwise.)
-
-.P
-When using storage-based fencing agents, the fencing action is not allowed
-to re-enable a node after disabling it. Re-enabling a fenced node is only
-safe once the node has been rebooted. A natural way to re-enable a fenced
-node's access to storage, is for that node to re-enable the access itself
-during its startup process. The cman init script calls fence_node -U
-(nodename defaults to local nodename when unfencing). Unfencing a node
-without an <unfence> configuration (see below) is a no-op.
-
-.P
-The basic differences between fencing and unfencing:
-.P
-.BR Fencing
-.IP 1. 3
-libfence: fence_node(), command line: fence_node nodename
-.IP 2. 3
-Turns off or disables a node.
-.IP 3. 3
-Agents run with the default action of "off", "disable" or "reboot".
-.IP 4. 3
-Performed by a cluster node against another node that fails (by the fenced daemon).
-.P
-.BR Unfencing
-.IP 1. 3
-libfence: unfence_node(), command line: fence_node -U nodename
-.IP 2. 3
-Turns on or enables a node.
-.IP 3. 3
-Agents run with the explicit action of "on" or "enable".
-.IP 4. 3
-Performed by a cluster node "against" itself during startup (by the cman init script).
-
-.SH OPTIONS
-.TP
-.B \-U
-Unfence the node, default local node name.
-.TP
-.B \-v
-Show fence agent results, \-vv to also show agent args.
-.TP
-.B \-h
-Print a help message describing available options, then exit.
-.TP
-.B \-V
-Print program version information, then exit.
-
-.SH FILES
-
-The Unfencing/unfence_node() configuration is very similar to the
-Fencing/fence_node() configuration shown in
-.BR fenced (8).
-Unfencing is only performed for a node with an <unfence> section:
-
-.nf
-<clusternode name="node1" nodeid="1">
- <fence>
- </fence>
- <unfence>
- </unfence>
-</clusternode>
-.fi
-
-The <unfence> section does not contain <method> sections like the <fence>
-section does. It contains <device> references directly, which mirror the
-corresponding device sections for <fence>, with the notable addition of
-the explicit action of "on" or "enable". The same <fencedevice> is
-referenced by both fence and unfence <device> lines, and the same per-node
-args should be repeated.
-
-.nf
-<clusternode name="node1" nodeid="1">
- <fence>
- <method name="1">
- <device name="myswitch" foo="x"/>
- </method>
- </fence>
-
- <unfence>
- <device name="myswitch" foo="x" action="on"/>
- </unfence>
-</clusternode>
-.fi
-
-.SH SEE ALSO
-.BR fenced (8)
-
diff --git a/fence/man/fence_tool.8 b/fence/man/fence_tool.8
deleted file mode 100644
index 237745d..0000000
--- a/fence/man/fence_tool.8
+++ /dev/null
@@ -1,60 +0,0 @@
-.TH FENCE_TOOL 8 2009-12-21 cluster cluster
-
-.SH NAME
-fence_tool \- a utility for the fenced daemon
-
-.SH SYNOPSIS
-.B fence_tool
-[COMMAND] [OPTIONS]
-
-.SH DESCRIPTION
-This utility controls and queries the
-.BR fenced (8)
-daemon with the following commands:
-.TP
-.B join
-join the fence domain.
-.TP
-.B leave
-leave the fence domain.
-.TP
-.B dump
-print the fenced internal debug buffer ont stdout.
-.TP
-.B ls
-display internal fenced state.
-.P
-The leave command will not be sent to fenced if fence_tool detects that
-any instances of gfs or dlm are in use.
-
-.SH OPTIONS
-.TP
-.B \-n
-Show all node information in ls.
-.TP
-.BI \-t " seconds"
-Retry cman connection for this many seconds.
-0 none, -1 indefinite. Default 0.
-.TP
-.BI \-q " seconds"
-Delay join up to this many seconds for the cluster to have quorum.
-0 none, -1 indefinite. Default 0.
-.TP
-.BI \-m " seconds"
-Delay join up to this many seconds for all nodes in cluster.conf to be
-cluster members.
-0 none, -1 indefinite. Default 0.
-.TP
-.BI \-w " seconds"
-Wait up to this many seconds for the result of join or leave.
-0 none, -1 indefinite. Default 0.
-.TP
-.B \-h
-Print a help message describing available options, then exit.
-.TP
-.B \-V
-Print program version information, then exit.
-
-.SH SEE ALSO
-.BR fenced (8)
-
diff --git a/fence/man/fenced.8 b/fence/man/fenced.8
deleted file mode 100644
index b172151..0000000
--- a/fence/man/fenced.8
+++ /dev/null
@@ -1,353 +0,0 @@
-.TH FENCED 8 2009-12-21 cluster cluster
-
-.SH NAME
-fenced \- the I/O Fencing daemon
-
-.SH SYNOPSIS
-.B fenced
-[OPTIONS]
-
-.SH DESCRIPTION
-The fencing daemon, fenced, fences cluster nodes that have failed.
-Fencing a node generally means rebooting it or otherwise preventing it
-from writing to storage, e.g. disabling its port on a SAN switch. Fencing
-involves interacting with a hardware device, e.g. network power switch,
-SAN switch, storage array. Different "fencing agents" are run by fenced
-to interact with various hardware devices.
-
-Software related to sharing storage among nodes in a cluster, e.g. GFS,
-usually requires fencing to be configured to prevent corruption of the
-storage in the presence of node failure and recovery. GFS will not allow
-a node to mount a GFS file system unless the node is running fenced.
-
-Once started, fenced waits for the
-.BR fence_tool (8)
-join command to be run, telling it to join the fence domain: a group of
-nodes that will fence group members that fail. When the cluster does not
-have quorum, fencing operations are postponed until quorum is restored.
-If a failed fence domain member is reset and rejoins the cluster before
-the remaining domain members have fenced it, the fencing is no longer
-needed and will be skipped.
-
-fenced uses the corosync cluster membership system, it's closed process
-group library (libcpg), and the cman quorum and configuration libraries
-(libcman, libccs).
-
-The cman init script usually starts the fenced daemon and runs fence_tool
-join and leave.
-
-.SS Node failure
-
-When a fence domain member fails, fenced runs an agent to fence it. The
-specific agent to run and the agent parameters are all read from the
-cluster.conf file (using libccs) at the time of fencing. The fencing
-operation against a failed node is not considered complete until the
-exec'ed agent exits. The exit value of the agent indicates the success or
-failure of the operation. If the operation failed, fenced will retry
-(possibly with a different agent, depending on the configuration) until
-fencing succeeds. Other systems such as DLM and GFS wait for fencing to
-complete before starting their own recovery for a failed node.
-Information about fencing operations will also appear in syslog.
-
-When a domain member fails, the actual fencing operation can be delayed by
-a configurable number of seconds (cluster.conf post_fail_delay or -f).
-Within this time, the failed node could be reset and rejoin the cluster to
-avoid being fenced. This delay is 0 by default to minimize the time that
-other systems are blocked.
-
-.SS Domain startup
-
-When the fence domain is first created in the cluster (by the first node
-to join it) and subsequently enabled (by the cluster gaining quorum) any
-nodes listed in cluster.conf that are not presently members of the
-corosync cluster are fenced. The status of these nodes is unknown, and to
-be safe they are assumed to need fencing. This startup fencing can be
-disabled, but it's only truly safe to do so if an operator is present to
-verify that no cluster nodes are in need of fencing.
-
-The following example illustrates why startup fencing is important. Take
-a three node cluster with nodes A, B and C; all three have a GFS file
-system mounted. All three nodes experience a low-level kernel hang at
-about the same time. A watchdog triggers a reboot on nodes A and B, but
-not C. A and B reboot, form the cluster again, gain quorum, join the
-fence domain, _don't_ fence node C which is still hung and unresponsive,
-and mount the GFS fs again. If C were to come back to life, it could
-corrupt the fs. So, A and B need to fence C when they reform the fence
-domain since they don't know the state of C. If C _had_ been reset by a
-watchdog like A and B, but was just slow in rebooting, then A and B might
-be fencing C unnecessarily when they do startup fencing.
-
-The first way to avoid fencing nodes unnecessarily on startup is to ensure
-that all nodes have joined the cluster before any of the nodes start the
-fence daemon. This method is difficult to automate.
-
-A second way to avoid fencing nodes unnecessarily on startup is using the
-cluster.conf post_join_delay setting (or -j option). This is the number
-of seconds fenced will delay before actually fencing any victims after
-nodes join the domain. This delay gives nodes that have been tagged for
-fencing a chance to join the cluster and avoid being fenced. A delay of
--1 here will cause the daemon to wait indefinitely for all nodes to join
-the cluster and no nodes will actually be fenced on startup.
-
-To disable fencing at domain-creation time entirely, the cluster.conf
-clean_start setting (or -c option) can be used to declare that all nodes
-are in a clean or safe state to start. This setting/option should not
-generally be used since it risks not fencing a node that needs it, which
-can lead to corruption in other applications (like GFS) that depend on
-fencing.
-
-Avoiding unnecessary fencing at startup is primarily a concern when nodes
-are fenced by power cycling. If nodes are fenced by disabling their SAN
-access, then unnecessarily fencing a node is usually less disruptive.
-
-.SS Fencing override
-
-If a fencing device fails, the agent may repeatedly return errors as
-fenced tries to fence a failed node. In this case, the admin can manually
-reset the failed node, and then use
-.BR fence_ack_manual (8)
-to tell fenced to continue without fencing the node.
-
-.SH OPTIONS
-Command line options override a corresponding setting in cluster.conf.
-
-.TP
-.B \-D
-Enable debugging to stderr and don't fork.
-.br
-See also
-.B fence_tool dump
-in
-.BR fence_tool (8).
-.TP
-.B \-L
-Enable debugging to log file.
-.br
-See also
-.B logging
-in
-.BR cluster.conf (5).
-.TP
-.BI \-g " num"
-groupd compatibility mode, 0 off, 1 on. Default 0.
-.TP
-.BI \-r " path"
-Register a directory that needs to be empty for the daemon to start. Use
-a dash (\-) to skip default directories /sys/fs/gfs, /sys/fs/gfs2,
-/sys/kernel/dlm.
-.TP
-.B \-c
-All nodes are in a clean state to start. Do no startup fencing.
-.TP
-.B \-s
-Skip startup fencing of nodes with no defined fence methods.
-.TP
-.B \-q
-Disable dbus signals.
-.TP
-.BI \-j " secs"
-Post-join fencing delay. Default 6.
-.TP
-.BI \-f " secs"
-Post-fail fencing delay. Default 0.
-.TP
-.BI \-R " secs"
-Number of seconds to wait for a manual override after a failed fencing
-attempt before the next attempt. Default 3.
-.TP
-.BI \-O " path"
-Location of a FIFO used for communication between fenced and fence_ack_manual.
-.TP
-.B \-h
-Print a help message describing available options, then exit.
-.TP
-.B \-V
-Print program version information, then exit.
-
-.SH FILES
-.BR cluster.conf (5)
-is usually located at /etc/cluster/cluster.conf. It is not read directly.
-Other cluster components load the contents into memory, and the values are
-accessed through the libccs library.
-
-Configuration options for fenced are added to the <fence_daemon /> section
-of cluster.conf, within the top level <cluster> section.
-
-.TP
-.B post_join_delay
-is the number of seconds the daemon will wait before fencing any victims
-after a node joins the domain. Default 6.
-
-<fence_daemon post_join_delay="6"/>
-
-.TP
-.B post_fail_delay
-is the number of seconds the daemon will wait before fencing any victims
-after a domain member fails. Default 0.
-
-<fence_daemon post_fail_delay="0"/>
-
-.TP
-.B clean_start
-is used to prevent any startup fencing the daemon might do.
-It indicates that the daemon should assume all nodes are in a clean state
-to start. Default 0.
-
-<fence_daemon clean_start="0"/>
-
-.TP
-.B override_path
-is the location of a FIFO used for communication between fenced and
-fence_ack_manual. Default shown.
-
-<fence_daemon override_path="/var/run/cluster/fenced_override"/>
-
-.TP
-.B override_time
-is the number of seconds to wait for administrator intervention
-between fencing attempts following fence agent failures. Default 3.
-
-<fence_daemon override_time="3"/>
-
-.SS Per-node fencing settings
-
-The per-node fencing configuration is partly dependant on the specific
-agent/hardware being used. The general framework begins like this:
-
-.nf
-<clusternodes>
-
-<clusternode name="node1" nodeid="1">
- <fence>
- </fence>
-</clusternode>
-
-<clusternode name="node2" nodeid="2">
- <fence>
- </fence>
-</clusternode>
-
-</clusternodes>
-.fi
-
-The simple fragment above is a valid configuration: there is no way to
-fence these nodes. If one of these nodes is in the fence domain and
-fails, fenced will repeatedly fail in its attempts to fence it. The admin
-will need to manually reset the failed node and then use fence_ack_manual
-to tell fenced to continue without fencing it (see override above).
-
-There is typically a single method used to fence each node (the name given
-to the method is not significant). A method refers to a specific device
-listed in the separate <fencedevices> section, and then lists any
-node-specific parameters related to using the device.
-
-.nf
-<clusternodes>
-
-<clusternode name="node1" nodeid="1">
- <fence>
- <method name="1">
- <device name="myswitch" foo="x"/>
- </method>
- </fence>
-</clusternode>
-
-<clusternode name="node2" nodeid="2">
- <fence>
- <method name="1">
- <device name="myswitch" foo="y"/>
- </method>
- </fence>
-</clusternode>
-
-</clusternodes>
-.fi
-
-.SS Fence device settings
-
-This section defines properties of the devices used to fence nodes. There
-may be one or more devices listed. The per-node fencing sections above
-reference one of these fence devices by name.
-
-.nf
-<fencedevices>
- <fencedevice name="myswitch" agent="..." something="..."/>
-</fencedevices>
-.fi
-
-.SS Multiple methods for a node
-
-In more advanced configurations, multiple fencing methods can be defined
-for a node. If fencing fails using the first method, fenced will try the
-next method, and continue to cycle through methods until one succeeds.
-
-.nf
-<clusternode name="node1" nodeid="1">
- <fence>
- <method name="1">
- <device name="myswitch" foo="x"/>
- </method>
- <method name="2">
- <device name="another" bar="123"/>
- </method>
- </fence>
-</clusternode>
-
-<fencedevices>
- <fencedevice name="myswitch" agent="..." something="..."/>
- <fencedevice name="another" agent="..."/>
-</fencedevices>
-.fi
-
-.SS Dual path, redundant power
-
-Sometimes fencing a node requires disabling two power ports or two i/o
-paths. This is done by specifying two or more devices within a method.
-fenced will run the agent for the device twice, once for each device line,
-and both must succeed for fencing to be considered successful.
-
-.nf
-<clusternode name="node1" nodeid="1">
- <fence>
- <method name="1">
- <device name="sanswitch1" port="11"/>
- <device name="sanswitch2" port="11"/>
- </method>
- </fence>
-</clusternode>
-.fi
-
-When using power switches to fence nodes with dual power supplies, the
-agents must be told to turn off both power ports before restoring power to
-either port. The default off-on behavior of the agent could result in the
-power never being fully disabled to the node.
-
-.nf
-<clusternode name="node1" nodeid="1">
- <fence>
- <method name="1">
- <device name="nps1" port="11" action="off"/>
- <device name="nps2" port="11" action="off"/>
- <device name="nps1" port="11" action="on"/>
- <device name="nps2" port="11" action="on"/>
- </method>
- </fence>
-</clusternode>
-.fi
-
-.SS NOTES
-
-Due to a limitation in XML/DTD validation, the name="" value within
-the device or fencedevice section cannot start with a number.
-
-.SS Hardware-specific settings
-
-Find documentation for configuring specific devices from the device
-agent's man page.
-
-.SH SEE ALSO
-.BR fence_tool (8),
-.BR fence_ack_manual (8),
-.BR fence_node (8),
-.BR cluster.conf (5)
-
diff --git a/group/Makefile b/group/Makefile
deleted file mode 100644
index 6a7cecf..0000000
--- a/group/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS = lib dlm_controld tool daemon man
diff --git a/group/daemon/Makefile b/group/daemon/Makefile
deleted file mode 100644
index b1a98c5..0000000
--- a/group/daemon/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-TARGET= groupd
-
-SBINDIRT=$(TARGET)
-
-all: ${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= app.o \
- cpg.o \
- cman.o \
- joinleave.o \
- main.o \
- logging.o
-
-CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${logtincdir} -I${corosyncincdir}
-CFLAGS += -I$(S) -I$(S)/../include/ -I$(S)/../lib/
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${ccslibdir} -lccs
-LDFLAGS += -L${cmanlibdir} -lcman
-LDFLAGS += -L${logtlibdir} -llogthread
-LDFLAGS += -L${corosynclibdir} -lcpg -lpthread
-LDFLAGS += -L${libdir}
-
-${TARGET}: ${OBJS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-clean: generalclean
-
--include $(OBJS:.o=.Tpo)
diff --git a/group/daemon/app.c b/group/daemon/app.c
deleted file mode 100644
index 702b56a..0000000
--- a/group/daemon/app.c
+++ /dev/null
@@ -1,1846 +0,0 @@
-
-/* Apply queued events to apps */
-
-#include "gd_internal.h"
-
-struct list_head recovery_sets;
-
-struct nodeid {
- struct list_head list;
- int nodeid;
-};
-
-const char *msg_type(int type)
-{
- switch (type) {
- case MSG_APP_STOPPED:
- return "stopped";
- case MSG_APP_STARTED:
- return "started";
- case MSG_APP_RECOVER:
- return "recover";
- case MSG_APP_INTERNAL:
- return "internal";
- case MSG_GLOBAL_ID:
- return "global_id";
- }
- return "unknown";
-}
-
-void msg_bswap_out(msg_t *msg)
-{
- msg->ms_version[0] = cpu_to_le32(MSG_VER_MAJOR);
- msg->ms_version[1] = cpu_to_le32(MSG_VER_MINOR);
- msg->ms_version[2] = cpu_to_le32(MSG_VER_PATCH);
- msg->ms_type = cpu_to_le16(msg->ms_type);
- msg->ms_level = cpu_to_le16(msg->ms_level);
- msg->ms_length = cpu_to_le32(msg->ms_length);
- msg->ms_global_id = cpu_to_le32(msg->ms_global_id);
- msg->ms_event_id = cpu_to_le64(msg->ms_event_id);
-}
-
-void msg_bswap_in(msg_t *msg)
-{
- msg->ms_version[0] = le32_to_cpu(MSG_VER_MAJOR);
- msg->ms_version[1] = le32_to_cpu(MSG_VER_MINOR);
- msg->ms_version[2] = le32_to_cpu(MSG_VER_PATCH);
- msg->ms_type = le16_to_cpu(msg->ms_type);
- msg->ms_level = le16_to_cpu(msg->ms_level);
- msg->ms_length = le32_to_cpu(msg->ms_length);
- msg->ms_global_id = le32_to_cpu(msg->ms_global_id);
- msg->ms_event_id = le64_to_cpu(msg->ms_event_id);
-}
-
-static uint64_t make_event_id(group_t *g, int state, int nodeid)
-{
- uint64_t id;
- uint32_t n = nodeid;
- uint32_t memb_count = g->memb_count;
- uint16_t type = 0;
-
- if (state == EST_JOIN_BEGIN)
- type = 1;
- else if (state == EST_LEAVE_BEGIN)
- type = 2;
- else if (state == EST_FAIL_BEGIN)
- type = 3;
- else
- log_error(g, "make_event_id invalid state %d", state);
-
- id = n;
- id = id << 32;
- memb_count = memb_count << 16;
- id = id | memb_count;
- id = id | type;
-
- log_group(g, "make_event_id %llx nodeid %d memb_count %d type %u",
- (unsigned long long)id, nodeid, g->memb_count, type);
-
- return id;
-}
-
-static void free_event(event_t *ev)
-{
- struct nodeid *id, *id_safe;
-
- list_for_each_entry_safe(id, id_safe, &ev->extended, list) {
- list_del(&id->list);
- free(id);
- }
- free(ev);
-}
-
-static int event_id_to_nodeid(uint64_t id)
-{
- int nodeid;
- uint64_t n = id >> 32;
- nodeid = n & 0xFFFFFFFF;
- return nodeid;
-}
-
-static int event_id_to_type(uint64_t id)
-{
- uint64_t n;
- n = id & 0x000000000000FFFF;
- return ((int) n);
-}
-
-/*
- * Free queued message if:
- * - the id indicates a join for node X and X is a member
- * - the id indicates a leave for node X and X is not a member
- *
- * Note sure if all these cases are relevant, currently we only
- * purge messages after we join.
- */
-
-static void purge_messages(group_t *g)
-{
- struct save_msg *save, *tmp;
- node_t *node;
- int nodeid, type;
- const char *state_str;
-
- list_for_each_entry_safe(save, tmp, &g->messages, list) {
- if (save->msg.ms_type == MSG_APP_INTERNAL)
- continue;
-
- nodeid = event_id_to_nodeid(save->msg.ms_event_id);
- type = event_id_to_type(save->msg.ms_event_id);
- node = find_app_node(g->app, nodeid);
-
- if ((type == 1 && node) || (type != 1 && !node) ||
- (save->msg.ms_type == MSG_APP_RECOVER)) {
-
- if (save->msg.ms_type == MSG_APP_RECOVER)
- state_str = "MSG_APP_RECOVER";
- else if (type == 1)
- state_str = "EST_JOIN_BEGIN";
- else if (type == 2)
- state_str = "EST_LEAVE_BEGIN";
- else if (type == 3)
- state_str = "EST_FAIL_BEGIN";
- else
- state_str = "error";
-
- log_group(g, "purge msg %llx from %d %s",
- (unsigned long long)save->msg.ms_event_id,
- nodeid, state_str);
-
- list_del(&save->list);
- if (save->msg_long)
- free(save->msg_long);
- free(save);
- }
- }
-}
-
-/* For a recovery event where multiple nodes have failed, the event id
- is based on the lowest nodeid of all the failed nodes. The event
- id is also based on the number of remaining group members which
- changes as failed nodes are added to the recovery event. */
-
-void extend_recover_event(group_t *g, event_t *ev, int nodeid)
-{
- struct nodeid *id;
- int new_id_nodeid = nodeid;
-
- log_group(g, "extend_recover_event for %d with node %d",
- ev->nodeid, nodeid);
-
- /* the lowest nodeid in a recovery event is kept in ev->nodeid,
- the other nodeid's are kept in the extended list */
-
- if (nodeid < ev->nodeid) {
- new_id_nodeid = ev->nodeid;
- ev->nodeid = nodeid;
- ev->id = make_event_id(g, EST_FAIL_BEGIN, nodeid);
- }
-
- id = malloc(sizeof(struct nodeid));
- // FIXME: handle failed malloc
- id->nodeid = new_id_nodeid;
- list_add(&id->list, &ev->extended);
-}
-
-struct recovery_set *get_recovery_set(int nodeid)
-{
- struct recovery_set *rs;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- if (rs->nodeid == nodeid)
- return rs;
- }
-
- rs = malloc(sizeof(*rs));
- ASSERT(rs);
- memset(rs, 0, sizeof(struct recovery_set));
- rs->nodeid = nodeid;
- rs->cman_update = 0;
- rs->cpg_update = 0;
- INIT_LIST_HEAD(&rs->entries);
-
- list_add_tail(&rs->list, &recovery_sets);
-
- return rs;
-}
-
-/* When a node fails, all the groups that that node was in are tracked by
- one of these recovery_sets. These are the groups that will need layered
- recovery, i.e. all effected groups must be completely stopped (the app
- stopped on all nodes) before any are restarted. When restarted, the groups
- must be restarted in order from lowest level first. All groups on each
- level must complete recovery (on all nodes) before recovery can begin for
- the next level. */
-
-/* FIXME: do we need to worry about the case where we get an
- add_recovery_set_cman() that finds an old rs, the old rs completes
- and goes away, and then we get the add_recovery_set_cpg() matching
- the _cman() variant that we ignored? */
-
-void add_recovery_set_cman(int nodeid)
-{
- struct recovery_set *rs;
-
- log_debug("add_recovery_set_cman nodeid %d", nodeid);
-
- rs = get_recovery_set(nodeid);
- if (rs->cman_update) {
- log_debug("old recovery for %d still in progress", nodeid);
- return;
- }
- rs->cman_update = 1;
-
- if (!rs->cpg_update && !in_groupd_cpg(nodeid)) {
- log_debug("free recovery set %d not running groupd", nodeid);
- list_del(&rs->list);
- free(rs);
- return;
- }
-
- if (list_empty(&rs->entries) && rs->cpg_update) {
- log_debug("free unused recovery set %d cman", nodeid);
- list_del(&rs->list);
- free(rs);
- }
-}
-
-/* procdown of 1 means the groupd daemon process exited, but the node didn't
- fail. when only the process fails, we won't get a cman callback which is
- only for nodedown. if the node wasn't in any groups we don't add a recovery
- set and don't care about the exited groupd; if the node with the failed
- groupd _was_ in any groups, we add a rs and process_groupd_confchg() will do
- cman_kill_node() to make the node really fail (and we'll get an
- add_recovery_set_cman()). */
-
-struct recovery_set *add_recovery_set_cpg(int nodeid, int procdown)
-{
- struct recovery_set *rs;
- struct recovery_entry *re;
- group_t *g;
- node_t *node;
-
- log_debug("add_recovery_set_cpg nodeid %d procdown %d",
- nodeid, procdown);
-
- rs = get_recovery_set(nodeid);
- if (rs->cpg_update) {
- log_debug("old recovery for %d still in progress", nodeid);
- return rs;
- }
- rs->cpg_update = 1;
-
- list_for_each_entry(g, &gd_groups, list) {
- list_for_each_entry(node, &g->app->nodes, list) {
- if (node->nodeid == nodeid) {
- log_group(g, "add to recovery set %d", nodeid);
- re = malloc(sizeof(*re));
- // FIXME: handle failed malloc
- memset(re, 0, sizeof(struct recovery_entry));
- re->group = g;
- list_add_tail(&re->list, &rs->entries);
- break;
- }
- }
- }
-
- if (list_empty(&rs->entries)) {
- if (rs->cman_update || procdown) {
- log_debug("free unused recovery set %d cpg", nodeid);
- list_del(&rs->list);
- free(rs);
- return NULL;
- }
- }
-
- return rs;
-}
-
-static void _del_recovery_set(group_t *g, int nodeid, int purge)
-{
- struct recovery_set *rs, *rs2;
- struct recovery_entry *re, *re2;
- int found = 0, entries_not_recovered;
-
- list_for_each_entry_safe(rs, rs2, &recovery_sets, list) {
- if (rs->nodeid != nodeid)
- continue;
-
- entries_not_recovered = 0;
-
- list_for_each_entry_safe(re, re2, &rs->entries, list) {
- if (re->group == g) {
- if (purge) {
- list_del(&re->list);
- free(re);
- log_group(g, "purged from rs %d",
- rs->nodeid);
- } else {
- re->recovered = 1;
- log_group(g, "done in recovery set %d",
- rs->nodeid);
- found++;
- }
- } else {
- if (re->recovered == 0)
- entries_not_recovered++;
- }
- }
-
- if (entries_not_recovered) {
- log_debug("recovery set %d has %d entries not done",
- rs->nodeid, entries_not_recovered);
- continue;
- }
-
- /* all entries in this rs are recovered, free it */
- log_debug("recovery set %d is all done", rs->nodeid);
-
- list_for_each_entry_safe(re, re2, &rs->entries, list) {
- list_del(&re->list);
- free(re);
- }
- list_del(&rs->list);
- free(rs);
- }
-
- if (!found)
- log_group(g, "not found in any recovery sets for %d", nodeid);
-}
-
-/* A group has finished recovery for given event (which can encompass more than
- one failed nodeid). Remove this group from recovery sets for those nodeids
- and free any recovery sets that are now completed. */
-
-static void del_recovery_set(group_t *g, event_t *ev, int purge)
-{
- struct nodeid *id;
-
- log_group(g, "rev %llx done, remove group from rs %d",
- (unsigned long long)ev->id, ev->nodeid);
- _del_recovery_set(g, ev->nodeid, purge);
-
- list_for_each_entry(id, &ev->extended, list) {
- log_group(g, "rev %llx done, remove group from rs %d",
- (unsigned long long)ev->id, id->nodeid);
- _del_recovery_set(g, id->nodeid, purge);
- }
-}
-
-/* go through all recovery sets and check that all failed nodes have
- been removed by cman callbacks; if they haven't then cman may be
- inquorate and we just haven't gotten the cman callback yet that
- will set cman_quorate = 0 [group recoveries are driven by cpg
- callbacks, not cman callbacks, so that's why we might be trying
- to do recovery without having heard from cman yet.] */
-
-static int cman_quorum_updated(void)
-{
- struct recovery_set *rs;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- if (rs->cman_update)
- continue;
- log_debug("no cman update for recovery_set %d quorate %d",
- rs->nodeid, cman_quorate);
- return 0;
- }
- return 1;
-}
-
-static int is_recovery_event(event_t *ev)
-{
- if (event_id_to_type(ev->id) == 3)
- return 1;
- return 0;
-}
-
-/* all groups referenced by a recovery set are stopped on all nodes,
- and stopped for recovery */
-
-static int set_is_all_stopped(struct recovery_set *rs, event_t *rev)
-{
- struct recovery_entry *re;
- event_t *ev;
-
- list_for_each_entry(re, &rs->entries, list) {
- ev = re->group->app->current_event;
-
- /* we need to use ev->fail_all_stopped instead of checking
- ev->state == FAIL_ALL_STOPPED because if two groups are at
- the low level, one will detect all_levels_all_stopped first
- and then immediately move on to starting before the other,
- also checking all_levels_all_stopped, can see it's in
- FAIL_ALL_STOPPED */
-
- if (ev && is_recovery_event(ev) && ev->fail_all_stopped)
- continue;
- else
- return 0;
- }
- return 1;
-}
-
-/* for every recovery set that this group is in, are all other groups in
- each of those sets in the "all stopped" state for recovery? */
-
-static int all_levels_all_stopped(group_t *g, event_t *rev)
-{
- struct recovery_set *rs;
- struct recovery_entry *re;
- int found = 0;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- list_for_each_entry(re, &rs->entries, list) {
- if (re->group == g) {
- found = 1;
- if (set_is_all_stopped(rs, rev))
- break;
- else
- return 0;
- }
- }
- }
-
- if (!found)
- return 0;
- return 1;
-}
-
-#if 0
-void dump_recovery_sets(void)
-{
- struct recovery_set *rs;
- struct recovery_entry *re;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- log_debug("recovery_set %d", rs->nodeid);
- list_for_each_entry(re, &rs->entries, list) {
- log_debug(" recovery_entry %d:%s recovered %d",
- re->group->level, re->group->name,
- re->recovered);
- }
- }
-}
-#endif
-
-static int group_in_recovery_set(struct recovery_set *rs, group_t *g)
-{
- struct recovery_entry *re;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- list_for_each_entry(re, &rs->entries, list) {
- if (re->group == g)
- return 1;
- }
- }
- return 0;
-}
-
-static int rs_lower_levels_recovered(struct recovery_set *rs, int level)
-{
- struct recovery_entry *re;
-
- list_for_each_entry(re, &rs->entries, list) {
- if (re->group->level < level && !re->recovered)
- return 0;
- }
- return 1;
-}
-
-/* lower level groups should be recovered in each rs this group is in */
-
-static int lower_levels_recovered(group_t *g)
-{
- struct recovery_set *rs;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- if (!group_in_recovery_set(rs, g))
- continue;
-
- if (rs_lower_levels_recovered(rs, g->level))
- continue;
-
- log_group(g, "lower levels not recovered in rs %d", rs->nodeid);
- return 0;
- }
- return 1;
-}
-
-/* We're interested in any unrecovered group at a lower level than g, not
- just lower groups in the same recovery set. */
-
-static int lower_groups_need_recovery(group_t *g)
-{
- struct recovery_set *rs;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- if (rs_lower_levels_recovered(rs, g->level))
- continue;
- log_group(g, "lower group not recovered in rs %d", rs->nodeid);
- return 1;
- }
- return 0;
-}
-
-static int level_is_lowest(struct recovery_set *rs, int level)
-{
- struct recovery_entry *re;
-
- list_for_each_entry(re, &rs->entries, list) {
- if (re->group->level < level)
- return 0;
- }
- return 1;
-}
-
-/* this group is at the lowest level in any recovery sets it's in */
-
-static int lowest_level(group_t *g)
-{
- struct recovery_set *rs;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- if (!group_in_recovery_set(rs, g))
- continue;
- if (level_is_lowest(rs, g->level))
- continue;
- return 0;
- }
- return 1;
-}
-
-static event_t *create_event(group_t *g)
-{
- event_t *ev;
-
- ev = malloc(sizeof(event_t));
- ASSERT(ev);
-
- memset(ev, 0, sizeof(event_t));
-
- INIT_LIST_HEAD(&ev->memb);
- INIT_LIST_HEAD(&ev->extended);
- ev->event_nr = ++gd_event_nr;
-
- return ev;
-}
-
-int queue_app_recover(group_t *g, int nodeid)
-{
- event_t *ev;
-
- ev = create_event(g);
- ev->nodeid = nodeid;
- ev->state = EST_FAIL_BEGIN;
- ev->fail_all_stopped = 0;
- ev->id = make_event_id(g, EST_FAIL_BEGIN, nodeid);
-
- log_group(g, "queue recover event for nodeid %d", nodeid);
-
- list_add_tail(&ev->list, &g->app->events);
- return 0;
-}
-
-void del_event_nodes(event_t *ev)
-{
- node_t *node, *n;
-
- list_for_each_entry_safe(node, n, &ev->memb, list) {
- list_del(&node->list);
- free(node);
- }
-}
-
-static void add_event_nodes(group_t *g, event_t *ev)
-{
- node_t *node, *n;
-
- list_for_each_entry(node, &g->memb, list) {
- n = new_node(node->nodeid);
- list_add(&n->list, &ev->memb);
- }
-}
-
-static event_t *search_event(group_t *g, int nodeid)
-{
- event_t *ev;
-
- list_for_each_entry(ev, &g->app->events, list) {
- if (ev->nodeid == nodeid)
- return ev;
- }
- return NULL;
-}
-
-static void dump_queued_events(group_t *g)
-{
- event_t *ev;
-
- list_for_each_entry(ev, &g->app->events, list) {
- log_group(g, " queued ev %d %llx %s",
- ev->nodeid, (unsigned long long)ev->id,
- ev_state_str(ev));
- }
-}
-
-int queue_app_join(group_t *g, int nodeid)
-{
- event_t *ev;
-
- /* sanity check */
- ev = g->app->current_event;
- if (ev && ev->nodeid == nodeid) {
- log_group(g, "queue_app_join: current event %d %llx %s",
- nodeid, (unsigned long long)ev->id, ev_state_str(ev));
- }
-
- /* sanity check */
- ev = search_event(g, nodeid);
- if (ev) {
- log_group(g, "queue_app_join: queued event %d %llx %s",
- nodeid, (unsigned long long)ev->id, ev_state_str(ev));
- }
-
- ev = create_event(g);
- ev->nodeid = nodeid;
- ev->state = EST_JOIN_BEGIN;
- ev->id = make_event_id(g, EST_JOIN_BEGIN, nodeid);
-
- log_group(g, "queue join event for nodeid %d", nodeid);
- dump_queued_events(g);
-
- if (nodeid == our_nodeid)
- add_event_nodes(g, ev);
-
- list_add_tail(&ev->list, &g->app->events);
- return 0;
-}
-
-int queue_app_leave(group_t *g, int nodeid)
-{
- event_t *ev;
-
- /* sanity check */
- ev = g->app->current_event;
- if (ev && ev->nodeid == nodeid) {
- log_group(g, "queue_app_leave: current event %d %llx %s",
- nodeid, (unsigned long long)ev->id, ev_state_str(ev));
- }
-
- /* sanity check */
- ev = search_event(g, nodeid);
- if (ev) {
- log_group(g, "queue_app_leave: queued event %d %llx %s",
- nodeid, (unsigned long long)ev->id, ev_state_str(ev));
- }
-
- ev = create_event(g);
- ev->nodeid = nodeid;
- ev->state = EST_LEAVE_BEGIN;
- ev->id = make_event_id(g, EST_LEAVE_BEGIN, nodeid);
-
- log_group(g, "queue leave event for nodeid %d", nodeid);
- dump_queued_events(g);
-
- list_add_tail(&ev->list, &g->app->events);
- return 0;
-}
-
-int queue_app_message(group_t *g, struct save_msg *save)
-{
- /* log_group(g, "queue message %s from %d",
- msg_type(save->msg.ms_type), save->nodeid); */
- list_add_tail(&save->list, &g->messages);
- return 0;
-}
-
-/* This is called when we get the nodedown for the per-group cpg; we know
- that after the cpg nodedown we won't get any further messages. bz 436984
- It's conceivable but unlikely that the nodedown processing (initiated by
- the groupd cpg nodedown) could begin before the per-group cpg nodedown
- is received where this purging occurs. If it does, then we may need to
- add code to wait for the nodedown to happen in both the groupd cpg and the
- per-group cpg before processing the nodedown. */
-
-void purge_node_messages(group_t *g, int nodeid)
-{
- struct save_msg *save, *tmp;
-
- list_for_each_entry_safe(save, tmp, &g->messages, list) {
- if (save->nodeid != nodeid)
- continue;
-
- log_group(g, "purge msg from dead node %d", nodeid);
-
- list_del(&save->list);
- if (save->msg_long)
- free(save->msg_long);
- free(save);
- }
-}
-
-static void del_app_nodes(app_t *a)
-{
- node_t *node, *tmp;
-
- list_for_each_entry_safe(node, tmp, &a->nodes, list) {
- list_del(&node->list);
- free(node);
- }
-}
-
-node_t *find_app_node(app_t *a, int nodeid)
-{
- node_t *node;
-
- list_for_each_entry(node, &a->nodes, list) {
- if (node->nodeid == nodeid)
- return node;
- }
- return NULL;
-}
-
-int is_our_join(event_t *ev)
-{
- return (ev->nodeid == our_nodeid);
-}
-
-static int is_our_leave(event_t *ev)
-{
- return (ev->nodeid == our_nodeid);
-}
-
-/* Called after all nodes have acked that they're stopped for our
- leave. We get their stopped messages even though we've left the
- cpg because the messages are sent through the groupd cpg.
- groupd_down() will fill in stops for us for nodes that fail before
- sending stopped for our leave. */
-
-static void finalize_our_leave(group_t *g)
-{
- struct recovery_set *rs;
- struct recovery_entry *re, *re2;
- app_t *a = g->app;
-
- log_group(g, "finalize_our_leave");
-
- app_terminate(a);
- cpg_finalize(g->cpg_handle);
- client_dead(g->cpg_client);
- g->app = NULL;
- del_app_nodes(a);
- free(a);
-
- /* this group shouldn't be in any recovery sets... sanity check
- and avoid future segfault by removing re's referencing this g */
-
- list_for_each_entry(rs, &recovery_sets, list) {
- list_for_each_entry_safe(re, re2, &rs->entries, list) {
- if (re->group == g) {
- log_error(g, "finalize: still in recovery "
- "set %d", rs->nodeid);
- list_del(&re->list);
- free(re);
- }
- }
- }
-
- remove_group(g);
-}
-
-static int send_stopped(group_t *g)
-{
- msg_t msg;
- event_t *ev = g->app->current_event;
-
- memset(&msg, 0, sizeof(msg));
- msg.ms_type = MSG_APP_STOPPED;
- msg.ms_global_id = g->global_id;
- msg.ms_event_id = ev->id;
- msg.ms_level = g->level;
- memcpy(&msg.ms_name, &g->name, MAX_NAMELEN);
-
- msg_bswap_out(&msg);
-
- log_group(g, "send stopped");
- return send_message_groupd(g, &msg, sizeof(msg), MSG_APP_STOPPED);
-}
-
-static int send_started(group_t *g)
-{
- msg_t msg;
- event_t *ev = g->app->current_event;
-
- memset(&msg, 0, sizeof(msg));
- msg.ms_type = MSG_APP_STARTED;
- msg.ms_global_id = g->global_id;
- msg.ms_event_id = ev->id;
- msg.ms_level = g->level;
- memcpy(&msg.ms_name, &g->name, MAX_NAMELEN);
-
- msg_bswap_out(&msg);
-
- log_group(g, "send started");
- return send_message_groupd(g, &msg, sizeof(msg), MSG_APP_STARTED);
-}
-
-static int send_recover(group_t *g, event_t *rev)
-{
- msg_t msg;
-
- memset(&msg, 0, sizeof(msg));
- msg.ms_type = MSG_APP_RECOVER;
- msg.ms_global_id = g->global_id;
- msg.ms_event_id = rev->id;
- msg.ms_level = g->level;
- memcpy(&msg.ms_name, &g->name, MAX_NAMELEN);
-
- msg_bswap_out(&msg);
-
- log_group(g, "send recover");
- return send_message_groupd(g, &msg, sizeof(msg), MSG_APP_RECOVER);
-}
-
-int do_stopdone(char *name, int level)
-{
- group_t *g;
- g = find_group_level(name, level);
- return send_stopped(g);
-}
-
-int do_startdone(char *name, int level, int event_nr)
-{
- group_t *g;
- event_t *ev;
- const char *state;
-
- g = find_group_level(name, level);
- if (!g) {
- log_print("do_startdone: no group level %d name %s",
- level, name);
- return -1;
- }
-
- ev = g->app->current_event;
-
- state = ev ? ev_state_str(ev) : "no-event";
-
- if (!ev || ev->event_nr != event_nr) {
- log_group(g, "ignore startdone %d state %s", event_nr, state);
- return 0;
- }
-
- if (!event_state_starting(g->app)) {
- log_error(g, "IGNORE startdone %d state %s", event_nr, state);
- return 0;
- }
-
- return send_started(g);
-}
-
-const char *ev_state_str(event_t *ev)
-{
- switch (ev->state) {
- case EST_JOIN_BEGIN:
- return "JOIN_BEGIN";
- case EST_JOIN_STOP_WAIT:
- return "JOIN_STOP_WAIT";
- case EST_JOIN_ALL_STOPPED:
- return "JOIN_ALL_STOPPED";
- case EST_JOIN_START_WAIT:
- return "JOIN_START_WAIT";
- case EST_JOIN_ALL_STARTED:
- return "JOIN_ALL_STARTED";
- case EST_LEAVE_BEGIN:
- return "LEAVE_BEGIN";
- case EST_LEAVE_STOP_WAIT:
- return "LEAVE_STOP_WAIT";
- case EST_LEAVE_ALL_STOPPED:
- return "LEAVE_ALL_STOPPED";
- case EST_LEAVE_START_WAIT:
- return "LEAVE_START_WAIT";
- case EST_LEAVE_ALL_STARTED:
- return "LEAVE_ALL_STARTED";
- case EST_FAIL_BEGIN:
- return "FAIL_BEGIN";
- case EST_FAIL_STOP_WAIT:
- return "FAIL_STOP_WAIT";
- case EST_FAIL_ALL_STOPPED:
- return "FAIL_ALL_STOPPED";
- case EST_FAIL_START_WAIT:
- return "FAIL_START_WAIT";
- case EST_FAIL_ALL_STARTED:
- return "FAIL_ALL_STARTED";
- default:
- return "unknown";
- }
-}
-
-static int count_nodes_not_stopped(app_t *a)
-{
- node_t *node;
- int i = 0;
-
- list_for_each_entry(node, &a->nodes, list) {
- if (!node->stopped)
- i++;
- }
- return i;
-}
-
-static int event_state_begin(app_t *a)
-{
- if (a->current_event->state == EST_JOIN_BEGIN ||
- a->current_event->state == EST_LEAVE_BEGIN ||
- a->current_event->state == EST_FAIL_BEGIN)
- return TRUE;
- return FALSE;
-}
-
-int event_state_stopping(app_t *a)
-{
- if (a->current_event->state == EST_JOIN_STOP_WAIT ||
- a->current_event->state == EST_LEAVE_STOP_WAIT ||
- a->current_event->state == EST_FAIL_STOP_WAIT)
- return TRUE;
- return FALSE;
-}
-
-int event_state_starting(app_t *a)
-{
- if (a->current_event->state == EST_JOIN_START_WAIT ||
- a->current_event->state == EST_LEAVE_START_WAIT ||
- a->current_event->state == EST_FAIL_START_WAIT)
- return TRUE;
- return FALSE;
-}
-
-#if 0
-int event_state_all_stopped(app_t *a)
-{
- if (a->current_event->state == EST_JOIN_ALL_STOPPED ||
- a->current_event->state == EST_LEAVE_ALL_STOPPED ||
- a->current_event->state == EST_FAIL_ALL_STOPPED)
- return TRUE;
- return FALSE;
-}
-#endif
-
-static int event_state_all_started(app_t *a)
-{
- if (a->current_event->state == EST_JOIN_ALL_STARTED ||
- a->current_event->state == EST_LEAVE_ALL_STARTED ||
- a->current_event->state == EST_FAIL_ALL_STARTED)
- return TRUE;
- return FALSE;
-}
-
-static int process_current_event(group_t *g)
-{
- app_t *a = g->app;
- event_t *ev = a->current_event;
- node_t *node, *n;
- struct nodeid *id;
- int rv = 0, do_start = 0, count;
-
- if (!(event_state_stopping(a) || event_state_starting(a)))
- log_group(g, "process_current_event %llx %d %s",
- (unsigned long long)ev->id, ev->nodeid,
- ev_state_str(ev));
-
- switch (ev->state) {
-
- case EST_JOIN_BEGIN:
- ev->state = EST_JOIN_STOP_WAIT;
-
- if (is_our_join(ev)) {
- /* the initial set of members that we've joined,
- includes us */
-
- list_for_each_entry_safe(node, n, &ev->memb, list) {
- list_move(&node->list, &a->nodes);
- a->node_count++;
- log_group(g, "app node init: add %d total %d",
- node->nodeid, a->node_count);
- }
-
- /* we could have the joining node send out a stopped
- message here for all to receive and count but
- that's unnecessary, we just have everyone
- set the joining node as stopped initially */
-
- node = find_app_node(a, our_nodeid);
- ASSERT(node);
- node->stopped = 1;
-
- /* if we're the first node to be joining, move
- ahead to the JOIN_ALL_STOPPED state */
-
- if (a->node_count == 1)
- ev->state++;
-
- rv = 1;
- } else {
- app_stop(a);
-
- node = new_node(ev->nodeid);
- list_add(&node->list, &a->nodes);
- a->node_count++;
- log_group(g, "app node join: add %d total %d",
- node->nodeid, a->node_count);
- node->stopped = 1;
- }
- break;
-
- case EST_JOIN_STOP_WAIT:
- count = count_nodes_not_stopped(a);
- log_group(g, "waiting for %d more stopped messages "
- "before JOIN_ALL_STOPPED %d", count, ev->nodeid);
- break;
-
- case EST_JOIN_ALL_STOPPED:
- if (!cman_quorate) {
- log_group(g, "wait for quorum before starting app");
- break;
- }
-
- /* We want to move ahead to start here if this ev is to be
- started before a pending rev that will abort it. Once
- started, the rev becomes current and stops the app
- immediately. */
-
- if (lower_groups_need_recovery(g) &&
- !ev->start_app_before_pending_rev) {
- log_group(g, "wait for lower_groups_need_recovery "
- "before starting app");
- break;
- }
- ev->start_app_before_pending_rev = 0;
-
- ev->state = EST_JOIN_START_WAIT;
-
- if (!g->have_set_id) {
- g->have_set_id = 1;
- app_setid(a);
- }
-
- app_start(a);
- break;
-
- case EST_JOIN_ALL_STARTED:
- app_finish(a);
-
- if (is_our_join(ev)) {
- purge_messages(g);
- g->joining = 0;
- }
- free_event(ev);
- a->current_event = NULL;
- rv = 1;
- break;
-
- case EST_LEAVE_BEGIN:
- ev->state = EST_LEAVE_STOP_WAIT;
- app_stop(a);
- break;
-
- case EST_LEAVE_STOP_WAIT:
- count = count_nodes_not_stopped(a);
- log_group(g, "waiting for %d more stopped messages "
- "before LEAVE_ALL_STOPPED %d", count, ev->nodeid);
- break;
-
- case EST_LEAVE_ALL_STOPPED:
- if (is_our_leave(ev)) {
- /* frees group structure */
- finalize_our_leave(g);
- rv = -1;
- break;
- }
- ev->state = EST_LEAVE_START_WAIT;
-
- node = find_app_node(a, ev->nodeid);
- list_del(&node->list);
- a->node_count--;
- log_group(g, "app node leave: del %d total %d",
- node->nodeid, a->node_count);
- free(node);
- app_start(a);
- break;
-
- case EST_LEAVE_ALL_STARTED:
- app_finish(a);
- free_event(ev);
- a->current_event = NULL;
- rv = 1;
- break;
-
- case EST_FAIL_BEGIN:
- ev->state = EST_FAIL_STOP_WAIT;
- app_stop(a);
-
- /* set the failed nodes as stopped since we won't
- be getting a "stopped" message from them. the node
- may already have been removed in the case where one
- rev interrupts another */
-
- node = find_app_node(a, ev->nodeid);
- if (node)
- node->stopped = 1;
-
- /* multiple nodes failed together making an extended event */
- list_for_each_entry(id, &ev->extended, list) {
- node = find_app_node(a, id->nodeid);
- if (node)
- node->stopped = 1;
- }
-
- break;
-
- case EST_FAIL_STOP_WAIT:
- count = count_nodes_not_stopped(a);
- log_group(g, "waiting for %d more stopped messages "
- "before FAIL_ALL_STOPPED %d", count, ev->nodeid);
- break;
-
- case EST_FAIL_ALL_STOPPED:
- ev->fail_all_stopped = 1;
-
- /* when recovering for failed nodes, we immediately stop all
- apps the node was involved with but wait for quorum before
- starting them again */
-
- /* we make sure that cman has updated our quorum status since
- the last node failure */
-
- if (!cman_quorum_updated())
- break;
-
- if (!cman_quorate)
- break;
-
- if (lowest_level(g)) {
- if (all_levels_all_stopped(g, ev)) {
- ev->state = EST_FAIL_START_WAIT;
- do_start = 1;
- } else
- log_group(g, "wait for all_levels_all_stopped");
- } else {
- if (lower_levels_recovered(g)) {
- ev->state = EST_FAIL_START_WAIT;
- do_start = 1;
- } else
- log_group(g, "wait for lower_levels_recovered");
- }
-
- if (!do_start)
- break;
-
- node = find_app_node(a, ev->nodeid);
- if (node) {
- a->node_count--;
- log_group(g, "app node fail: del node %d total %d",
- node->nodeid, a->node_count);
- list_del(&node->list);
- free(node);
- } else
- log_group(g, "app node fail: %d prev removed",
- ev->nodeid);
-
- list_for_each_entry(id, &ev->extended, list) {
- node = find_app_node(a, id->nodeid);
- if (node) {
- a->node_count--;
- log_group(g, "app node fail: del node %d "
- "total %d, ext", node->nodeid,
- a->node_count);
- list_del(&node->list);
- free(node);
- } else
- log_group(g, "app node fail: %d prev removed",
- id->nodeid);
- }
-
- app_start(a);
- break;
-
- case EST_FAIL_ALL_STARTED:
- app_finish(a);
- del_recovery_set(g, ev, 0);
- free_event(ev);
- a->current_event = NULL;
- rv = 1;
- break;
-
- default:
- /*
- log_group(g, "nothing to do: %llx %d %s",
- (unsigned long long)ev->id, ev->nodeid,
- ev_state_str(ev));
- */
- break;
- }
-
- return rv;
-}
-
-static void clear_all_nodes_stopped(app_t *a)
-{
- node_t *node;
- log_group(a->g, "clear_all_nodes_stopped");
- list_for_each_entry(node, &a->nodes, list)
- node->stopped = 0;
-}
-
-static int mark_node_stopped(app_t *a, int nodeid)
-{
- node_t *node;
-
- /* we might get a stopped message from another node who's going
- through X_BEGIN before we get to X_BEGIN ourselves, so we need
- to accept their message if we're in X_BEGIN, too */
-
- if (!event_state_stopping(a) && !event_state_begin(a)) {
- log_error(a->g, "mark_node_stopped: event not stopping/begin: "
- "state %s from %d",
- ev_state_str(a->current_event), nodeid);
- return -1;
- }
-
- node = find_app_node(a, nodeid);
- if (!node) {
- log_error(a->g, "mark_node_stopped: no nodeid %d", nodeid);
- return -1;
- }
-
- log_group(a->g, "mark node %d stopped", nodeid);
-
- node->stopped = 1;
- node->started = 0;
-
- return 0;
-}
-
-static int mark_node_started(app_t *a, int nodeid)
-{
- node_t *node;
-
- if (!event_state_starting(a))
- log_group(a->g, "mark_node_started: event not starting %d "
- "from %d", a->current_event->state, nodeid);
-
- node = find_app_node(a, nodeid);
- if (!node) {
- log_error(a->g, "mark_node_started: no nodeid %d", nodeid);
- return -1;
- }
-
- log_group(a->g, "mark node %d started", nodeid);
-
- node->stopped = 0;
- node->started = 1;
-
- return 0;
-}
-
-static int all_nodes_stopped(app_t *a)
-{
- node_t *node;
-
- list_for_each_entry(node, &a->nodes, list) {
- if (!node->stopped) {
- /* ASSERT(node->started); */
- return FALSE;
- }
- }
- return TRUE;
-}
-
-static int all_nodes_started(app_t *a)
-{
- node_t *node;
-
- list_for_each_entry(node, &a->nodes, list) {
- if (!node->started) {
- /* ASSERT(node->stopped); */
- return FALSE;
- }
- }
- return TRUE;
-}
-
-static int process_app_messages(group_t *g)
-{
- app_t *a = g->app;
- struct save_msg *save, *tmp;
- event_t *ev;
- int rv = 0;
-
- list_for_each_entry_safe(save, tmp, &g->messages, list) {
-
- /* internal messages, sent not by groupd but by apps
- to each other, are delivered to the apps in
- deliver_app_messages() */
-
- if (save->msg.ms_type == MSG_APP_INTERNAL)
- continue;
-
- ev = a->current_event;
-
- if (save->msg.ms_type == MSG_APP_RECOVER) {
- if (ev && ev->state == EST_JOIN_STOP_WAIT &&
- is_our_join(ev)) {
- /* keep this msg around for
- recover_current_event() to see, it will
- be purged later */
- if (!save->print_ignore) {
- log_group(g, "rev %llx taken on node %d",
- (unsigned long long)save->msg.ms_event_id,
- save->nodeid);
- save->print_ignore = 1;
- }
- continue;
- } else {
- goto free_save;
- }
- }
-
-
- if (!ev || ev->id != save->msg.ms_event_id) {
- if (!save->print_ignore) {
- log_group(g, "ignore msg from %d id %llx %s",
- save->nodeid,
- (unsigned long long)save->msg.ms_event_id,
- msg_type(save->msg.ms_type));
- save->print_ignore = 1;
- }
- continue;
- }
-
- switch (save->msg.ms_type) {
-
- case MSG_APP_STOPPED:
- mark_node_stopped(a, save->nodeid);
- break;
-
- case MSG_APP_STARTED:
- mark_node_started(a, save->nodeid);
- break;
-
- default:
- log_error(g, "process_app_messages: invalid type %d "
- "from %d", save->msg.ms_type, save->nodeid);
- }
-
- if (g->global_id == 0 && save->msg.ms_global_id != 0) {
- g->global_id = save->msg.ms_global_id;
- log_group(g, "set global_id %x from %d",
- g->global_id, save->nodeid);
- }
- free_save:
- list_del(&save->list);
- if (save->msg_long)
- free(save->msg_long);
- free(save);
- rv = 1;
- }
-
- /* state changes to X_ALL_STOPPED or X_ALL_STARTED */
-
- if (event_state_stopping(a) && all_nodes_stopped(a))
- a->current_event->state++;
-
- if (event_state_starting(a) && all_nodes_started(a))
- a->current_event->state++;
-
- return rv;
-}
-
-static void deliver_app_messages(group_t *g)
-{
- app_t *a = g->app;
- struct save_msg *save, *tmp;
-
- list_for_each_entry_safe(save, tmp, &g->messages, list) {
- switch (save->msg.ms_type) {
- case MSG_APP_INTERNAL:
- app_deliver(a, save);
- break;
- default:
- continue;
- }
-
- list_del(&save->list);
- if (save->msg_long)
- free(save->msg_long);
- free(save);
- }
-}
-
-event_t *find_queued_recover_event(group_t *g)
-{
- event_t *ev;
-
- list_for_each_entry(ev, &g->app->events, list) {
- if (ev->state == EST_FAIL_BEGIN)
- return ev;
- }
- return NULL;
-}
-
-#if 0
-static int group_started(event_t *ev)
-{
- switch (ev->state) {
- case EST_JOIN_BEGIN:
- case EST_JOIN_STOP_WAIT:
- case EST_JOIN_ALL_STOPPED:
- case EST_LEAVE_BEGIN:
- case EST_LEAVE_STOP_WAIT:
- case EST_LEAVE_ALL_STOPPED:
- case EST_FAIL_BEGIN:
- case EST_FAIL_STOP_WAIT:
- case EST_FAIL_ALL_STOPPED:
- return 0;
- default:
- return 1;
- };
-}
-#endif
-
-void dump_group(group_t *g)
-{
- app_t *a = g->app;
- node_t *node;
- struct save_msg *save;
- event_t *ev;
-
- printf("---\n");
- printf("name: %s\n", g->name);
- printf("level: %d\n", g->level);
- printf("global_id: %u\n", g->global_id);
- printf("cpg handle: %llx\n", (unsigned long long)g->cpg_handle);
- printf("cpg client: %d\n", g->cpg_client);
- printf("app client: %d\n", g->app->client);
-
- printf("memb count: %u\n", g->memb_count);
- printf("memb list: ");
- list_for_each_entry(node, &g->memb, list)
- printf("%d ", node->nodeid);
- printf("\n");
-
- printf("app node count: %u\n", g->app->node_count);
- printf("app node list: ");
- list_for_each_entry(node, &g->app->nodes, list)
- printf("%d ", node->nodeid);
- printf("\n");
-
- printf("saved messages: ");
- list_for_each_entry(save, &g->messages, list)
- printf("%d/%d ", save->nodeid, save->msg.ms_type);
- printf("\n");
-
- if (a->current_event)
- printf("current_event %d-%d\n", a->current_event->nodeid, a->current_event->state);
-
- printf("events: ");
- list_for_each_entry(ev, &a->events, list)
- printf("%d-%d ", ev->nodeid, ev->state);
- printf("\n");
-
- printf("---\n");
-}
-
-void dump_all_groups(void)
-{
- group_t *g;
- list_for_each_entry(g, &gd_groups, list)
- dump_group(g);
-}
-
-/* handle a node failure while processing an event. returning > 0 means
- we want process_current_event() to be called for the group */
-
-static int recover_current_event(group_t *g)
-{
- app_t *a = g->app;
- event_t *ev, *rev;
- node_t *node, *us;
- struct save_msg *save;
- struct nodeid *id, *safe;
- int rv = 0;
-
- ev = a->current_event;
- if (!ev)
- return 0;
-
- rev = find_queued_recover_event(g);
- if (!rev)
- return 0;
-
- /* if the current ev is for recovery, we merge the new rev into it;
- if the current ev is still stopping (or all stopped), it just
- continues as usual; if the current ev is starting, the state is
- reset back to FAIL_BEGIN so it goes through a stopping cycle for
- the new node failure that's been added to it */
-
- if (is_recovery_event(ev)) {
- log_group(g, "merge new rev %d into current rev %d %s",
- rev->nodeid, ev->nodeid, ev_state_str(ev));
-
- if (ev->state > EST_FAIL_ALL_STOPPED) {
- ev->state = EST_FAIL_BEGIN;
- ev->fail_all_stopped = 0;
- clear_all_nodes_stopped(a);
- } else if (event_state_stopping(a)) {
- mark_node_stopped(a, rev->nodeid);
- list_for_each_entry(id, &rev->extended, list)
- mark_node_stopped(a, id->nodeid);
- }
-
- id = malloc(sizeof(struct nodeid));
- // FIXME: handle failed malloc
- id->nodeid = rev->nodeid;
- list_add(&id->list, &ev->extended);
- log_group(g, "extend active rev %d with failed node %d",
- ev->nodeid, rev->nodeid);
- list_for_each_entry_safe(id, safe, &rev->extended, list) {
- list_del(&id->list);
- list_add(&id->list, &ev->extended);
- log_group(g, "extend active rev %d with failed node %d",
- ev->nodeid, id->nodeid);
- }
-
- send_recover(g, rev);
- list_del(&rev->list);
- free_event(rev);
- return 1;
- }
-
- /* This is a really gross situation, wish I could find a better way
- to deal with it... (rev's skip ahead of other queued ev's, I think
- that's the root of the difficulties here, we don't know if the
- rev has skipped ahead of our join on remote nodes or not).
-
- If our own join event is current on other nodes, then we want a
- rev (which will replace our join ev once it's starting). If our
- join event isn't current on other nodes, then recovery will occur
- before we're added to the app group and the rev doesn't apply to us
- (apart from needing to remove the failed node from the memb list).
-
- We won't know if our join ev is current on other nodes, though,
- until we see a message -- if the message event id is for our join,
- then our ev is current and we'll process the rev after our ev, if
- the message event id is for the rev, then the rev is being done
- by the current members without us and our ev will be done later;
- the rev doesn't apply to us.
-
- Do nothing until we see a message indicating whether other nodes
- are on our join ev (in which case go to "rev will abort curr" code),
- or whether they're processing this rev (before our join ev comes
- up) in which case we can drop the rev (NB attend to rs, too). */
-
- if (ev->state == EST_JOIN_STOP_WAIT && is_our_join(ev)) {
-
- log_group(g, "rev %d is for group we're waiting to join",
- rev->nodeid);
-
- /* If the failed node is the only other app member apart
- from us in the pending membership list, then we must go
- ahead with our own join event, there will be no remote nodes
- processing a rev or an ev for this group. We send a recover
- message so other nodes waiting to join after us will purge
- their rev on the group. */
-
- if (a->node_count == 2) {
- node = find_app_node(a, rev->nodeid);
- us = find_app_node(a, our_nodeid);
-
- if (node && us) {
- log_group(g, "joining group with one other node"
- " now dead rev %d", rev->nodeid);
- a->node_count--;
- list_del(&node->list);
- free(node);
- send_recover(g, rev);
- del_recovery_set(g, rev, 1);
- list_del(&rev->list);
- free_event(rev);
- return 0;
- }
- }
-
- /* Look for a remote node with stopped of 1, if we find one,
- then fall through to the 'else if (event_state_stopping)'
- below. A remote node with stopped of 1 means we've received
- a stopped message with an event_id of our join event. */
-
- list_for_each_entry(node, &a->nodes, list) {
- if (node->nodeid == our_nodeid)
- continue;
- if (node->stopped) {
- log_group(g, "our join is current on %d",
- node->nodeid);
- log_group(g, "rev %d behind our join ev %llx",
- rev->nodeid,
- (unsigned long long)ev->id);
- goto next;
- }
- }
-
- /* Look through saved messages for one with an event_id
- matching the rev, if we find one, then we get rid of this
- rev and clear this group (that we're joining) from any
- recovery sets that are sequencing recovery of groups the
- failed node was in. The other nodes are processing the
- rev before processing our join ev. */
-
- list_for_each_entry(save, &g->messages, list) {
- if (save->msg.ms_type == MSG_APP_INTERNAL)
- continue;
- if (save->msg.ms_event_id != rev->id)
- continue;
-
- log_group(g, "rev %d %llx ahead of our join ev %llx",
- rev->nodeid,
- (unsigned long long)rev->id,
- (unsigned long long)ev->id);
-
- node = find_app_node(a, rev->nodeid);
- if (node) {
- a->node_count--;
- log_group(g, "not joined, remove %d rev %d",
- node->nodeid, rev->nodeid);
- list_del(&node->list);
- free(node);
- }
- list_for_each_entry(id, &rev->extended, list) {
- node = find_app_node(a, id->nodeid);
- if (node) {
- a->node_count--;
- log_group(g, "not joined, remove %d "
- "rev %d", id->nodeid,
- rev->nodeid);
- list_del(&node->list);
- free(node);
- }
- }
-
- del_recovery_set(g, rev, 1);
- list_del(&rev->list);
- log_group(g, "got rid of rev %d for unjoined group",
- rev->nodeid);
- free_event(rev);
- return 0;
- }
-
- log_group(g, "no messages indicating remote state of group");
- return 0;
- }
-
- next:
- /* Before starting the rev we need to apply the node addition/removal
- * of the current ev to the app. This means processing the current ev
- * up through the starting stage. So, we're sending the app the start
- * to inform it of the ev node change, knowing that the start won't
- * complete due to the node failure (pending rev), and knowing that
- * we'll shortly be sending it a stop and new start for the rev.
- *
- * If the current event is waiting for a "stopped" message from failed
- * node(s), fill in those stopped messages so we move along to the
- * starting state so the recovery event can then take over. */
-
- if (event_state_starting(a) || event_state_all_started(a)) {
- log_group(g, "rev %d replaces current ev %d %s",
- rev->nodeid, ev->nodeid, ev_state_str(ev));
-
- /* what we do for our own join when reaching JOIN_ALL_STARTED */
- if (is_our_join(ev)) {
- purge_messages(g);
- g->joining = 0;
- }
- clear_all_nodes_stopped(a);
- list_del(&rev->list);
- a->current_event = rev;
- free_event(ev);
- send_recover(g, rev);
- rv = 1;
- } else if (event_state_stopping(a)) {
- /* We'll come back through here multiple times until all the
- stopped messages are received; we need to continue to
- process this event that's stopping so it will get to the
- starting state at which point the rev can replace it. */
-
- log_group(g, "rev %d will abort current ev %d %s",
- rev->nodeid, ev->nodeid, ev_state_str(ev));
-
- ev->start_app_before_pending_rev = 1;
-
- mark_node_stopped(a, rev->nodeid);
- list_for_each_entry(id, &rev->extended, list)
- mark_node_stopped(a, id->nodeid);
- rv = 1;
- } else {
- log_group(g, "rev %d delayed for ev %d %s",
- rev->nodeid, ev->nodeid, ev_state_str(ev));
- }
-
- /* FIXME: does the code above work ok if ev->nodeid == rev->noded
- (joining node failed) */
-
- /* FIXME: if the current event is a leave and the leaving node has
- failed, then replace the current event with the rev */
-
- return rv;
-}
-
-int process_app(group_t *g)
-{
- app_t *a = g->app;
- event_t *ev = NULL;
- int rv = 0, ret;
-
- if (a->current_event) {
- rv += process_app_messages(g);
-
- ret = process_current_event(g);
- if (ret < 0)
- goto out;
- rv += ret;
-
- ret = recover_current_event(g);
- if (ret <= 0)
- goto out;
-
- ret = process_current_event(g);
- if (ret < 0)
- goto out;
- rv += ret;
- } else {
-
- /* We only take on a new non-recovery event if there are
- no recovery sets outstanding. The new event may be
- to mount gfs X where there are no living mounters of X,
- and the pending recovery set is to fence a node that
- had X mounted. update: relax this so events are taken
- if there are unrecovered groups _at a lower level_. */
-
- ev = find_queued_recover_event(g);
- if (ev) {
- log_group(g, "set current event to recovery for %d",
- ev->nodeid);
- list_del(&ev->list);
- } else if (!list_empty(&a->events)) {
-#if 0
- if (!cman_quorate) {
- log_group(g, "no new event while inquorate");
- } else if (lower_groups_need_recovery(g)) {
- log_group(g, "no new event while lower level "
- "groups need recovery");
- } else {
- ev = list_entry(a->events.next, event_t, list);
- list_del(&ev->list);
- }
-#endif
- ev = list_entry(a->events.next, event_t, list);
- list_del(&ev->list);
- }
-
- if (ev) {
- a->need_first_event = 0;
- a->current_event = ev;
- rv = process_current_event(g);
- } else if (a->need_first_event) {
- log_group(g, "waiting for first cpg event");
- }
- }
- out:
- return rv;
-}
-
-/* process_apps() will be called again immediately if it returns > 0 */
-
-int process_apps(void)
-{
- group_t *g, *safe;
- int rv = 0;
-
- if (group_mode != GROUP_LIBGROUP)
- return 0;
-
- list_for_each_entry_safe(g, safe, &gd_groups, list) {
- rv += process_app(g);
- deliver_app_messages(g);
- }
-
- return rv;
-}
-
-/* This is a bit of a hack that may not be entirely necessary. The problem
- we're solving with this function is when a node leaves a group and is
- collecting all the "stopped" messages from the remaining members, some
- of those members may fail, so we wouldn't get a stopped message from
- them and never finalize_our_leave (terminate the group). I'm not entirely
- sure that we _need_ to wait for stopped messages from remaining members
- before we do the finalize_our_leave/terminate... The reasoning at this
- point is that when gfs is withdrawing, we want to be sure gfs is
- suspended everywhere before we leave the lockspace (which happens at
- terminate for the withdraw/leave) */
-
-void groupd_down(int nodeid)
-{
- group_t *g;
-
- list_for_each_entry(g, &gd_groups, list) {
- if (g->app &&
- g->app->current_event &&
- g->app->current_event->state == EST_LEAVE_STOP_WAIT &&
- is_our_leave(g->app->current_event)) {
- log_group(g, "groupd down on %d, push our leave",
- nodeid);
- mark_node_stopped(g->app, nodeid);
- }
- }
-}
-
diff --git a/group/daemon/cman.c b/group/daemon/cman.c
deleted file mode 100644
index 0c0bbfa..0000000
--- a/group/daemon/cman.c
+++ /dev/null
@@ -1,206 +0,0 @@
-
-/* Interface with corosync's cman API */
-
-#include <libcman.h>
-#include "gd_internal.h"
-
-static cman_handle_t ch;
-static cman_handle_t ch_admin;
-static int old_quorate;
-static cman_node_t old_nodes[MAX_NODES];
-static int old_node_count;
-static cman_node_t cman_nodes[MAX_NODES];
-static int cman_node_count;
-static char name_buf[CMAN_MAX_NODENAME_LEN+1];
-
-
-int kill_cman(int nodeid)
-{
- return cman_kill_node(ch_admin, nodeid);
-}
-
-static int is_member(cman_node_t *node_list, int count, int nodeid)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- if (node_list[i].cn_nodeid == nodeid)
- return node_list[i].cn_member;
- }
- return 0;
-}
-
-static int is_old_member(int nodeid)
-{
- return is_member(old_nodes, old_node_count, nodeid);
-}
-
-static int is_cman_member(int nodeid)
-{
- return is_member(cman_nodes, cman_node_count, nodeid);
-}
-
-static void statechange(void)
-{
- int i, rv;
-
- old_quorate = cman_quorate;
- old_node_count = cman_node_count;
- memcpy(&old_nodes, &cman_nodes, sizeof(old_nodes));
-
- cman_quorate = cman_is_quorate(ch);
-
- cman_node_count = 0;
- memset(&cman_nodes, 0, sizeof(cman_nodes));
- rv = cman_get_nodes(ch, MAX_NODES, &cman_node_count, cman_nodes);
- if (rv < 0) {
- log_print("cman_get_nodes error %d %d", rv, errno);
- return;
- }
-
- /*
- printf("cman: %d old nodes:\n", old_node_count);
- for (i = 0; i < old_node_count; i++)
- printf("%d:%d ", old_nodes[i].cn_nodeid,
- old_nodes[i].cn_member);
- printf("\n");
-
- printf("cman: %d new nodes:\n", cman_node_count);
- for (i = 0; i < cman_node_count; i++)
- printf("%d:%d ", cman_nodes[i].cn_nodeid,
- cman_nodes[i].cn_member);
- printf("\n");
- */
-
- if (old_quorate && !cman_quorate)
- log_debug("cman: lost quorum");
- if (!old_quorate && cman_quorate)
- log_debug("cman: have quorum");
-
- for (i = 0; i < old_node_count; i++) {
- if (old_nodes[i].cn_member &&
- !is_cman_member(old_nodes[i].cn_nodeid)) {
-
- log_debug("cman: node %d removed",
- old_nodes[i].cn_nodeid);
- add_recovery_set_cman(old_nodes[i].cn_nodeid);
- }
- }
-
- for (i = 0; i < cman_node_count; i++) {
- if (cman_nodes[i].cn_member &&
- !is_old_member(cman_nodes[i].cn_nodeid))
- log_debug("cman: node %d added",
- cman_nodes[i].cn_nodeid);
- }
-}
-
-static void cman_callback(cman_handle_t h, void *private, int reason, int arg)
-{
- switch (reason) {
- case CMAN_REASON_TRY_SHUTDOWN:
- cman_replyto_shutdown(ch, 1);
- break;
- case CMAN_REASON_STATECHANGE:
- statechange();
- break;
- case CMAN_REASON_CONFIG_UPDATE:
- setup_logging();
- break;
- }
-}
-
-void process_cman(int ci)
-{
- int rv;
-
- rv = cman_dispatch(ch, CMAN_DISPATCH_ALL);
- if (rv == -1 && errno == EHOSTDOWN)
- cluster_dead(0);
-}
-
-int setup_cman(void)
-{
- cman_node_t node;
- int rv, fd;
- int init = 0, active = 0;
-
- retry_init:
- ch = cman_init(NULL);
- if (!ch) {
- if (init++ < 2) {
- sleep(1);
- goto retry_init;
- }
- log_print("cman_init error %d", errno);
- return -ENOTCONN;
- }
-
- retry_active:
- rv = cman_is_active(ch);
- if (!rv) {
- if (active++ < 2) {
- sleep(1);
- goto retry_active;
- }
- log_print("cman_is_active error %d", errno);
- cman_finish(ch);
- return -ENOTCONN;
- }
-
- ch_admin = cman_admin_init(NULL);
- if (!ch_admin) {
- log_print("cman_admin_init error %d", errno);
- cman_finish(ch);
- return -ENOTCONN;
- }
-
- rv = cman_start_notification(ch, cman_callback);
- if (rv < 0) {
- log_print("cman_start_notification error %d %d", rv, errno);
- cman_finish(ch);
- cman_finish(ch_admin);
- return rv;
- }
-
- memset(&node, 0, sizeof(node));
- rv = cman_get_node(ch, CMAN_NODEID_US, &node);
- if (rv < 0) {
- log_print("cman_get_node us error %d %d", rv, errno);
- cman_stop_notification(ch);
- cman_finish(ch);
- cman_finish(ch_admin);
- return rv;
- }
-
- cman_node_count = 0;
- memset(&cman_nodes, 0, sizeof(cman_nodes));
- rv = cman_get_nodes(ch, MAX_NODES, &cman_node_count, cman_nodes);
- if (rv < 0) {
- log_print("cman_get_nodes error %d %d", rv, errno);
- cman_stop_notification(ch);
- cman_finish(ch);
- cman_finish(ch_admin);
- return rv;
- }
-
- cman_quorate = cman_is_quorate(ch);
-
- memset(name_buf, 0, sizeof(name_buf));
- strncpy(name_buf, node.cn_name, CMAN_MAX_NODENAME_LEN);
- our_name = name_buf;
- our_nodeid = node.cn_nodeid;
- log_debug("cman: our nodeid %d name %s quorum %d",
- our_nodeid, our_name, cman_quorate);
-
- fd = cman_get_fd(ch);
-
- return fd;
-}
-
-void close_cman(void)
-{
- cman_finish(ch);
- cman_finish(ch_admin);
-}
-
diff --git a/group/daemon/cpg.c b/group/daemon/cpg.c
deleted file mode 100644
index 4668afd..0000000
--- a/group/daemon/cpg.c
+++ /dev/null
@@ -1,1116 +0,0 @@
-
-/* Interface with corosync's closed-process-group (cpg) API */
-
-#include "gd_internal.h"
-
-static cpg_handle_t groupd_handle;
-static struct cpg_name groupd_name;
-static int global_id_counter = 0;
-static int groupd_joined = 0;
-static int groupd_ci;
-
-static int got_confchg;
-static struct cpg_address groupd_cpg_member[MAX_GROUP_MEMBERS];
-static int groupd_cpg_member_count;
-static struct cpg_address saved_member[MAX_GROUP_MEMBERS];
-static struct cpg_address saved_joined[MAX_GROUP_MEMBERS];
-static struct cpg_address saved_left[MAX_GROUP_MEMBERS];
-static int saved_member_count;
-static int saved_joined_count;
-static int saved_left_count;
-static cpg_handle_t saved_handle;
-static struct cpg_name saved_name;
-static int message_flow_control_on;
-static struct list_head group_nodes;
-static uint64_t send_version_first;
-
-#define CLUSTER2 2
-#define CLUSTER3 3
-
-struct group_version {
- uint32_t nodeid;
- uint16_t cluster;
- uint16_t group_mode;
- uint16_t groupd_compat;
- uint16_t groupd_count;
- uint32_t unused;
-};
-
-struct group_node {
- uint32_t nodeid;
- uint32_t got_from;
- int got_version;
- int sent_version;
- uint64_t add_time;
- struct group_version ver;
- struct list_head list;
-};
-
-static void block_old_nodes(void);
-
-static const char *mode_str(int m)
-{
- switch (m) {
- case GROUP_PENDING:
- return "PENDING";
- case GROUP_LIBGROUP:
- return "LIBGROUP";
- case GROUP_LIBCPG:
- return "LIBCPG";
- default:
- return "UNKNOWN";
- }
-}
-
-static struct group_node *get_group_node(int nodeid)
-{
- struct group_node *node;
-
- list_for_each_entry(node, &group_nodes, list) {
- if (node->nodeid == nodeid)
- return node;
- }
- return NULL;
-}
-
-static void group_node_add(int nodeid)
-{
- struct group_node *node;
-
- node = get_group_node(nodeid);
- if (node)
- return;
-
- node = malloc(sizeof(struct group_node));
- if (!node)
- return;
- memset(node, 0, sizeof(struct group_node));
-
- node->nodeid = nodeid;
- node->add_time = time(NULL);
- list_add_tail(&node->list, &group_nodes);
-}
-
-static void group_node_del(int nodeid)
-{
- struct group_node *node;
-
- node = get_group_node(nodeid);
- if (!node) {
- log_print("group_node_del %d no node", nodeid);
- return;
- }
-
- list_del(&node->list);
- free(node);
-}
-
-static void version_copy_in(struct group_version *ver)
-{
- ver->nodeid = le32_to_cpu(ver->nodeid);
- ver->cluster = le16_to_cpu(ver->cluster);
- ver->group_mode = le16_to_cpu(ver->group_mode);
- ver->groupd_compat = le16_to_cpu(ver->groupd_compat);
- ver->groupd_count = le16_to_cpu(ver->groupd_count);
-}
-
-static void _send_version(int nodeid, int cluster, int mode, int compat)
-{
- group_t g, *gp;
- char *buf;
- msg_t *msg;
- int len;
- int count = 0;
- struct group_version *ver;
-
- list_for_each_entry(gp, &gd_groups, list)
- count++;
-
- /* just so log_group will work */
- memset(&g, 0, sizeof(group_t));
- strcpy(g.name, "groupd");
-
- len = sizeof(msg_t) + sizeof(struct group_version);
-
- buf = malloc(len);
- if (!buf)
- return;
- memset(buf, 0, len);
-
- msg = (msg_t *)buf;
- ver = (struct group_version *)(buf + sizeof(msg_t));
-
- msg->ms_type = MSG_GROUP_VERSION;
- msg_bswap_out(msg);
-
- log_debug("send_version nodeid %d cluster %d mode %s compat %d",
- nodeid, cluster, mode_str(mode), compat);
-
- ver->nodeid = cpu_to_le32(nodeid);
- ver->cluster = cpu_to_le16(cluster);
- ver->group_mode = cpu_to_le16(mode);
- ver->groupd_compat = cpu_to_le16(compat);
- ver->groupd_count = cpu_to_le16(count);
-
- send_message_groupd(&g, buf, len, MSG_GROUP_VERSION);
-}
-
-static void send_version(void)
-{
- _send_version(our_nodeid, CLUSTER3, group_mode, cfgd_groupd_compat);
-}
-
-static void set_group_mode(void)
-{
- struct group_node *node;
- int need_version, pending_count;
-
- need_version = 0;
- pending_count = 0;
-
- list_for_each_entry(node, &group_nodes, list) {
- if (!node->got_version) {
- need_version++;
- continue;
- }
- if (node->ver.group_mode == GROUP_PENDING) {
- pending_count++;
- continue;
- }
-
- /* If we receive any non-pending group mode, adopt it
- immediately. */
-
- group_mode = node->ver.group_mode;
-
- switch (group_mode) {
- case GROUP_PENDING:
- /* shouldn't happen */
- log_level(LOG_INFO, "groupd compatibility mode 2 ver");
- break;
- case GROUP_LIBGROUP:
- log_level(LOG_INFO, "groupd compatibility mode 1 ver");
- break;
- case GROUP_LIBCPG:
- log_level(LOG_INFO, "groupd compatibility mode 0 ver");
- break;
- default:
- log_level(LOG_INFO, "groupd compatibility mode %d ver",
- group_mode);
- break;
- }
-
- log_debug("set_group_mode %s matching nodeid %d got_from %d",
- mode_str(group_mode), node->nodeid, node->got_from);
- break;
- }
-
- if (group_mode == GROUP_LIBCPG)
- block_old_nodes();
-}
-
-static void receive_version(int from, msg_t *msg, int len)
-{
- struct group_node *node;
- struct group_version *ver;
-
- if (group_mode != GROUP_PENDING)
- return;
-
- ver = (struct group_version *)((char *)msg + sizeof(msg_t));
-
- version_copy_in(ver);
-
- node = get_group_node(ver->nodeid);
- if (!node) {
- log_print("receive_version from %d nodeid %d not found",
- from, ver->nodeid);
- return;
- }
-
- /* ignore a repeat of what we've seen before */
-
- if (node->got_version && from == node->got_from &&
- node->ver.group_mode == ver->group_mode)
- return;
-
- log_debug("receive_version from %d nodeid %d cluster %d mode %s "
- "compat %d", from, ver->nodeid, ver->cluster,
- mode_str(ver->group_mode), ver->groupd_compat);
-
- node->got_version = 1;
- node->got_from = from;
- memcpy(&node->ver, ver, sizeof(struct group_version));
-
- set_group_mode();
-}
-
-void group_mode_check_timeout(void)
-{
- struct group_node *node;
- int need_version, pending_count, sent_count;
- uint64_t now;
-
- if (group_mode != GROUP_PENDING)
- return;
-
- if (!send_version_first)
- return;
-
- /* Wait for cfgd_groupd_wait seconds to receive a version message from
- an added node, after which we'll send a version message for it,
- calling it a cluster2 node; receiving this will cause everyone to
- immediately set mode to LIBGROUP. */
-
- need_version = 0;
- pending_count = 0;
- sent_count = 0;
- now = time(NULL);
-
- list_for_each_entry(node, &group_nodes, list) {
- if (node->got_version) {
- pending_count++;
- continue;
- }
-
- need_version++;
-
- if (node->sent_version) {
- sent_count++;
- continue;
- }
-
- if (now - node->add_time >= cfgd_groupd_wait) {
- log_print("send version for nodeid %d times %llu %llu",
- node->nodeid,
- (unsigned long long)node->add_time,
- (unsigned long long)now);
- _send_version(node->nodeid, CLUSTER2, GROUP_LIBGROUP,1);
- node->sent_version = 1;
- sent_count++;
- }
- }
-
- if (need_version) {
- log_debug("group_mode_check_timeout need %d pending %d sent %d",
- need_version, pending_count, sent_count);
- return;
- }
-
- /* we have a version from everyone, and they all are pending;
- wait for cfgd_groupd_mode_delay to give any old cluster2 nodes
- a chance to join and cause us to use LIBGROUP */
-
- if (now - send_version_first < cfgd_groupd_mode_delay) {
- log_debug("group_mode_check_timeout delay times %llu %llu",
- (unsigned long long)send_version_first,
- (unsigned long long)now);
- return;
- }
-
- /* everyone is cluster3/pending so we can use LIBCPG; receiving
- this will cause everyone to immediately set mode to LIBCPG */
-
- log_debug("send version LIBCPG all %d pending", pending_count);
-
- _send_version(our_nodeid, CLUSTER3, GROUP_LIBCPG, cfgd_groupd_compat);
-}
-
-static node_t *find_group_node(group_t *g, int nodeid)
-{
- node_t *node;
-
- list_for_each_entry(node, &g->memb, list) {
- if (node->nodeid == nodeid)
- return node;
- }
- return NULL;
-}
-
-static void process_node_down(group_t *g, int nodeid)
-{
- node_t *node;
- event_t *ev, *ev_safe;
- int no_rev = 0;
-
- node = find_group_node(g, nodeid);
- if (!node)
- return;
-
- log_group(g, "process_node_down %d", nodeid);
-
- list_del(&node->list);
- g->memb_count--;
- free(node);
-
- log_group(g, "cpg del node %d total %d - down",
- nodeid, g->memb_count);
-
- /* purge any queued join/leave events from the dead node */
-
- list_for_each_entry_safe(ev, ev_safe, &g->app->events, list) {
- if (ev->nodeid != nodeid)
- continue;
-
- if (ev->state == EST_JOIN_BEGIN ||
- ev->state == EST_LEAVE_BEGIN) {
- if (ev->state == EST_JOIN_BEGIN)
- no_rev = 1;
-
- log_group(g, "purge event %s from %d", ev_state_str(ev),
- nodeid);
- del_event_nodes(ev);
- list_del(&ev->list);
- free(ev);
- }
- }
-
- /* the failed node was never added to the app, so the app
- doesn't need to be recovered for it */
- if (no_rev)
- return;
-
- ev = find_queued_recover_event(g);
- if (ev)
- extend_recover_event(g, ev, nodeid);
- else
- queue_app_recover(g, nodeid);
-}
-
-static void process_node_join(group_t *g, int nodeid)
-{
- node_t *node;
- int i;
-
- log_group(g, "process_node_join %d", nodeid);
-
- if (nodeid == our_nodeid) {
- for (i = 0; i < saved_member_count; i++) {
- node = new_node(saved_member[i].nodeid);
- list_add_tail(&node->list, &g->memb);
- g->memb_count++;
- log_group(g, "cpg add node %d total %d",
- node->nodeid, g->memb_count);
- }
-
- /* if we're the first one to join (create) the group,
- then set its global_id */
-
- if (saved_member_count == 1) {
- g->global_id = (++global_id_counter << 16) |
- (0x0000FFFF & our_nodeid);
- log_group(g, "create group id %x our_nodeid %d",
- g->global_id, our_nodeid);
- }
- } else {
- node = new_node(nodeid);
- list_add_tail(&node->list, &g->memb);
- g->memb_count++;
- log_group(g, "cpg add node %d total %d",
- node->nodeid, g->memb_count);
- }
-
- queue_app_join(g, nodeid);
-
- /* if this is for our own join, then make it current immediately;
- other code gets confused if we're not joined and have no current
- event */
- if (nodeid == our_nodeid)
- process_app(g);
-}
-
-static void process_node_leave(group_t *g, int nodeid)
-{
- node_t *node;
-
- log_group(g, "process_node_leave %d", nodeid);
-
- node = find_group_node(g, nodeid);
- if (!node) {
- log_error(g, "process_node_leave: no member %d", nodeid);
- return;
- }
-
- list_del(&node->list);
- g->memb_count--;
- free(node);
-
- log_group(g, "cpg del node %d total %d", nodeid, g->memb_count);
-
- queue_app_leave(g, nodeid);
-}
-
-static uint32_t max_global_id(uint32_t add_nodeid)
-{
- group_t *g;
- uint32_t nodeid, counter, max_counter = 0, max_gid = 0;
-
- list_for_each_entry(g, &gd_groups, list) {
- nodeid = g->global_id & 0x0000FFFF;
- counter = (g->global_id >> 16) & 0x0000FFFF;
- if (nodeid != add_nodeid)
- continue;
- if (!max_counter || counter > max_counter) {
- max_counter = counter;
- max_gid = g->global_id;
- }
- }
- return max_gid;
-}
-
-static int send_gid(uint32_t gid)
-{
- group_t g;
- msg_t msg;
-
- /* just so log_group will work */
- memset(&g, 0, sizeof(group_t));
- strcpy(g.name, "groupd");
-
- memset(&msg, 0, sizeof(msg));
- msg.ms_type = MSG_GLOBAL_ID;
- msg.ms_global_id = gid;
-
- msg_bswap_out(&msg);
-
- return send_message_groupd(&g, &msg, sizeof(msg), MSG_GLOBAL_ID);
-}
-
-static void process_groupd_confchg(void)
-{
- group_t *g;
- struct recovery_set *rs;
- int i, found = 0;
- uint32_t gid;
-
- log_debug("groupd confchg total %d left %d joined %d",
- saved_member_count, saved_left_count, saved_joined_count);
-
- if (!send_version_first) {
- for (i = 0; i < saved_member_count; i++) {
- group_node_add(saved_member[i].nodeid);
- log_debug("groupd init %d", saved_member[i].nodeid);
- }
-
- send_version_first = time(NULL);
- } else {
- for (i = 0; i < saved_left_count; i++) {
- group_node_del(saved_left[i].nodeid);
- log_debug("groupd del %d", saved_left[i].nodeid);
- }
- for (i = 0; i < saved_joined_count; i++) {
- group_node_add(saved_joined[i].nodeid);
- log_debug("groupd add %d", saved_joined[i].nodeid);
- }
- }
-
- if (saved_joined_count)
- send_version();
-
- memcpy(&groupd_cpg_member, &saved_member, sizeof(saved_member));
- groupd_cpg_member_count = saved_member_count;
-
- if (group_mode != GROUP_LIBGROUP)
- return;
-
- for (i = 0; i < saved_member_count; i++) {
- if (saved_member[i].nodeid == our_nodeid &&
- saved_member[i].pid == (uint32_t) getpid()) {
- found = 1;
- }
- }
-
- if (!groupd_joined)
- goto next;
-
- /* find any groups that were created in the past by a new node
- and send it the id it used so it can initialize global_id_counter
- to avoid creating a new group with a duplicate id */
-
- for (i = 0; i < saved_joined_count; i++) {
- gid = max_global_id(saved_joined[i].nodeid);
- if (!gid)
- continue;
- log_debug("joined node %d had old max gid %x",
- saved_joined[i].nodeid, gid);
- send_gid(gid);
- }
-
- next:
- if (found)
- groupd_joined = 1;
- else
- log_print("we are not in groupd confchg: %u %u",
- our_nodeid, (uint32_t) getpid());
-
- for (i = 0; i < saved_left_count; i++) {
- if (saved_left[i].reason == CPG_REASON_LEAVE)
- continue;
-
- if (saved_left[i].reason == CPG_REASON_NODEDOWN) {
- /* a nice clean failure */
- add_recovery_set_cpg(saved_left[i].nodeid, 0);
- } else if (saved_left[i].reason == CPG_REASON_PROCDOWN) {
- /* groupd failed, but the node is still up; if
- the node was in any groups (non-NULL rs is
- returned), then kill the node so it'll be a
- real nodedown */
- rs = add_recovery_set_cpg(saved_left[i].nodeid, 1);
- if (rs) {
- log_print("kill node %d - groupd PROCDOWN",
- saved_left[i].nodeid);
- kill_cman(saved_left[i].nodeid);
- }
- }
- groupd_down(saved_left[i].nodeid);
- }
-
- /* we call process_node_down from here, instead of from the other cpg
- confchg's because we want everyone to see the same order of
- confchg's with respect to messages. see bz 258121 */
-
- for (i = 0; i < saved_left_count; i++) {
- if (saved_left[i].reason == CPG_REASON_NODEDOWN ||
- saved_left[i].reason == CPG_REASON_PROCDOWN) {
- list_for_each_entry(g, &gd_groups, list)
- process_node_down(g, saved_left[i].nodeid);
- }
- }
-}
-
-void copy_groupd_data(group_data_t *data)
-{
- int i;
-
- data->level = -1;
- data->member_count = groupd_cpg_member_count;
- for (i = 0; i < groupd_cpg_member_count; i++)
- data->members[i] = groupd_cpg_member[i].nodeid;
-}
-
-int in_groupd_cpg(int nodeid)
-{
- int i;
- for (i = 0; i < groupd_cpg_member_count; i++) {
- if (nodeid == groupd_cpg_member[i].nodeid)
- return 1;
- }
- return 0;
-}
-
-static group_t *find_group_by_handle(cpg_handle_t h)
-{
- group_t *g;
-
- list_for_each_entry(g, &gd_groups, list) {
- if (g->cpg_handle == h)
- return g;
- }
- return NULL;
-}
-
-static void deliver_cb(cpg_handle_t handle,
- const struct cpg_name *group_name,
- uint32_t nodeid, uint32_t pid,
- void *data, size_t data_len)
-{
- group_t *g;
- struct save_msg *save;
- msg_t *msg = (msg_t *) data;
- char *buf;
- char name[MAX_NAMELEN+1];
- uint32_t to_nodeid, counter;
- int len;
-
- memset(&name, 0, sizeof(name));
-
- msg_bswap_in(msg);
-
- if (msg->ms_type == MSG_GROUP_VERSION) {
- receive_version(nodeid, msg, data_len);
- return;
- }
-
- if (msg->ms_type == MSG_GLOBAL_ID) {
- to_nodeid = msg->ms_global_id & 0x0000FFFF;
- counter = (msg->ms_global_id >> 16) & 0x0000FFFF;
-
- if (to_nodeid == our_nodeid) {
- log_debug("recv global_id %x from %u cur counter %u",
- msg->ms_global_id, nodeid, global_id_counter);
- if (counter > global_id_counter)
- global_id_counter = counter;
- }
- return;
- }
-
- if (handle == groupd_handle) {
- memcpy(&name, &msg->ms_name, MAX_NAMELEN);
-
- g = find_group_level(name, msg->ms_level);
- if (!g) {
- if (daemon_debug_verbose > 1) {
- log_print("%d:%s RECV len %zd %s from %d, "
- "no group",
- msg->ms_level, name, data_len,
- msg_type(msg->ms_type), nodeid);
- }
- return;
- }
- } else {
- if (group_mode != GROUP_LIBGROUP)
- return;
-
- g = find_group_by_handle(handle);
- if (!g) {
- len = group_name->length;
- if (len > MAX_NAMELEN)
- len = MAX_NAMELEN;
- memcpy(&name, &group_name->value, len);
-
- log_print("deliver_cb no group handle %llx name %s",
- (unsigned long long)handle, name);
- return;
- }
- }
-
- if (daemon_debug_verbose > 1)
- log_group(g, "RECV len %zd %s from %d", data_len,
- msg_type(msg->ms_type), nodeid);
-
- save = malloc(sizeof(struct save_msg));
- // FIXME: handle failed malloc
- memset(save, 0, sizeof(struct save_msg));
- save->nodeid = nodeid;
- save->msg_len = data_len;
-
- if (data_len > sizeof(msg_t)) {
- buf = malloc(data_len);
- // FIXME: handle failed malloc
- memcpy(buf, data, data_len);
- save->msg_long = buf;
- memcpy(&save->msg, data, sizeof(msg_t));
- } else
- memcpy(&save->msg, data, sizeof(msg_t));
-
- queue_app_message(g, save);
-}
-
-static void process_confchg(void)
-{
- group_t *g;
- int i;
-
- if (saved_handle == groupd_handle) {
- process_groupd_confchg();
- return;
- }
-
- if (group_mode != GROUP_LIBGROUP)
- return;
-
- g = find_group_by_handle(saved_handle);
- if (!g) {
- log_debug("confchg: no group for handle %llx name %s",
- (unsigned long long)saved_handle,
- saved_name.value);
- return;
- }
-
- log_group(g, "confchg left %d joined %d total %d",
- saved_left_count, saved_joined_count, saved_member_count);
-
- for (i = 0; i < saved_joined_count; i++)
- process_node_join(g, saved_joined[i].nodeid);
-
- for (i = 0; i < saved_left_count; i++) {
- log_group(g, "confchg removed node %d reason %d",
- saved_left[i].nodeid, saved_left[i].reason);
-
- switch (saved_left[i].reason) {
- case CPG_REASON_LEAVE:
- process_node_leave(g, saved_left[i].nodeid);
- break;
- case CPG_REASON_NODEDOWN:
- case CPG_REASON_PROCDOWN:
- /* process_node_down(g, saved_left[i].nodeid); */
- purge_node_messages(g, saved_left[i].nodeid);
- break;
- default:
- log_error(g, "unknown leave reason %d node %d",
- saved_left[i].reason,
- saved_joined[i].nodeid);
- }
- }
-}
-
-static void confchg_cb(cpg_handle_t handle,
- const struct cpg_name *group_name,
- const struct cpg_address *member_list,
- size_t member_list_entries,
- const struct cpg_address *left_list,
- size_t left_list_entries,
- const struct cpg_address *joined_list,
- size_t joined_list_entries)
-{
- group_t *g;
- const char *name = "unknown";
- int i, level = -1;
-
- if (handle == groupd_handle)
- name = "groupd";
- else {
- g = find_group_by_handle(handle);
- if (g) {
- name = g->name;
- level = g->level;
- }
- }
-
- /*
- log_debug("%d:%s confchg_cb total %d left %d joined %d", level, name,
- member_list_entries, left_list_entries, joined_list_entries);
- */
-
- saved_handle = handle;
-
- if (left_list_entries > MAX_GROUP_MEMBERS) {
- log_debug("left_list_entries %zd", left_list_entries);
- left_list_entries = MAX_GROUP_MEMBERS;
- }
- if (joined_list_entries > MAX_GROUP_MEMBERS) {
- log_debug("joined_list_entries %zd", joined_list_entries);
- joined_list_entries = MAX_GROUP_MEMBERS;
- }
- if (member_list_entries > MAX_GROUP_MEMBERS) {
- log_debug("member_list_entries %zd", joined_list_entries);
- member_list_entries = MAX_GROUP_MEMBERS;
- }
-
- saved_left_count = left_list_entries;
- saved_joined_count = joined_list_entries;
- saved_member_count = member_list_entries;
-
- memset(&saved_name, 0, sizeof(saved_name));
- saved_name.length = group_name->length;
- memcpy(&saved_name.value, &group_name->value, group_name->length);
-
- for (i = 0; i < left_list_entries; i++)
- saved_left[i] = left_list[i];
-
- for (i = 0; i < joined_list_entries; i++)
- saved_joined[i] = joined_list[i];
-
- for (i = 0; i < member_list_entries; i++)
- saved_member[i] = member_list[i];
-
- got_confchg = 1;
-}
-
-cpg_callbacks_t callbacks = {
- .cpg_deliver_fn = deliver_cb,
- .cpg_confchg_fn = confchg_cb,
-};
-
-static void process_cpg(int ci)
-{
- group_t *g = NULL;
- cpg_error_t error;
- cpg_handle_t handle;
- int found = 0;
- cpg_flow_control_state_t flow_control_state;
-
- if (ci == groupd_ci) {
- handle = groupd_handle;
- goto dispatch;
- }
-
- list_for_each_entry(g, &gd_groups, list) {
- if (g->cpg_client == ci) {
- handle = g->cpg_handle;
- found = 1;
- break;
- }
- }
-
- if (!found) {
- log_print("process_cpg: no group found for ci %d", ci);
- sleep(1);
- return;
- }
-
- dispatch:
- got_confchg = 0;
-
- error = cpg_dispatch(handle, CPG_DISPATCH_ONE);
- if (error != CPG_OK) {
- log_print("cpg_dispatch error %d", error);
- return;
- }
-
- error = cpg_flow_control_state_get(handle, &flow_control_state);
- if (error != CPG_OK)
- log_error(g, "cpg_flow_control_state_get %d", error);
- else if (flow_control_state == CPG_FLOW_CONTROL_ENABLED) {
- message_flow_control_on = 1;
- log_debug("flow control on");
- } else {
- if (message_flow_control_on)
- log_debug("flow control off");
- message_flow_control_on = 0;
- }
-
- if (got_confchg)
- process_confchg();
-}
-
-int setup_cpg(void)
-{
- cpg_error_t error;
- int fd;
-
- INIT_LIST_HEAD(&group_nodes);
-
- error = cpg_initialize(&groupd_handle, &callbacks);
- if (error != CPG_OK) {
- log_print("cpg_initialize error %d", error);
- return error;
- }
-
- cpg_fd_get(groupd_handle, &fd);
-
- groupd_ci = client_add(fd, process_cpg, NULL);
-
- memset(&groupd_name, 0, sizeof(groupd_name));
- strcpy(groupd_name.value, "groupd");
- groupd_name.length = 7;
-
- retry:
- error = cpg_join(groupd_handle, &groupd_name);
- if (error == CPG_ERR_TRY_AGAIN) {
- log_debug("setup_cpg cpg_join retry");
- sleep(1);
- goto retry;
- }
- if (error != CPG_OK) {
- log_print("cpg_join error %d", error);
- cpg_finalize(groupd_handle);
- return error;
- }
-
- log_debug("setup_cpg groupd_handle %llx",
- (unsigned long long)groupd_handle);
-
- return 0;
-}
-
-void close_cpg(void)
-{
- group_t *g;
- cpg_error_t error;
- int i = 0;
-
- if (!groupd_handle)
- return;
- if (cluster_down)
- goto fin;
- retry:
- error = cpg_leave(groupd_handle, &groupd_name);
- if (error == CPG_ERR_TRY_AGAIN) {
- sleep(1);
- if (!(++i % 10))
- log_print("daemon cpg_leave error retrying");
- goto retry;
- }
- if (error != CPG_OK)
- log_print("daemon cpg_leave error %d", error);
- fin:
- list_for_each_entry(g, &gd_groups, list) {
- if (g->cpg_handle)
- cpg_finalize(g->cpg_handle);
- }
- cpg_finalize(groupd_handle);
-}
-
-int do_cpg_join(group_t *g)
-{
- cpg_error_t error;
- cpg_handle_t h;
- struct cpg_name name;
- int fd, ci, i = 0;
-
- error = cpg_initialize(&h, &callbacks);
- if (error != CPG_OK) {
- log_group(g, "cpg_initialize error %d", error);
- return error;
- }
-
- cpg_fd_get(h, &fd);
-
- ci = client_add(fd, process_cpg, NULL);
-
- g->cpg_client = ci;
- g->cpg_handle = h;
- g->cpg_fd = fd;
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "%d_%s", g->level, g->name);
- name.length = strlen(name.value) + 1;
-
- log_group(g, "is cpg client %d name %s handle %llx", ci, name.value,
- (unsigned long long)h);
-
- retry:
- error = cpg_join(h, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- log_debug("cpg_join error retry");
- sleep(1);
- if (!(++i % 10))
- log_error(g, "cpg_join error retrying");
- goto retry;
- }
- if (error != CPG_OK) {
- log_group(g, "cpg_join error %d", error);
- cpg_finalize(h);
- return error;
- }
-
- log_group(g, "cpg_join ok");
- return 0;
-}
-
-int do_cpg_leave(group_t *g)
-{
- cpg_error_t error;
- struct cpg_name name;
- int i = 0;
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "%d_%s", g->level, g->name);
- name.length = strlen(name.value) + 1;
-
- retry:
- error = cpg_leave(g->cpg_handle, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- log_debug("cpg_leave error retry");
- sleep(1);
- if (!(++i % 10))
- log_error(g, "cpg_leave error retrying");
- goto retry;
- }
- if (error != CPG_OK) {
- log_group(g, "cpg_leave error %d", error);
- return error;
- }
-
- log_group(g, "cpg_leave ok");
- return 0;
-}
-
-static int _send_message(cpg_handle_t h, group_t *g, void *buf, int len)
-{
- struct iovec iov;
- cpg_error_t error;
- int retries = 0;
-
- iov.iov_base = buf;
- iov.iov_len = len;
-
- retry:
- error = cpg_mcast_joined(h, CPG_TYPE_AGREED, &iov, 1);
- if (error == CPG_ERR_TRY_AGAIN) {
- retries++;
- usleep(1000);
- if (!(retries % 100))
- log_error(g, "cpg_mcast_joined retry %d", retries);
- goto retry;
- } else if (error != CPG_OK)
- log_error(g, "cpg_mcast_joined error %d handle %llx", error,
- (unsigned long long)h);
-
- if (retries)
- log_group(g, "cpg_mcast_joined retried %d", retries);
-
- return 0;
-}
-
-int send_message_groupd(group_t *g, void *buf, int len, int type)
-{
- if (daemon_debug_verbose > 1)
- log_group(g, "SEND len %d %s", len, msg_type(type));
-
- return _send_message(groupd_handle, g, buf, len);
-}
-
-int send_message(group_t *g, void *buf, int len)
-{
- return _send_message(g->cpg_handle, g, buf, len);
-}
-
-static void block_old_group(const char *name, int level)
-{
- group_t *g;
- app_t *a;
- cpg_error_t error;
- cpg_handle_t h;
- struct cpg_name cpgname;
- int rv, fd, ci, i = 0;
-
- rv = create_group(name, level, &g);
- if (rv)
- return;
- a = create_app(g);
- if (!a)
- return;
-
- error = cpg_initialize(&h, &callbacks);
- if (error != CPG_OK) {
- log_print("cpg_initialize error %d", error);
- return;
- }
-
- cpg_fd_get(h, &fd);
-
- ci = client_add(fd, process_cpg, NULL);
-
- g->cpg_client = ci;
- g->cpg_handle = h;
- g->cpg_fd = fd;
- g->joining = 1;
- a->client = ci;
-
- memset(&cpgname, 0, sizeof(cpgname));
- sprintf(cpgname.value, "%d_%s", level, name);
- cpgname.length = strlen(cpgname.value) + 1;
-
- retry:
- error = cpg_join(h, &cpgname);
- if (error == CPG_ERR_TRY_AGAIN) {
- log_debug("cpg_join error retry");
- sleep(1);
- if (!(++i % 10))
- log_print("cpg_join error retrying");
- goto retry;
- }
- if (error != CPG_OK) {
- log_print("cpg_join error %d", error);
- cpg_finalize(h);
- return;
- }
-}
-
-/* Problem: GROUP_LIBCPG is selected during version detection, then
- an old cluster2 node starts (people aren't supposed to do this, but it may
- happen, so it's nice to do what we can to address it). groupd on the old
- cluster2 node, using libgroup, will allow new groups to be formed on it.
- Solution is a hack: when the cluster3 nodes select LIBCPG mode, they also
- create unused/placeholder cpg's with the names of old known cluster2 groups,
- which blocks them being fully joined by old groupd's that may come along. */
-
-static void block_old_nodes(void)
-{
- block_old_group("default", 0);
- block_old_group("clvmd", 1);
- block_old_group("rgmanager", 1);
-}
-
diff --git a/group/daemon/gd_internal.h b/group/daemon/gd_internal.h
deleted file mode 100644
index 5e2c4d3..0000000
--- a/group/daemon/gd_internal.h
+++ /dev/null
@@ -1,325 +0,0 @@
-#ifndef __GD_INTERNAL_DOT_H__
-#define __GD_INTERNAL_DOT_H__
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <string.h>
-#include <strings.h>
-#include <ctype.h>
-#include <dirent.h>
-#include <syslog.h>
-#include <time.h>
-#include <sched.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/types.h>
-#include <sys/errno.h>
-#include <sys/poll.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <corosync/cpg.h>
-#include <liblogthread.h>
-
-#include "list.h"
-#include "linux_endian.h"
-#include "groupd.h"
-#include "libgroup.h"
-
-#define MAX_NAMELEN 32 /* should match libgroup.h */
-#define MAX_LEVELS 4
-#define MAX_NODES 128
-
-extern int daemon_debug_opt;
-extern int daemon_debug_verbose;
-extern int daemon_quit;
-extern int cluster_down;
-extern int cman_quorate;
-extern int our_nodeid;
-extern char *our_name;
-extern char daemon_debug_buf[256];
-extern char dump_buf[GROUPD_DUMP_SIZE];
-extern int dump_point;
-extern int dump_wrap;
-extern struct list_head gd_groups;
-extern struct list_head gd_levels[MAX_LEVELS];
-extern uint32_t gd_event_nr;
-
-#define GROUP_PENDING 1
-#define GROUP_LIBGROUP 2
-#define GROUP_LIBCPG 3
-
-extern int group_mode;
-
-#define DEFAULT_GROUPD_COMPAT 0
-#define DEFAULT_GROUPD_WAIT 5
-#define DEFAULT_GROUPD_MODE_DELAY 2
-#define DEFAULT_DEBUG_LOGFILE 0
-
-extern int optd_groupd_compat;
-extern int optd_groupd_wait;
-extern int optd_groupd_mode_delay;
-extern int optd_debug_logfile;
-
-extern int cfgd_groupd_compat;
-extern int cfgd_groupd_wait;
-extern int cfgd_groupd_mode_delay;
-extern int cfgd_debug_logfile;
-
-void daemon_dump_save(void);
-
-#define log_level(lvl, fmt, args...) \
-do { \
- snprintf(daemon_debug_buf, 255, "%ld " fmt "\n", time(NULL), ##args); \
- daemon_dump_save(); \
- logt_print(lvl, fmt "\n", ##args); \
- if (daemon_debug_opt) \
- fprintf(stderr, "%s", daemon_debug_buf); \
-} while (0)
-
-#define log_debug(fmt, args...) log_level(LOG_DEBUG, fmt, ##args)
-#define log_print(fmt, args...) log_level(LOG_ERR, fmt, ##args)
-
-#define log_group(g, fmt, args...) \
-do { \
- snprintf(daemon_debug_buf, 255, "%ld %d:%s " fmt "\n", time(NULL), \
- (g)->level, (g)->name, ##args); \
- daemon_dump_save(); \
- logt_print(LOG_DEBUG, fmt "\n", ##args); \
- if (daemon_debug_opt) \
- fprintf(stderr, "%s", daemon_debug_buf); \
-} while (0)
-
-#define log_error(g, fmt, args...) \
-do { \
- snprintf(daemon_debug_buf, 255, "%ld %d:%s " fmt "\n", time(NULL), \
- (g)->level, (g)->name, ##args); \
- daemon_dump_save(); \
- logt_print(LOG_ERR, fmt "\n", ##args); \
- if (daemon_debug_opt) \
- fprintf(stderr, "%s", daemon_debug_buf); \
-} while (0)
-
-#define ASSERT(x) \
-do { \
- if (!(x)) { \
- log_print("Assertion failed on line %d of file %s\n" \
- "Assertion: \"%s\"\n", __LINE__, __FILE__, #x); \
- } \
-} while (0)
-
-#ifndef TRUE
-#define TRUE (1)
-#endif
-#ifndef FALSE
-#define FALSE (0)
-#endif
-
-struct group;
-struct app;
-struct event;
-struct node;
-struct msg;
-typedef struct group group_t;
-typedef struct app app_t;
-typedef struct event event_t;
-typedef struct node node_t;
-typedef struct msg msg_t;
-
-
-/*
- * Event - manages nodes joining/leaving/failing
- */
-
-#define EST_JOIN_BEGIN 1
-#define EST_JOIN_STOP_WAIT 2
-#define EST_JOIN_ALL_STOPPED 3
-#define EST_JOIN_START_WAIT 4
-#define EST_JOIN_ALL_STARTED 5
-#define EST_LEAVE_BEGIN 6
-#define EST_LEAVE_STOP_WAIT 7
-#define EST_LEAVE_ALL_STOPPED 8
-#define EST_LEAVE_START_WAIT 9
-#define EST_LEAVE_ALL_STARTED 10
-#define EST_FAIL_BEGIN 11
-#define EST_FAIL_STOP_WAIT 12
-#define EST_FAIL_ALL_STOPPED 13
-#define EST_FAIL_START_WAIT 14
-#define EST_FAIL_ALL_STARTED 15
-
-struct event {
- struct list_head list;
- struct list_head memb;
- int event_nr;
- int state;
- int nodeid;
- uint64_t id;
- struct list_head extended;
- int start_app_before_pending_rev;
- int fail_all_stopped;
-};
-
-/*
- * Group
- */
-
-struct group {
- struct list_head list; /* list of groups */
- struct list_head level_list;
- uint16_t level;
- uint32_t global_id;
- struct list_head memb;
- int memb_count;
- int namelen;
- char name[MAX_NAMELEN+1];
- app_t *app;
- struct list_head messages;
- cpg_handle_t cpg_handle;
- int cpg_fd;
- int cpg_client;
- int have_set_id;
- int joining;
- int leaving;
-};
-
-struct app {
- int client;
- int node_count;
- struct list_head nodes;
- struct list_head events;
- event_t *current_event;
- group_t *g;
- int need_first_event; /* for debugging */
-};
-
-#define MSG_APP_STOPPED 1
-#define MSG_APP_STARTED 2
-#define MSG_APP_RECOVER 3
-#define MSG_APP_INTERNAL 4
-#define MSG_GLOBAL_ID 5
-#define MSG_GROUP_VERSION 6
-
-#define MSG_VER_MAJOR 1
-#define MSG_VER_MINOR 1
-#define MSG_VER_PATCH 0
-
-struct msg {
- uint32_t ms_version[3];
- uint16_t ms_type;
- uint16_t ms_level;
- uint32_t ms_length;
- uint32_t ms_global_id;
- uint64_t ms_event_id;
- char ms_name[MAX_NAMELEN];
-};
-
-struct save_msg {
- struct list_head list;
- int nodeid;
- int print_ignore;
- int msg_len;
- msg_t msg;
- char *msg_long;
-};
-
-struct node {
- struct list_head list;
- int nodeid;
- int stopped;
- int started;
-};
-
-struct recovery_set {
- struct list_head list;
- struct list_head entries;
- int nodeid;
- int cman_update;
- int cpg_update;
-};
-
-struct recovery_entry {
- struct list_head list;
- group_t *group;
- int recovered;
-};
-
-
-/* app.c */
-void add_recovery_set_cman(int nodeid);
-struct recovery_set *add_recovery_set_cpg(int nodeid, int procdown);
-int queue_app_recover(group_t *g, int nodeid);
-int queue_app_join(group_t *g, int nodeid);
-int queue_app_leave(group_t *g, int nodeid);
-int queue_app_message(group_t *g, struct save_msg *save);
-int do_stopdone(char *name, int level);
-int do_startdone(char *name, int level, int event_nr);
-const char *ev_state_str(event_t *ev);
-event_t *find_queued_recover_event(group_t *g);
-void extend_recover_event(group_t *g, event_t *ev, int nodeid);
-int process_apps(void);
-void del_event_nodes(event_t *ev);
-void dump_group(group_t *g);
-void dump_all_groups(void);
-node_t *find_app_node(app_t *a, int nodeid);
-int event_state_stopping(app_t *a);
-int event_state_starting(app_t *a);
-void msg_bswap_out(msg_t *msg);
-void msg_bswap_in(msg_t *msg);
-struct recovery_set *get_recovery_set(int nodeid);
-void groupd_down(int nodeid);
-const char *msg_type(int type);
-int process_app(group_t *g);
-int is_our_join(event_t *ev);
-void purge_node_messages(group_t *g, int nodeid);
-
-/* main.c */
-void read_ccs_name(const char *path, char *name);
-void read_ccs_yesno(const char *path, int *yes, int *no);
-void read_ccs_int(const char *path, int *config_val);
-void app_stop(app_t *a);
-void app_setid(app_t *a);
-void app_start(app_t *a);
-void app_finish(app_t *a);
-void app_terminate(app_t *a);
-void app_deliver(app_t *a, struct save_msg *save);
-int client_add(int fd, void (*workfn)(int ci), void (*deadfn)(int ci));
-void client_dead(int ci);
-void cluster_dead(int ci);
-
-/* cman.c */
-int setup_cman(void);
-void close_cman(void);
-void process_cman(int ci);
-int kill_cman(int nodeid);
-
-/* cpg.c */
-int setup_cpg(void);
-void close_cpg(void);
-int do_cpg_join(group_t *g);
-int do_cpg_leave(group_t *g);
-int send_message(group_t *g, void *buf, int len);
-int send_message_groupd(group_t *g, void *buf, int len, int type);
-void copy_groupd_data(group_data_t *data);
-int in_groupd_cpg(int nodeid);
-void group_mode_check_timeout(void);
-
-/* joinleave.c */
-void remove_group(group_t *g);
-int do_join(char *name, int level, int ci);
-int do_leave(char *name, int level);
-node_t *new_node(int nodeid);
-group_t *find_group_level(char *name, int level);
-int create_group(const char *name, int level, group_t **g_out);
-app_t *create_app(group_t *g);
-
-/* logging.c */
-
-void init_logging(void);
-void setup_logging(void);
-void close_logging(void);
-
-#endif /* __GD_INTERNAL_DOT_H__ */
-
diff --git a/group/daemon/groupd.h b/group/daemon/groupd.h
deleted file mode 100644
index 69bd1fc..0000000
--- a/group/daemon/groupd.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __GROUPD_DOT_H__
-#define __GROUPD_DOT_H__
-
-#define GROUPD_SOCK_PATH ("groupd_socket")
-#define NODE_FAILED (1)
-#define NODE_JOIN (2)
-#define NODE_LEAVE (3)
-#define GROUPD_MSGLEN (2200) /* should be enough to permit
- group_send() of up to 2048 bytes
- of data plus header info */
-#define GROUPD_DUMP_SIZE (1024 * 1024)
-
-#endif
diff --git a/group/daemon/joinleave.c b/group/daemon/joinleave.c
deleted file mode 100644
index e2a1ea7..0000000
--- a/group/daemon/joinleave.c
+++ /dev/null
@@ -1,165 +0,0 @@
-
-/* Initiate join/leave requests from apps */
-
-#include "gd_internal.h"
-
-
-group_t *find_group_level(char *name, int level)
-{
- group_t *g;
-
- list_for_each_entry(g, &gd_levels[level], level_list) {
- if (!strcmp(g->name, name))
- return g;
- }
- return NULL;
-}
-
-int create_group(const char *name, int level, group_t **g_out)
-{
- group_t *g;
-
- g = malloc(sizeof(*g));
- if (!g)
- return -ENOMEM;
-
- memset(g, 0, sizeof(*g));
-
- strcpy(g->name, name);
- g->namelen = strlen(name);
- g->level = level;
- INIT_LIST_HEAD(&g->memb);
- INIT_LIST_HEAD(&g->messages);
-
- list_add_tail(&g->list, &gd_groups);
- list_add_tail(&g->level_list, &gd_levels[level]);
-
- *g_out = g;
- return 0;
-}
-
-static void free_group_memb(group_t *g)
-{
- node_t *node, *n;
-
- list_for_each_entry_safe(node, n, &g->memb, list) {
- list_del(&node->list);
- free(node);
- }
-}
-
-void remove_group(group_t *g)
-{
- list_del(&g->list);
- list_del(&g->level_list);
- free_group_memb(g);
- free(g);
-}
-
-app_t *create_app(group_t *g)
-{
- app_t *a;
-
- a = malloc(sizeof(app_t));
- if (!a)
- return NULL;
- memset(a, 0, sizeof(app_t));
-
- a->need_first_event = 1;
- INIT_LIST_HEAD(&a->nodes);
- INIT_LIST_HEAD(&a->events);
- a->g = g;
- g->app = a;
-
- return a;
-}
-
-int do_join(char *name, int level, int ci)
-{
- group_t *g;
- app_t *a;
- int rv;
-
- g = find_group_level(name, level);
- if (g) {
- log_group(g, "%d:%s can't join existing group", level, name);
- rv = -EEXIST;
- goto out;
- }
-
- rv = create_group(name, level, &g);
- if (rv)
- goto out;
-
- a = create_app(g);
- if (!a) {
- rv = -ENOMEM;
- goto out;
- }
-
- a->client = ci;
-
- log_debug("%d:%s got join", level, name);
- g->joining = 1;
- rv = do_cpg_join(g);
- out:
- return rv;
-}
-
-int do_leave(char *name, int level)
-{
- group_t *g;
- event_t *ev;
- int rv;
-
- g = find_group_level(name, level);
- if (!g)
- return -ENOENT;
-
- if (!g->app) {
- log_group(g, "leave: no app");
- return -EINVAL;
- }
-
- if (g->joining) {
- log_error(g, "leave: still joining");
- return -EAGAIN;
- }
-
- if (g->leaving) {
- log_error(g, "leave: already leaving");
- return -EBUSY;
- }
-
- ev = g->app->current_event;
-
- if (ev && ev->nodeid == our_nodeid) {
- log_error(g, "leave: busy event %llx state %s",
- (unsigned long long)ev->id,
- ev_state_str(ev));
- return -EAGAIN;
- }
-
- list_for_each_entry(ev, &g->app->events, list) {
- ASSERT(ev->nodeid != our_nodeid);
- log_group(g, "do_leave: found queued event id %llx",
- (unsigned long long)ev->id);
- }
-
- log_debug("%d:%s got leave", level, name);
- g->leaving = 1;
- rv = do_cpg_leave(g);
- return rv;
-}
-
-node_t *new_node(int nodeid)
-{
- node_t *node;
-
- node = malloc(sizeof(*node));
- // FIXME: handle failed malloc
- memset(node, 0, sizeof(*node));
- node->nodeid = nodeid;
- return node;
-}
-
diff --git a/group/daemon/logging.c b/group/daemon/logging.c
deleted file mode 100644
index e3cd636..0000000
--- a/group/daemon/logging.c
+++ /dev/null
@@ -1,60 +0,0 @@
-#include "gd_internal.h"
-#include "ccs.h"
-
-extern int ccs_handle;
-
-#define DAEMON_NAME "groupd"
-#define DEFAULT_LOG_MODE LOG_MODE_OUTPUT_FILE|LOG_MODE_OUTPUT_SYSLOG
-#define DEFAULT_SYSLOG_FACILITY SYSLOGFACILITY
-#define DEFAULT_SYSLOG_PRIORITY SYSLOGLEVEL
-#define DEFAULT_LOGFILE_PRIORITY LOG_INFO /* ? */
-#define DEFAULT_LOGFILE LOGDIR "/" DAEMON_NAME ".log"
-
-static int log_mode;
-static int syslog_facility;
-static int syslog_priority;
-static int logfile_priority;
-static char logfile[PATH_MAX];
-
-void init_logging(void)
-{
- log_mode = DEFAULT_LOG_MODE;
- syslog_facility = DEFAULT_SYSLOG_FACILITY;
- syslog_priority = DEFAULT_SYSLOG_PRIORITY;
- logfile_priority = DEFAULT_LOGFILE_PRIORITY;
- strcpy(logfile, DEFAULT_LOGFILE);
-
- /* logfile_priority is the only one of these options that
- can be controlled from command line or environment variable */
-
- if (cfgd_debug_logfile)
- logfile_priority = LOG_DEBUG;
-
- log_debug("logging mode %d syslog f %d p %d logfile p %d %s",
- log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-
- logt_init(DAEMON_NAME, log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-}
-
-void setup_logging(void)
-{
- ccs_read_logging(ccs_handle, DAEMON_NAME,
- &cfgd_debug_logfile, &log_mode,
- &syslog_facility, &syslog_priority,
- &logfile_priority, logfile);
-
- log_debug("logging mode %d syslog f %d p %d logfile p %d %s",
- log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-
- logt_conf(DAEMON_NAME, log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-}
-
-void close_logging(void)
-{
- logt_exit();
-}
-
diff --git a/group/daemon/main.c b/group/daemon/main.c
deleted file mode 100644
index 317a29c..0000000
--- a/group/daemon/main.c
+++ /dev/null
@@ -1,1074 +0,0 @@
-#include <signal.h>
-#include <time.h>
-
-#include "gd_internal.h"
-#include "ccs.h"
-#include "copyright.cf"
-
-#define LOCKFILE_NAME "/var/run/groupd.pid"
-#define CLIENT_NALLOC 32
-
-extern struct list_head recovery_sets;
-
-static int client_maxi;
-static int client_size = 0;
-static struct client *client = NULL;
-static struct pollfd *pollfd = NULL;
-static char last_action[16];
-int ccs_handle;
-
-struct client {
- int fd;
- int level;
- char type[32];
- void *workfn;
- void *deadfn;
-};
-
-static int do_read(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- while (off < count) {
- rv = read(fd, (char *)buf + off, count - off);
- if (rv == 0)
- return -1;
- if (rv == -1 && errno == EINTR)
- continue;
- if (rv == -1)
- return -1;
- off += rv;
- }
- return 0;
-}
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, (char *)buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0) {
- log_print("write fd %d errno %d", fd, errno);
- return rv;
- }
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-void read_ccs_name(const char *path, char *name)
-{
- char *str;
- int error;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return;
-
- strcpy(name, str);
-
- free(str);
-}
-
-void read_ccs_yesno(const char *path, int *yes, int *no)
-{
- char *str;
- int error;
-
- *yes = 0;
- *no = 0;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return;
-
- if (!strcmp(str, "yes"))
- *yes = 1;
-
- else if (!strcmp(str, "no"))
- *no = 1;
-
- free(str);
-}
-
-void read_ccs_int(const char *path, int *config_val)
-{
- char *str;
- int val;
- int error;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return;
-
- val = atoi(str);
-
- if (val < 0) {
- log_print("ignore invalid value %d for %s", val, path);
- return;
- }
-
- *config_val = val;
- log_debug("%s is %u", path, val);
- free(str);
-}
-
-#define GROUPD_COMPAT_PATH "/cluster/group/@groupd_compat"
-#define GROUPD_WAIT_PATH "/cluster/group/@groupd_wait"
-#define GROUPD_MODE_DELAY_PATH "/cluster/group/@groupd_mode_delay"
-
-static int setup_ccs(void)
-{
- int cd;
-
- cd = ccs_connect();
- if (cd < 0) {
- log_print("ccs_connect error %d %d", cd, errno);
- return -1;
- }
- ccs_handle = cd;
-
- /* These config values are set from cluster.conf only if they haven't
- already been set on the command line. */
-
- if (!optd_groupd_compat)
- read_ccs_int(GROUPD_COMPAT_PATH, &cfgd_groupd_compat);
-
- if (!optd_groupd_wait)
- read_ccs_int(GROUPD_WAIT_PATH, &cfgd_groupd_wait);
-
- if (!optd_groupd_mode_delay)
- read_ccs_int(GROUPD_MODE_DELAY_PATH, &cfgd_groupd_mode_delay);
-
- return 0;
-}
-
-static void close_ccs(void)
-{
- ccs_disconnect(ccs_handle);
-}
-
-static void app_action(app_t *a, char *buf)
-{
- int rv;
-
- log_group(a->g, "action for app: %s", buf);
-
- rv = do_write(client[a->client].fd, buf, GROUPD_MSGLEN);
- if (rv < 0)
- log_error(a->g, "app_action write error");
-}
-
-void app_deliver(app_t *a, struct save_msg *save)
-{
- char buf[GROUPD_MSGLEN];
- int rv;
-
- rv = snprintf(buf, sizeof(buf), "deliver %s %d %d",
- a->g->name, save->nodeid,
- (int)(save->msg_len - sizeof(msg_t)));
-
- log_group(a->g, "deliver to app: %s", buf);
-
- memcpy(buf + rv + 1, save->msg_long + sizeof(msg_t),
- save->msg_len - sizeof(msg_t));
-
- /*
- log_group(a->g, "app_deliver body len %d \"%s\"",
- save->msg_len - sizeof(msg_t),
- save->msg_long + sizeof(msg_t));
- */
-
- rv = do_write(client[a->client].fd, buf, GROUPD_MSGLEN);
- if (rv < 0)
- log_error(a->g, "app_deliver write error");
-}
-
-void app_terminate(app_t *a)
-{
- char buf[GROUPD_MSGLEN];
- snprintf(buf, sizeof(buf), "terminate %s", a->g->name);
- app_action(a, buf);
-}
-
-void app_stop(app_t *a)
-{
- char buf[GROUPD_MSGLEN];
- snprintf(buf, sizeof(buf), "stop %s", a->g->name);
- app_action(a, buf);
-}
-
-void app_setid(app_t *a)
-{
- char buf[GROUPD_MSGLEN];
- snprintf(buf, sizeof(buf), "setid %s %u", a->g->name, a->g->global_id);
- app_action(a, buf);
-}
-
-void app_start(app_t *a)
-{
- char buf[GROUPD_MSGLEN];
- int len = 0, type, count = 0;
- node_t *node;
-
- if (a->current_event->state == EST_JOIN_START_WAIT)
- type = NODE_JOIN;
- else if (a->current_event->state == EST_LEAVE_START_WAIT)
- type = NODE_LEAVE;
- else if (a->current_event->state == EST_FAIL_START_WAIT)
- type = NODE_FAILED;
- else {
- /* report error */
- type = -1;
- }
-
- /* start <name> <event_nr> <type> <count> <memb0> <memb1>... */
-
- list_for_each_entry(node, &a->nodes, list)
- count++;
-
- len = snprintf(buf, sizeof(buf), "start %s %d %d %d",
- a->g->name, a->current_event->event_nr, type, count);
-
- list_for_each_entry(node, &a->nodes, list)
- len += sprintf(buf+len, " %d", node->nodeid);
-
- app_action(a, buf);
-}
-
-void app_finish(app_t *a)
-{
- char buf[GROUPD_MSGLEN];
- snprintf(buf, sizeof(buf), "finish %s %d",
- a->g->name, a->current_event->event_nr);
- app_action(a, buf);
-}
-
-#define MAXARGS 16
-
-static char *get_args(char *buf, int *argc, char **argv, char sep, int want)
-{
- char *p = buf, *rp = NULL;
- int i;
-
- argv[0] = p;
-
- for (i = 1; i < MAXARGS; i++) {
- p = strchr(buf, sep);
- if (!p)
- break;
- *p = '\0';
-
- if (want == i) {
- rp = p + 1;
- break;
- }
-
- argv[i] = p + 1;
- buf = p + 1;
- }
- *argc = i;
-
- /* we ended by hitting \0, return the point following that */
- if (!rp)
- rp = strchr(buf, '\0') + 1;
-
- return rp;
-}
-
-enum {
- DO_SETUP = 1,
- DO_JOIN,
- DO_LEAVE,
- DO_STOP_DONE,
- DO_START_DONE,
- DO_SEND,
- DO_GET_GROUPS,
- DO_GET_GROUP,
- DO_DUMP,
- DO_LOG,
- DO_GET_VERSION,
-};
-
-static int get_action(char *buf)
-{
- char act[16];
- int i;
-
- memset(act, 0, 16);
-
- for (i = 0; i < 16; i++) {
- if (isalnum(buf[i]) || ispunct(buf[i]))
- act[i] = buf[i];
- else
- break;
- }
-
- /* for debug message */
- memset(&last_action, 0, 16);
- memcpy(last_action, act, 16);
-
- if (!strncmp(act, "setup", 16))
- return DO_SETUP;
-
- if (!strncmp(act, "join", 16))
- return DO_JOIN;
-
- if (!strncmp(act, "leave", 16))
- return DO_LEAVE;
-
- if (!strncmp(act, "stop_done", 16))
- return DO_STOP_DONE;
-
- if (!strncmp(act, "start_done", 16))
- return DO_START_DONE;
-
- if (!strncmp(act, "send", 16))
- return DO_SEND;
-
- if (!strncmp(act, "get_groups", 16))
- return DO_GET_GROUPS;
-
- if (!strncmp(act, "get_group", 16))
- return DO_GET_GROUP;
-
- if (!strncmp(act, "get_version", 16))
- return DO_GET_VERSION;
-
- if (!strncmp(act, "dump", 16))
- return DO_DUMP;
-
- if (!strncmp(act, "log", 16))
- return DO_LOG;
-
- return -1;
-}
-
-static void client_alloc(void)
-{
- int i;
-
- if (!client) {
- client = malloc(CLIENT_NALLOC * sizeof(struct client));
- pollfd = malloc(CLIENT_NALLOC * sizeof(struct pollfd));
- } else {
- client = realloc(client, (client_size + CLIENT_NALLOC) *
- sizeof(struct client));
- pollfd = realloc(pollfd, (client_size + CLIENT_NALLOC) *
- sizeof(struct pollfd));
- if (!pollfd)
- log_print("can't alloc for pollfd");
- }
- if (!client || !pollfd)
- log_print("can't alloc for client array");
-
- for (i = client_size; i < client_size + CLIENT_NALLOC; i++) {
- client[i].workfn = NULL;
- client[i].deadfn = NULL;
- client[i].fd = -1;
- client[i].level = -1;
- memset(client[i].type, 0, sizeof(client[i].type));
- pollfd[i].fd = -1;
- pollfd[i].revents = 0;
- }
- client_size += CLIENT_NALLOC;
-}
-
-void client_dead(int ci)
-{
- close(client[ci].fd);
- client[ci].workfn = NULL;
- client[ci].fd = -1;
- pollfd[ci].fd = -1;
-}
-
-int client_add(int fd, void (*workfn)(int ci), void (*deadfn)(int ci))
-{
- int i;
-
- if (!client)
- client_alloc();
- again:
- for (i = 0; i < client_size; i++) {
- if (client[i].fd == -1) {
- client[i].workfn = workfn;
- if (deadfn)
- client[i].deadfn = deadfn;
- else
- client[i].deadfn = client_dead;
- client[i].fd = fd;
- pollfd[i].fd = fd;
- pollfd[i].events = POLLIN;
- if (i > client_maxi)
- client_maxi = i;
- return i;
- }
- }
-
- client_alloc();
- goto again;
-}
-
-static void sigterm_handler(int sig)
-{
- daemon_quit = 1;
-}
-
-static void do_setup(int ci, int argc, char **argv)
-{
- log_debug("setup %s %s", argv[1], argv[2]);
-
- strcpy(client[ci].type, argv[1]);
- client[ci].level = atoi(argv[2]);
-}
-
-static void copy_group_data(group_t *g, group_data_t *data)
-{
- node_t *node;
- event_t *ev;
- int i = 0;
-
- strncpy(data->client_name, client[g->app->client].type, 32);
- strncpy(data->name, g->name, MAX_GROUP_NAME_LEN);
- data->level = g->level;
- data->id = g->global_id;
-
- if (g->app && g->app->current_event) {
- ev = g->app->current_event;
- data->event_state = ev->state;
- data->event_nodeid = ev->nodeid;
- data->event_id = ev->id;
- data->event_local_status = -2;
-
- node = find_app_node(g->app, our_nodeid);
- if (node) {
- if (event_state_stopping(g->app))
- data->event_local_status = node->stopped;
- else if (event_state_starting(g->app))
- data->event_local_status = node->started;
- else
- data->event_local_status = -1;
- }
- }
-
- data->member_count = g->app->node_count;
- list_for_each_entry(node, &g->app->nodes, list) {
- data->members[i] = node->nodeid;
- i++;
-
- if (node->nodeid == our_nodeid)
- data->member = 1;
- }
-
- /* we're in the member list but are still joining */
- if (data->member) {
- ev = g->app->current_event;
- if (ev && is_our_join(ev) &&
- (ev->state <= EST_JOIN_ALL_STARTED))
- data->member = 0;
- }
-}
-
-static int do_get_groups(int ci, int argc, char **argv)
-{
- group_t *g;
- group_data_t *data;
- int rv, count = 0, max = atoi(argv[1]);
-
- data = malloc(sizeof(group_data_t));
- // FIXME: handle failed malloc
- count = 0;
-
- list_for_each_entry(g, &gd_groups, list) {
- memset(data, 0, sizeof(group_data_t));
- copy_group_data(g, data);
- rv = do_write(client[ci].fd, data, sizeof(group_data_t));
- if (rv < 0) {
- log_print("do_get_groups write error");
- break;
- }
- count++;
- if (count >= max)
- break;
- }
- /* Now write an empty one indicating there aren't anymore: */
- memset(data, 0, sizeof(group_data_t));
- rv = do_write(client[ci].fd, data, sizeof(group_data_t));
- free(data);
- return 0;
-}
-
-static int do_get_group(int ci, int argc, char **argv)
-{
- group_t *g;
- group_data_t data;
- int rv;
-
- memset(&data, 0, sizeof(data));
-
- /* special case to get members of groupd cpg */
- if (atoi(argv[1]) == -1 && !strncmp(argv[2], "groupd", 6)) {
- copy_groupd_data(&data);
- goto out;
- }
-
- g = find_group_level(argv[2], atoi(argv[1]));
- if (!g)
- goto out;
-
- copy_group_data(g, &data);
- out:
- rv = do_write(client[ci].fd, &data, sizeof(data));
- if (rv < 0)
- log_print("do_get_group write error");
-
- return 0;
-}
-
-static int do_get_version(int ci)
-{
- int mode;
- int rv;
-
- if (group_mode == GROUP_PENDING)
- mode = -EAGAIN;
- else
- mode = group_mode;
-
- rv = do_write(client[ci].fd, &mode, sizeof(mode));
- if (rv < 0)
- log_print("do_get_version write error");
-
- return 0;
-}
-
-static int do_dump(int fd)
-{
- int len;
-
- if (dump_wrap) {
- len = GROUPD_DUMP_SIZE - dump_point;
- do_write(fd, dump_buf + dump_point, len);
- len = dump_point;
- } else
- len = dump_point;
-
- /* NUL terminate the debug string */
- dump_buf[dump_point] = '\0';
-
- do_write(fd, dump_buf, len);
-
- return 0;
-}
-
-static int do_log(int fd, const char *comment)
-{
- log_print("%s", comment);
- return 0;
-}
-
-static void do_send(char *name, int level, int len, char *data)
-{
- group_t *g;
- msg_t *msg;
- char *buf;
- int total;
-
- g = find_group_level(name, level);
- if (!g)
- return;
-
- total = sizeof(msg_t) + len;
- buf = malloc(total);
- // FIXME: handle failed malloc
- memset(buf, 0, total);
-
- memcpy(buf + sizeof(msg_t), data, len);
-
- msg = (msg_t *) buf;
- msg->ms_type = MSG_APP_INTERNAL;
- msg->ms_global_id = g->global_id;
-
- log_debug("%d:%s do_send %d bytes", level, name, total);
-
- send_message(g, msg, total);
-
- free(buf);
-}
-
-static void process_connection(int ci)
-{
- char buf[GROUPD_MSGLEN], *argv[MAXARGS], *p;
- int argc = 0, rv, act;
-
- memset(buf, 0, sizeof(buf));
- memset(argv, 0, sizeof(char *) * MAXARGS);
-
- rv = do_read(client[ci].fd, buf, GROUPD_MSGLEN);
- if (rv < 0) {
- client_dead(ci);
- return;
- }
-
- act = get_action(buf);
-
- log_debug("got client %d %s", ci, last_action);
-
- switch (act) {
-
- case DO_SETUP:
- get_args(buf, &argc, argv, ' ', 3);
- do_setup(ci, argc, argv);
- break;
-
- case DO_JOIN:
- get_args(buf, &argc, argv, ' ', 2);
- do_join(argv[1], client[ci].level, ci);
- break;
-
- case DO_LEAVE:
- get_args(buf, &argc, argv, ' ', 2);
- do_leave(argv[1], client[ci].level);
- break;
-
- case DO_STOP_DONE:
- get_args(buf, &argc, argv, ' ', 2);
- do_stopdone(argv[1], client[ci].level);
- break;
-
- case DO_START_DONE:
- get_args(buf, &argc, argv, ' ', 3);
- do_startdone(argv[1], client[ci].level, atoi(argv[2]));
- break;
-
- case DO_SEND:
- p = get_args(buf, &argc, argv, ' ', 3);
- do_send(argv[1], client[ci].level, atoi(argv[2]), p);
- break;
-
- case DO_GET_GROUPS:
- get_args(buf, &argc, argv, ' ', 2);
- do_get_groups(ci, argc, argv);
- break;
-
- case DO_GET_GROUP:
- get_args(buf, &argc, argv, ' ', 3);
- do_get_group(ci, argc, argv);
- break;
-
- case DO_GET_VERSION:
- do_get_version(ci);
- break;
-
- case DO_DUMP:
- do_dump(client[ci].fd);
- close(client[ci].fd);
- break;
-
- case DO_LOG:
- do_log(client[ci].fd, &buf[4]);
- break;
-
- default:
- log_print("unknown action %d client %d", act, ci);
- log_print("invalid message: \"%s\"", buf);
- }
-}
-
-static void process_listener(int ci)
-{
- int fd, i;
-
- fd = accept(client[ci].fd, NULL, NULL);
- if (fd < 0) {
- log_print("process_listener: accept error %d %d", fd, errno);
- return;
- }
-
- i = client_add(fd, process_connection, NULL);
-
- log_debug("client connection %d fd %d", i, fd);
-}
-
-static int setup_listener(const char *sock_path)
-{
- struct sockaddr_un addr;
- socklen_t addrlen;
- int rv, s;
-
- /* we listen for new client connections on socket s */
-
- s = socket(AF_LOCAL, SOCK_STREAM, 0);
- if (s < 0) {
- log_print("socket error %d %d", s, errno);
- return s;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- strcpy(&addr.sun_path[1], sock_path);
- addrlen = sizeof(sa_family_t) + strlen(addr.sun_path+1) + 1;
-
- rv = bind(s, (struct sockaddr *) &addr, addrlen);
- if (rv < 0) {
- log_print("bind error %d %d", rv, errno);
- close(s);
- return rv;
- }
-
- rv = listen(s, 5);
- if (rv < 0) {
- log_print("listen error %d %d", rv, errno);
- close(s);
- return rv;
- }
- return s;
-}
-
-void cluster_dead(int ci)
-{
- if (!cluster_down)
- log_print("cluster is down, exiting");
- daemon_quit = 1;
- cluster_down = 1;
-}
-
-#define min(x, y) ({ \
- typeof(x) _min1 = (x); \
- typeof(y) _min2 = (y); \
- (void) (&_min1 == &_min2); \
- _min1 < _min2 ? _min1 : _min2; })
-
-static void loop(void)
-{
- int poll_timeout = -1;
- int rv, i;
- void (*workfn) (int ci);
- void (*deadfn) (int ci);
-
- rv = setup_listener(GROUPD_SOCK_PATH);
- if (rv < 0)
- goto out;
- client_add(rv, process_listener, NULL);
-
- rv = setup_cman();
- if (rv < 0)
- goto out;
- client_add(rv, process_cman, cluster_dead);
-
- rv = setup_ccs();
- if (rv < 0)
- goto out;
-
- setup_logging();
-
- if (cfgd_groupd_compat == 0) {
- group_mode = GROUP_LIBCPG;
- log_level(LOG_INFO, "groupd compatibility mode 0 cfg");
- } else if (cfgd_groupd_compat == 1) {
- group_mode = GROUP_LIBGROUP;
- log_level(LOG_INFO, "groupd compatibility mode 1 cfg");
- } else if (cfgd_groupd_compat == 2) {
- group_mode = GROUP_PENDING;
- /* report the mode in set_group_mode() */
- }
-
- rv = setup_cpg();
- if (rv < 0)
- goto out;
-
- for (;;) {
- rv = poll(pollfd, client_maxi + 1, poll_timeout);
- if (rv == -1 && errno == EINTR) {
- if (daemon_quit && (group_mode == GROUP_LIBCPG ||
- list_empty(&gd_groups)))
- goto out;
- daemon_quit = 0;
- continue;
- }
- if (rv < 0) {
- log_print("poll errno %d", errno);
- goto out;
- }
-
- for (i = 0; i <= client_maxi; i++) {
- if (client[i].fd < 0)
- continue;
- if (pollfd[i].revents & POLLIN) {
- workfn = client[i].workfn;
- workfn(i);
- }
- if (pollfd[i].revents & (POLLERR | POLLHUP | POLLNVAL)) {
- deadfn = client[i].deadfn;
- deadfn(i);
- }
- }
-
- if (daemon_quit)
- break;
-
- /* process_apps() returns non-zero if there may be
- more work to do */
-
- do {
- rv = 0;
- rv += process_apps();
- } while (rv);
-
- poll_timeout = -1;
-
- if (group_mode == GROUP_PENDING) {
- group_mode_check_timeout();
- poll_timeout = 1000 * min(cfgd_groupd_wait, cfgd_groupd_mode_delay);
- }
- }
- out:
- close_cpg();
- close_ccs();
- close_cman();
-
- /* in LIBCPG mode, gd_groups is not empty because of the groups we
- add to "block" old versions of groupd */
- if ((group_mode == GROUP_LIBGROUP) && !list_empty(&gd_groups))
- log_print("groups abandoned");
-}
-
-static void lockfile(void)
-{
- int fd, error;
- struct flock lock;
- char buf[33];
-
- memset(buf, 0, 33);
-
- fd = open(LOCKFILE_NAME, O_CREAT|O_WRONLY,
- S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
- if (fd < 0) {
- 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, "groupd 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 print_usage(void)
-{
- printf("Usage:\n");
- printf("\n");
- printf("groupd [options]\n");
- printf("\n");
- printf("Options:\n");
- printf("\n");
- printf(" -D Enable debugging to stderr and don't fork\n");
- printf(" -L Enable debugging to log file\n");
- printf(" -g <num> group compatibility mode, 0 off, 1 on, 2 detect\n");
- printf(" 0: use libcpg, no backward compat, best performance\n");
- printf(" 1: use libgroup for compat with cluster2/rhel5\n");
- printf(" 2: detect old, or mode 1, nodes that require compat,\n"
- " use libcpg if none found\n");
- printf(" Default is %d\n", DEFAULT_GROUPD_COMPAT);
- printf(" -w <secs> seconds to wait for a node's version message before\n"
- " assuming an old version requiring compat mode\n");
- printf(" Default is %d\n", DEFAULT_GROUPD_WAIT);
- printf(" -d <secs> seconds to delay the mode selection to give time\n"
- " for an old version to join and force compat mode\n");
- printf(" Default is %d\n", DEFAULT_GROUPD_MODE_DELAY);
- printf(" -h Print this help, then exit\n");
- printf(" -V Print program version information, then exit\n");
-}
-
-#define OPTION_STRING "LDg:w:d:hVv"
-
-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':
- daemon_debug_opt = 1;
- break;
-
- case 'L':
- optd_debug_logfile = 1;
- cfgd_debug_logfile = 1;
- break;
-
- case 'g':
- optd_groupd_compat = 1;
- cfgd_groupd_compat = atoi(optarg);
- break;
-
- case 'w':
- optd_groupd_wait = 1;
- cfgd_groupd_wait = atoi(optarg);
- break;
-
- case 'd':
- optd_groupd_mode_delay = 1;
- cfgd_groupd_mode_delay = atoi(optarg);
- break;
-
- case 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case 'v':
- daemon_debug_verbose++;
- break;
-
- case 'V':
- printf("groupd %s (built %s %s)\n",
- RELEASE_VERSION, __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- break;
-
- case ':':
- case '?':
- fprintf(stderr, "Please use '-h' for usage.\n");
- exit(EXIT_FAILURE);
- break;
-
- case EOF:
- cont = FALSE;
- break;
-
- default:
- fprintf(stderr, "unknown option: %c\n", optchar);
- exit(EXIT_FAILURE);
- break;
- };
- }
-
- if (getenv("GROUPD_DEBUG")) {
- optd_debug_logfile = 1;
- cfgd_debug_logfile = 1;
- }
-}
-
-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)
- log_print("could not set SCHED_RR priority %d err %d",
- sched_param.sched_priority, errno);
- } else {
- log_print("could not get maximum scheduler priority err %d",
- errno);
- }
-}
-
-int main(int argc, char *argv[])
-{
- int i;
-
- INIT_LIST_HEAD(&recovery_sets);
- INIT_LIST_HEAD(&gd_groups);
- for (i = 0; i < MAX_LEVELS; i++)
- INIT_LIST_HEAD(&gd_levels[i]);
-
- read_arguments(argc, argv);
-
- if (!daemon_debug_opt) {
- if (daemon(0, 0) < 0) {
- perror("daemon error");
- exit(EXIT_FAILURE);
- }
- }
- lockfile();
- init_logging();
- log_level(LOG_INFO, "groupd %s", RELEASE_VERSION);
- signal(SIGTERM, sigterm_handler);
- set_scheduler();
-
- loop();
-
- unlink(LOCKFILE_NAME);
- return 0;
-}
-
-void daemon_dump_save(void)
-{
- int len, i;
-
- len = strlen(daemon_debug_buf);
-
- for (i = 0; i < len; i++) {
- dump_buf[dump_point++] = daemon_debug_buf[i];
-
- if (dump_point == GROUPD_DUMP_SIZE) {
- dump_point = 0;
- dump_wrap = 1;
- }
- }
-}
-
-int daemon_debug_opt;
-int daemon_debug_verbose;
-int daemon_quit;
-int cluster_down;
-int cman_quorate;
-int our_nodeid;
-char *our_name;
-char daemon_debug_buf[256];
-char dump_buf[GROUPD_DUMP_SIZE];
-int dump_point;
-int dump_wrap;
-struct list_head gd_groups;
-struct list_head gd_levels[MAX_LEVELS];
-uint32_t gd_event_nr;
-int group_mode;
-
-int optd_groupd_compat;
-int optd_groupd_wait;
-int optd_groupd_mode_delay;
-int optd_debug_logfile;
-
-int cfgd_groupd_compat = DEFAULT_GROUPD_COMPAT;
-int cfgd_groupd_wait = DEFAULT_GROUPD_WAIT;
-int cfgd_groupd_mode_delay = DEFAULT_GROUPD_MODE_DELAY;
-int cfgd_debug_logfile = DEFAULT_DEBUG_LOGFILE;
-
diff --git a/group/dlm_controld/Makefile b/group/dlm_controld/Makefile
deleted file mode 100644
index 39c2b74..0000000
--- a/group/dlm_controld/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-include ../../make/defines.mk
-
-TARGET = dlm_controld
-SBINDIRT = ${TARGET}
-
-all: depends ${TARGET}
-
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-OBJS= action.o \
- cpg.o \
- crc.o \
- deadlock.o \
- main.o \
- netlink.o \
- plock.o \
- group.o \
- config.o \
- member_cman.o \
- logging.o
-
-CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${logtincdir}
-CFLAGS += -I${dlmincdir} -I${dlmcontrolincdir}
-CFLAGS += -I${corosyncincdir} -I${openaisincdir}
-CFLAGS += -I${fencedincdir}
-CFLAGS += -I${KERNEL_SRC}/include/
-CFLAGS += -I$(S)/../lib/ -I$(S)/../include/
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${logtlibdir} -llogthread
-LDFLAGS += -L${ccslibdir} -L${cmanlibdir} -lccs -lcman
-LDFLAGS += -L${dlmlibdir} -L${fencedlibdir} -ldlm -lfenced
-LDFLAGS += -L${openaislibdir} -lSaCkpt
-LDFLAGS += -L${corosynclibdir} -lcpg -lconfdb
-LDFLAGS += -lpthread
-LDFLAGS += -L../lib -lgroup
-LDFLAGS += -L${libdir}
-
-LDDEPS += ../lib/libgroup.a
-
-${TARGET}: ${OBJS} ${LDDEPS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-depends:
- $(MAKE) -C ../lib all
-
-clean: generalclean
-
--include $(OBJS:.o=.Tpo)
diff --git a/group/dlm_controld/action.c b/group/dlm_controld/action.c
deleted file mode 100644
index 56401a3..0000000
--- a/group/dlm_controld/action.c
+++ /dev/null
@@ -1,1089 +0,0 @@
-#include "dlm_daemon.h"
-#include "config.h"
-
-#include <corosync/corotypes.h>
-#include <corosync/confdb.h>
-
-static int dir_members[MAX_NODES];
-static int dir_members_count;
-static int comms_nodes[MAX_NODES];
-static int comms_nodes_count;
-static char mg_name[DLM_LOCKSPACE_LEN+1];
-
-#define DLM_SYSFS_DIR "/sys/kernel/dlm"
-#define CLUSTER_DIR "/sys/kernel/config/dlm/cluster"
-#define SPACES_DIR "/sys/kernel/config/dlm/cluster/spaces"
-#define COMMS_DIR "/sys/kernel/config/dlm/cluster/comms"
-
-static int detect_protocol(void)
-{
- confdb_handle_t handle;
- hdb_handle_t totem_handle;
- char key_value[256];
- size_t value_len;
- int rv, proto = -1;
- confdb_callbacks_t callbacks = {
- .confdb_key_change_notify_fn = NULL,
- .confdb_object_create_change_notify_fn = NULL,
- .confdb_object_delete_change_notify_fn = NULL
- };
-
- rv = confdb_initialize(&handle, &callbacks);
- if (rv != CS_OK) {
- log_error("confdb_initialize error %d", rv);
- return -1;
- }
-
- rv = confdb_object_find_start(handle, OBJECT_PARENT_HANDLE);
- if (rv != CS_OK) {
- log_error("confdb_object_find_start error %d", rv);
- goto out;
- }
-
- rv = confdb_object_find(handle, OBJECT_PARENT_HANDLE,
- "totem", strlen("totem"), &totem_handle);
- if (rv != CS_OK) {
- log_error("confdb_object_find error %d", rv);
- goto out;
- }
-
- rv = confdb_key_get(handle, totem_handle,
- "rrp_mode", strlen("rrp_mode"),
- key_value, &value_len);
- if (rv != CS_OK) {
- log_error("confdb_key_get error %d", rv);
- goto out;
- }
-
- key_value[value_len] = '\0';
- log_debug("totem/rrp_mode = '%s'", key_value);
-
- if (!strcmp(key_value, "none"))
- proto = PROTO_TCP;
- else
- proto = PROTO_SCTP;
- out:
- confdb_finalize(handle);
- return proto;
-}
-
-/* look for an id that matches in e.g. /sys/fs/gfs/bull\:x/lock_module/id
- and then extract the "x" as the name */
-
-static int get_mountgroup_name(uint32_t mg_id)
-{
- char path[PATH_MAX];
- char *fsname;
- const char *fsdir;
- DIR *d;
- FILE *file;
- struct dirent *de;
- uint32_t id;
- int retry_gfs2 = 1;
- int rv, error;
-
- fsdir = "/sys/fs/gfs";
- retry:
- rv = -1;
-
- d = opendir(fsdir);
- if (!d) {
- log_debug("%s: opendir failed: %d", path, errno);
- goto out;
- }
-
- while ((de = readdir(d))) {
- if (de->d_name[0] == '.')
- continue;
-
- id = 0;
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%s/lock_module/id",
- fsdir, de->d_name);
-
- file = fopen(path, "r");
- if (!file) {
- log_error("can't open %s %d", path, errno);
- continue;
- }
-
- error = fscanf(file, "%u", &id);
- fclose(file);
-
- if (error != 1) {
- log_error("bad read %s %d", path, errno);
- continue;
- }
- if (id != mg_id) {
- log_debug("get_mountgroup_name skip %x %s",
- id, de->d_name);
- continue;
- }
-
- /* take the fsname out of clustername:fsname */
- fsname = strstr(de->d_name, ":");
- if (!fsname) {
- log_debug("get_mountgroup_name skip2 %x %s",
- id, de->d_name);
- continue;
- }
- fsname++;
-
- log_debug("get_mountgroup_name found %x %s %s",
- id, de->d_name, fsname);
- strncpy(mg_name, fsname, sizeof(mg_name));
- rv = 0;
- break;
- }
-
- closedir(d);
-
- out:
- if (rv && retry_gfs2) {
- retry_gfs2 = 0;
- fsdir = "/sys/fs/gfs2";
- goto retry;
- }
-
- return rv;
-}
-
-/* This is for the case where dlm_controld exits/fails, abandoning dlm
- lockspaces in the kernel, and then dlm_controld is restarted. When
- dlm_controld exits and abandons lockspaces, that node needs to be
- rebooted to clear the uncontrolled lockspaces from the kernel. */
-
-int check_uncontrolled_lockspaces(void)
-{
- DIR *d;
- struct dirent *de;
- int count = 0;
-
- d = opendir(DLM_SYSFS_DIR);
- if (!d)
- return 0;
-
- while ((de = readdir(d))) {
- if (de->d_name[0] == '.')
- continue;
-
- log_error("found uncontrolled lockspace %s", de->d_name);
- count++;
- }
- closedir(d);
-
- if (count) {
- kick_node_from_cluster(our_nodeid);
- return -1;
- }
- return 0;
-}
-
-/* find the mountgroup with "mg_id" in sysfs, get it's name, then look for
- the ls with with the same name in lockspaces list, return its id */
-
-void set_associated_id(uint32_t mg_id)
-{
- struct lockspace *ls;
- int rv;
-
- log_debug("set_associated_id mg_id %x %d", mg_id, mg_id);
-
- memset(&mg_name, 0, sizeof(mg_name));
-
- rv = get_mountgroup_name(mg_id);
- if (rv) {
- log_error("no mountgroup found with id %x", mg_id);
- return;
- }
-
- ls = find_ls(mg_name);
- if (!ls) {
- log_error("no lockspace found with name %s for mg_id %x",
- mg_name, mg_id);
- return;
- }
-
- log_debug("set_associated_id mg %x is ls %x", mg_id, ls->global_id);
-
- ls->associated_mg_id = mg_id;
-}
-
-static int do_sysfs(const char *name, const char *file, char *val)
-{
- char fname[512];
- int rv, fd;
-
- sprintf(fname, "%s/%s/%s", DLM_SYSFS_DIR, name, file);
-
- fd = open(fname, O_WRONLY);
- if (fd < 0) {
- log_error("open \"%s\" error %d %d", fname, fd, errno);
- return -1;
- }
-
- log_debug("write \"%s\" to \"%s\"", val, fname);
-
- rv = do_write(fd, val, strlen(val) + 1);
- close(fd);
- return rv;
-}
-
-int set_sysfs_control(char *name, int val)
-{
- char buf[32];
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, 32, "%d", val);
-
- return do_sysfs(name, "control", buf);
-}
-
-int set_sysfs_event_done(char *name, int val)
-{
- char buf[32];
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, 32, "%d", val);
-
- return do_sysfs(name, "event_done", buf);
-}
-
-int set_sysfs_id(char *name, uint32_t id)
-{
- char buf[32];
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, 32, "%u", id);
-
- return do_sysfs(name, "id", buf);
-}
-
-static int update_dir_members(char *name)
-{
- char path[PATH_MAX];
- DIR *d;
- struct dirent *de;
- int i = 0;
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%s/nodes", SPACES_DIR, name);
-
- d = opendir(path);
- if (!d) {
- log_debug("%s: opendir failed: %d", path, errno);
- return -1;
- }
-
- memset(dir_members, 0, sizeof(dir_members));
- dir_members_count = 0;
-
- /* FIXME: we should probably read the nodeid in each dir instead */
-
- while ((de = readdir(d))) {
- if (de->d_name[0] == '.')
- continue;
- dir_members[i++] = atoi(de->d_name);
- log_debug("dir_member %d", dir_members[i-1]);
- }
- closedir(d);
-
- dir_members_count = i;
- return 0;
-}
-
-static int id_exists(int id, int count, int *array)
-{
- int i;
- for (i = 0; i < count; i++) {
- if (array[i] == id)
- return 1;
- }
- return 0;
-}
-
-static int create_path(const char *path)
-{
- mode_t old_umask;
- int rv;
-
- old_umask = umask(0022);
- rv = mkdir(path, 0777);
- if (rv < 0 && errno == EEXIST)
- rv = 0;
- if (rv < 0)
- log_error("%s: mkdir failed: %d", path, errno);
- umask(old_umask);
- return rv;
-}
-
-static int path_exists(const char *path)
-{
- struct stat buf;
-
- if (stat(path, &buf) < 0) {
- if (errno != ENOENT)
- log_error("%s: stat failed: %d", path, errno);
- return 0;
- }
- return 1;
-}
-
-/* The "renew" nodes are those that have left and rejoined since the last
- call to set_members(). We rmdir/mkdir for these nodes so dlm-kernel
- can notice they've left and rejoined. */
-
-int set_configfs_members(char *name, int new_count, int *new_members,
- int renew_count, int *renew_members)
-{
- char path[PATH_MAX];
- char buf[32];
- int i, w, fd, rv, id, old_count, *old_members;
- int do_renew;
-
- /*
- * create lockspace dir if it doesn't exist yet
- */
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%s", SPACES_DIR, name);
-
- if (!path_exists(path)) {
- if (create_path(path))
- return -1;
- }
-
- /*
- * remove/add lockspace members
- */
-
- rv = update_dir_members(name);
- if (rv)
- return rv;
-
- old_members = dir_members;
- old_count = dir_members_count;
-
- for (i = 0; i < old_count; i++) {
- id = old_members[i];
- if (id_exists(id, new_count, new_members))
- continue;
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%s/nodes/%d",
- SPACES_DIR, name, id);
-
- log_debug("set_members rmdir \"%s\"", path);
-
- rv = rmdir(path);
- if (rv) {
- log_error("%s: rmdir failed: %d", path, errno);
- goto out;
- }
- }
-
- /*
- * remove lockspace dir after we've removed all the nodes
- * (when we're shutting down and adding no new nodes)
- */
-
- if (!new_count) {
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%s", SPACES_DIR, name);
-
- log_debug("set_members lockspace rmdir \"%s\"", path);
-
- rv = rmdir(path);
- if (rv)
- log_error("%s: rmdir failed: %d", path, errno);
- }
-
- for (i = 0; i < new_count; i++) {
- id = new_members[i];
-
- do_renew = 0;
-
- if (id_exists(id, renew_count, renew_members))
- do_renew = 1;
- else if (id_exists(id, old_count, old_members))
- continue;
-
- if (!is_cluster_member(id))
- update_cluster();
- /*
- * create node's dir
- */
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%s/nodes/%d",
- SPACES_DIR, name, id);
-
- if (do_renew) {
- log_debug("set_members renew rmdir \"%s\"", path);
- rv = rmdir(path);
- if (rv) {
- log_error("%s: renew rmdir failed: %d",
- path, errno);
-
- /* don't quit here, there's a case where
- * this can happen, where a node identified
- * for renewal was not really added
- * previously */
- }
- }
-
- log_debug("set_members mkdir \"%s\"", path);
-
- rv = create_path(path);
- if (rv)
- goto out;
-
- /*
- * set node's nodeid
- */
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%s/nodes/%d/nodeid",
- SPACES_DIR, name, id);
-
- rv = fd = open(path, O_WRONLY);
- if (rv < 0) {
- log_error("%s: open failed: %d", path, errno);
- goto out;
- }
-
- memset(buf, 0, 32);
- snprintf(buf, 32, "%d", id);
-
- rv = do_write(fd, buf, strlen(buf));
- if (rv < 0) {
- log_error("%s: write failed: %d, %s", path, errno, buf);
- close(fd);
- goto out;
- }
- close(fd);
-
- /*
- * set node's weight
- */
-
- w = get_weight(id, name);
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%s/nodes/%d/weight",
- SPACES_DIR, name, id);
-
- rv = fd = open(path, O_WRONLY);
- if (rv < 0) {
- log_error("%s: open failed: %d", path, errno);
- goto out;
- }
-
- memset(buf, 0, 32);
- snprintf(buf, 32, "%d", w);
-
- rv = do_write(fd, buf, strlen(buf));
- if (rv < 0) {
- log_error("%s: write failed: %d, %s", path, errno, buf);
- close(fd);
- goto out;
- }
- close(fd);
- }
-
- rv = 0;
- out:
- return rv;
-}
-
-#if 0
-char *str_ip(char *addr)
-{
- static char ip[256];
- struct sockaddr_in *sin = (struct sockaddr_in *) addr;
- memset(ip, 0, sizeof(ip));
- inet_ntop(AF_INET, &sin->sin_addr, ip, 256);
- return ip;
-}
-#endif
-
-static char *str_ip(char *addr)
-{
- static char str_ip_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, str_ip_buf, sizeof(str_ip_buf));
- return str_ip_buf;
-}
-
-/* record the nodeids that are currently listed under
- config/dlm/cluster/comms/ so that we can remove all of them */
-
-static int update_comms_nodes(void)
-{
- char path[PATH_MAX];
- DIR *d;
- struct dirent *de;
- int i = 0;
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, COMMS_DIR);
-
- d = opendir(path);
- if (!d) {
- log_debug("%s: opendir failed: %d", path, errno);
- return -1;
- }
-
- memset(comms_nodes, 0, sizeof(comms_nodes));
- comms_nodes_count = 0;
-
- while ((de = readdir(d))) {
- if (de->d_name[0] == '.')
- continue;
- comms_nodes[i++] = atoi(de->d_name);
- }
- closedir(d);
-
- comms_nodes_count = i;
- return 0;
-}
-
-/* clear out everything under config/dlm/cluster/comms/ */
-
-static void clear_configfs_comms(void)
-{
- char path[PATH_MAX];
- int i, rv;
-
- rv = update_comms_nodes();
- if (rv < 0)
- return;
-
- for (i = 0; i < comms_nodes_count; i++) {
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%d", COMMS_DIR, comms_nodes[i]);
-
- log_debug("clear_configfs_nodes rmdir \"%s\"", path);
-
- rv = rmdir(path);
- if (rv)
- log_error("%s: rmdir failed: %d", path, errno);
- }
-}
-
-static void clear_configfs_space_nodes(char *name)
-{
- char path[PATH_MAX];
- int i, rv;
-
- rv = update_dir_members(name);
- if (rv < 0)
- return;
-
- for (i = 0; i < dir_members_count; i++) {
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%s/nodes/%d",
- SPACES_DIR, name, dir_members[i]);
-
- log_debug("clear_configfs_space_nodes rmdir \"%s\"", path);
-
- rv = rmdir(path);
- if (rv)
- log_error("%s: rmdir failed: %d", path, errno);
- }
-}
-
-/* clear out everything under config/dlm/cluster/spaces/ */
-
-static void clear_configfs_spaces(void)
-{
- char path[PATH_MAX];
- DIR *d;
- struct dirent *de;
- int rv;
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s", SPACES_DIR);
-
- d = opendir(path);
- if (!d) {
- log_debug("%s: opendir failed: %d", path, errno);
- return;
- }
-
- while ((de = readdir(d))) {
- if (de->d_name[0] == '.')
- continue;
-
- clear_configfs_space_nodes(de->d_name);
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%s", SPACES_DIR, de->d_name);
-
- log_debug("clear_configfs_spaces rmdir \"%s\"", path);
-
- rv = rmdir(path);
- if (rv)
- log_error("%s: rmdir failed: %d", path, errno);
- }
- closedir(d);
-}
-
-static int add_configfs_base(void)
-{
- int rv = 0;
-
- if (!path_exists("/sys/kernel/config")) {
- log_error("No /sys/kernel/config, is configfs loaded?");
- return -1;
- }
-
- if (!path_exists("/sys/kernel/config/dlm")) {
- log_error("No /sys/kernel/config/dlm, is the dlm loaded?");
- return -1;
- }
-
- if (!path_exists("/sys/kernel/config/dlm/cluster"))
- rv = create_path("/sys/kernel/config/dlm/cluster");
-
- return rv;
-}
-
-int add_configfs_node(int nodeid, char *addr, int addrlen, int local)
-{
- char path[PATH_MAX];
- char padded_addr[sizeof(struct sockaddr_storage)];
- char buf[32];
- int rv, fd;
-
- log_debug("set_configfs_node %d %s local %d",
- nodeid, str_ip(addr), local);
-
- /*
- * create comm dir for this node
- */
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%d", COMMS_DIR, nodeid);
-
- rv = create_path(path);
- if (rv)
- return -1;
-
- /*
- * set the nodeid
- */
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%d/nodeid", COMMS_DIR, nodeid);
-
- fd = open(path, O_WRONLY);
- if (fd < 0) {
- log_error("%s: open failed: %d", path, errno);
- return -1;
- }
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, 32, "%d", nodeid);
-
- rv = do_write(fd, buf, strlen(buf));
- if (rv < 0) {
- log_error("%s: write failed: %d, %s", path, errno, buf);
- close(fd);
- return -1;
- }
- close(fd);
-
- /*
- * set the address
- */
-
- memset(padded_addr, 0, sizeof(padded_addr));
- memcpy(padded_addr, addr, addrlen);
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%d/addr", COMMS_DIR, nodeid);
-
- fd = open(path, O_WRONLY);
- if (fd < 0) {
- log_error("%s: open failed: %d", path, errno);
- return -1;
- }
-
- rv = do_write(fd, padded_addr, sizeof(struct sockaddr_storage));
- if (rv < 0) {
- log_error("%s: write failed: %d %d", path, errno, rv);
- close(fd);
- return -1;
- }
- close(fd);
-
- /*
- * set local
- */
-
- if (!local)
- goto out;
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%d/local", COMMS_DIR, nodeid);
-
- fd = open(path, O_WRONLY);
- if (fd < 0) {
- log_error("%s: open failed: %d", path, errno);
- return -1;
- }
-
- rv = do_write(fd, (void *)"1", strlen("1"));
- if (rv < 0) {
- log_error("%s: write failed: %d", path, errno);
- close(fd);
- return -1;
- }
- close(fd);
- out:
- return 0;
-}
-
-void del_configfs_node(int nodeid)
-{
- char path[PATH_MAX];
- int rv;
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/%d", COMMS_DIR, nodeid);
-
- log_debug("del_configfs_node rmdir \"%s\"", path);
-
- rv = rmdir(path);
- if (rv)
- log_error("%s: rmdir failed: %d", path, errno);
-}
-
-static int set_configfs_protocol(int proto)
-{
- char path[PATH_MAX];
- char buf[32];
- int fd, rv;
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/protocol", CLUSTER_DIR);
-
- fd = open(path, O_WRONLY);
- if (fd < 0) {
- log_error("%s: open failed: %d", path, errno);
- return fd;
- }
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, 32, "%d", proto);
-
- rv = do_write(fd, buf, strlen(buf));
- if (rv < 0) {
- log_error("%s: write failed: %d", path, errno);
- return rv;
- }
- close(fd);
- log_debug("set protocol %d", proto);
- return 0;
-}
-
-static int set_configfs_timewarn(int cs)
-{
- char path[PATH_MAX];
- char buf[32];
- int fd, rv;
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/timewarn_cs", CLUSTER_DIR);
-
- fd = open(path, O_WRONLY);
- if (fd < 0) {
- log_error("%s: open failed: %d", path, errno);
- return fd;
- }
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, 32, "%d", cs);
-
- rv = do_write(fd, buf, strlen(buf));
- if (rv < 0) {
- log_error("%s: write failed: %d", path, errno);
- return rv;
- }
- close(fd);
- log_debug("set timewarn_cs %d", cs);
- return 0;
-}
-
-static int set_configfs_debug(int val)
-{
- char path[PATH_MAX];
- char buf[32];
- int fd, rv;
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "%s/log_debug", CLUSTER_DIR);
-
- fd = open(path, O_WRONLY);
- if (fd < 0) {
- log_error("%s: open failed: %d", path, errno);
- return fd;
- }
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, 32, "%d", val);
-
- rv = do_write(fd, buf, strlen(buf));
- if (rv < 0) {
- log_error("%s: write failed: %d", path, errno);
- return rv;
- }
- close(fd);
- log_debug("set log_debug %d", val);
- return 0;
-}
-
-#define NET_RMEM_DEFAULT 4194304
-#define NET_RMEM_MAX 4194304
-
-static int set_proc_rmem(void)
-{
- char path[PATH_MAX];
- char buf[32];
- int fd, rv;
-
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "/proc/sys/net/core/rmem_default");
-
- fd = open(path, O_RDWR);
- if (fd < 0) {
- log_error("%s: open failed: %d", path, errno);
- return fd;
- }
-
- memset(buf, 0, sizeof(buf));
-
- rv = read(fd, buf, sizeof(buf));
- if (rv < 0) {
- log_error("%s: read failed: %d", path, errno);
- close(fd);
- return rv;
- }
-
- if (atoi(buf) >= NET_RMEM_DEFAULT) {
- close(fd);
- goto next;
- }
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, 32, "%d", NET_RMEM_DEFAULT);
-
- rv = do_write(fd, buf, strlen(buf));
- if (rv < 0) {
- log_error("%s: write failed: %d", path, errno);
- close(fd);
- return rv;
- }
-
- close(fd);
- log_debug("set %s %s", path, buf);
-
- next:
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX, "/proc/sys/net/core/rmem_max");
-
- fd = open(path, O_RDWR);
- if (fd < 0) {
- log_error("%s: open failed: %d", path, errno);
- return fd;
- }
-
- memset(buf, 0, sizeof(buf));
-
- rv = read(fd, buf, sizeof(buf));
- if (rv < 0) {
- log_error("%s: read failed: %d", path, errno);
- close(fd);
- return rv;
- }
-
- if (atoi(buf) >= NET_RMEM_MAX) {
- close(fd);
- goto out;
- }
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, 32, "%d", NET_RMEM_MAX);
-
- rv = do_write(fd, buf, strlen(buf));
- if (rv < 0) {
- log_error("%s: write failed: %d", path, errno);
- close(fd);
- return rv;
- }
-
- close(fd);
- log_debug("set %s %s", path, buf);
- out:
- return 0;
-}
-
-void clear_configfs(void)
-{
- clear_configfs_comms();
- clear_configfs_spaces();
- rmdir("/sys/kernel/config/dlm/cluster");
-}
-
-int setup_configfs(void)
-{
- int rv;
-
- clear_configfs();
-
- rv = add_configfs_base();
- if (rv < 0)
- return rv;
-
- /* add configfs entries for existing nodes */
- update_cluster();
-
- /* the kernel has its own defaults for these values which we
- don't want to change unless these have been set; -1 means
- they have not been set on command line or config file */
-
- if (cfgk_debug != -1)
- set_configfs_debug(cfgk_debug);
- if (cfgk_timewarn != -1)
- set_configfs_timewarn(cfgk_timewarn);
-
- if (cfgk_protocol == PROTO_DETECT) {
- rv = detect_protocol();
- if (rv == PROTO_TCP || rv == PROTO_SCTP)
- cfgk_protocol = rv;
- }
-
- if (cfgk_protocol == PROTO_TCP || cfgk_protocol == PROTO_SCTP)
- set_configfs_protocol(cfgk_protocol);
-
- if (cfgk_protocol == PROTO_SCTP)
- set_proc_rmem();
-
- return 0;
-}
-
-static void find_minors(void)
-{
- FILE *fl;
- char name[256];
- uint32_t number;
- int found = 0;
- int c;
-
- control_minor = 0;
- monitor_minor = 0;
- plock_minor = 0;
- old_plock_minor = 0;
-
- if (!(fl = fopen("/proc/misc", "r"))) {
- log_error("/proc/misc fopen failed: %s", strerror(errno));
- return;
- }
-
- while (!feof(fl)) {
- if (fscanf(fl, "%d %255s\n", &number, &name[0]) == 2) {
-
- if (!strcmp(name, "dlm-control")) {
- control_minor = number;
- found++;
- } else if (!strcmp(name, "dlm-monitor")) {
- monitor_minor = number;
- found++;
- } else if (!strcmp(name, "dlm_plock")) {
- plock_minor = number;
- found++;
- } else if (!strcmp(name, "lock_dlm_plock")) {
- old_plock_minor = number;
- found++;
- }
-
- } else do {
- c = fgetc(fl);
- } while (c != EOF && c != '\n');
-
- if (found == 3)
- break;
- }
- fclose(fl);
-
- if (!found)
- log_error("Is dlm missing from kernel? No misc devices found.");
-}
-
-static int find_udev_device(const char *path, uint32_t minor)
-{
- struct stat st;
- int i;
-
- for (i = 0; i < 10; i++) {
- if (stat(path, &st) == 0 && minor(st.st_rdev) == minor)
- return 0;
- sleep(1);
- }
-
- log_error("cannot find device %s with minor %d", path, minor);
- return -1;
-}
-
-int setup_misc_devices(void)
-{
- int rv;
-
- find_minors();
-
- if (control_minor) {
- rv = find_udev_device("/dev/misc/dlm-control", control_minor);
- if (rv < 0)
- return rv;
- log_debug("found /dev/misc/dlm-control minor %u",
- control_minor);
- }
-
- if (monitor_minor) {
- rv = find_udev_device("/dev/misc/dlm-monitor", monitor_minor);
- if (rv < 0)
- return rv;
- log_debug("found /dev/misc/dlm-monitor minor %u",
- monitor_minor);
- }
-
- if (plock_minor) {
- rv = find_udev_device("/dev/misc/dlm_plock", plock_minor);
- if (rv < 0)
- return rv;
- log_debug("found /dev/misc/dlm_plock minor %u",
- plock_minor);
- }
-
- if (!plock_minor && old_plock_minor) {
- rv = find_udev_device("/dev/misc/lock_dlm_plock",
- old_plock_minor);
- if (rv < 0)
- return rv;
- log_debug("found /dev/misc/lock_dlm_plock minor %u",
- old_plock_minor);
- }
-
- return 0;
-}
-
diff --git a/group/dlm_controld/config.c b/group/dlm_controld/config.c
deleted file mode 100644
index 1720e7a..0000000
--- a/group/dlm_controld/config.c
+++ /dev/null
@@ -1,306 +0,0 @@
-#include <sys/types.h>
-#include <asm/types.h>
-#include <sys/uio.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <unistd.h>
-#include <dirent.h>
-
-#include "dlm_daemon.h"
-#include "config.h"
-#include "ccs.h"
-
-int ccs_handle;
-
-/* when not set in cluster.conf, a node's default weight is 1 */
-
-#define MASTER_PATH "/cluster/dlm/lockspace[@name=\"%s\"]/master"
-#define WEIGHT_PATH "/cluster/clusternodes/clusternode[@name=\"%s\"]/@weight"
-#define MASTER_NAME MASTER_PATH "/@name"
-#define MASTER_WEIGHT MASTER_PATH "[@name=\"%s\"]/@weight"
-
-/* look for node's weight in the dlm/lockspace section */
-
-static int get_weight_lockspace(char *node, char *lockspace)
-{
- char path[PATH_MAX], *str;
- int error, weight;
- int master_count = 0, node_is_master = 0;
-
- memset(path, 0, PATH_MAX);
- sprintf(path, MASTER_NAME, lockspace);
-
- while (1) {
- error = ccs_get_list(ccs_handle, path, &str);
- if (error || !str)
- break;
- master_count++;
- if (strcmp(str, node) == 0)
- node_is_master = 1;
- free(str);
- }
-
- /* if there are no masters, next check for a clusternode weight */
-
- if (!master_count)
- return -1;
-
- /* if there's a master and this node isn't it, it gets weight 0 */
-
- if (!node_is_master)
- return 0;
-
- /* master gets its specified weight or 1 if none is given */
-
- memset(path, 0, PATH_MAX);
- sprintf(path, MASTER_WEIGHT, lockspace, node);
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return 1;
-
- weight = atoi(str);
- free(str);
- return weight;
-}
-
-/* look for node's weight on its clusternode line */
-
-static int get_weight_clusternode(char *node, char *lockspace)
-{
- char path[PATH_MAX], *str;
- int error, weight;
-
- memset(path, 0, PATH_MAX);
- sprintf(path, WEIGHT_PATH, node);
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return -1;
-
- weight = atoi(str);
- free(str);
- return weight;
-}
-
-int get_weight(int nodeid, char *lockspace)
-{
- char *node;
- int w;
-
- node = nodeid2name(nodeid);
- if (!node) {
- log_error("no name for nodeid %d", nodeid);
- w = 1;
- goto out;
- }
-
- w = get_weight_lockspace(node, lockspace);
- if (w >= 0)
- goto out;
-
- w = get_weight_clusternode(node, lockspace);
- if (w >= 0)
- goto out;
-
- /* default weight is 1 */
- w = 1;
- out:
- return w;
-}
-
-void read_ccs_name(const char *path, char *name)
-{
- char *str;
- int error;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return;
-
- strcpy(name, str);
-
- free(str);
-}
-
-void read_ccs_yesno(const char *path, int *yes, int *no)
-{
- char *str;
- int error;
-
- *yes = 0;
- *no = 0;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return;
-
- if (!strcmp(str, "yes"))
- *yes = 1;
-
- else if (!strcmp(str, "no"))
- *no = 1;
-
- free(str);
-}
-
-int read_ccs_int(const char *path, int *config_val)
-{
- char *str;
- int val;
- int error;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return -1;
-
- val = atoi(str);
-
- if (val < 0) {
- log_error("ignore invalid value %d for %s", val, path);
- return -1;
- }
-
- *config_val = val;
- log_debug("%s is %u", path, val);
- free(str);
- return 0;
-}
-
-static void read_ccs_protocol(const char *path, int *config_val)
-{
- char *str;
- int val;
- int error;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return;
-
- if (!strncasecmp(str, "tcp", 3))
- val = PROTO_TCP;
- else if (!strncasecmp(str, "sctp", 4))
- val = PROTO_SCTP;
- else if (!strncasecmp(str, "detect", 6))
- val = PROTO_DETECT;
- else {
- log_error("ignore invalid value %s for %s", str, path);
- return;
- }
-
- *config_val = val;
- log_debug("%s is %u (%s)", path, val, str);
- free(str);
-}
-
-#define DEBUG_PATH "/cluster/dlm/@log_debug"
-#define TIMEWARN_PATH "/cluster/dlm/@timewarn"
-#define PROTOCOL_PATH "/cluster/dlm/@protocol"
-#define GROUPD_COMPAT_PATH "/cluster/group/@groupd_compat"
-#define ENABLE_FENCING_PATH "/cluster/dlm/@enable_fencing"
-#define ENABLE_QUORUM_PATH "/cluster/dlm/@enable_quorum"
-#define ENABLE_DEADLK_PATH "/cluster/dlm/@enable_deadlk"
-#define ENABLE_PLOCK_PATH "/cluster/dlm/@enable_plock"
-#define PLOCK_DEBUG_PATH "/cluster/dlm/@plock_debug"
-#define PLOCK_RATE_LIMIT_PATH "/cluster/dlm/@plock_rate_limit"
-#define PLOCK_OWNERSHIP_PATH "/cluster/dlm/@plock_ownership"
-#define DROP_RESOURCES_TIME_PATH "/cluster/dlm/@drop_resources_time"
-#define DROP_RESOURCES_COUNT_PATH "/cluster/dlm/@drop_resources_count"
-#define DROP_RESOURCES_AGE_PATH "/cluster/dlm/@drop_resources_age"
-
-/* for backward-compat */
-#define GFS_PLOCK_RATE_LIMIT_PATH "/cluster/gfs_controld/@plock_rate_limit"
-#define GFS_PLOCK_OWNERSHIP_PATH "/cluster/gfs_controld/@plock_ownership"
-#define GFS_DROP_RESOURCES_TIME_PATH "/cluster/gfs_controld/@drop_resources_time"
-#define GFS_DROP_RESOURCES_COUNT_PATH "/cluster/gfs_controld/@drop_resources_count"
-#define GFS_DROP_RESOURCES_AGE_PATH "/cluster/gfs_controld/@drop_resources_age"
-
-int setup_ccs(void)
-{
- int cd, rv;
-
- /* skip things that cannot be changed while running */
- if (ccs_handle)
- goto update;
-
- cd = ccs_connect();
- if (cd < 0) {
- log_error("ccs_connect error %d %d", cd, errno);
- return -1;
- }
- ccs_handle = cd;
-
- /* These config values are set from cluster.conf only if they haven't
- already been set on the command line. */
-
- if (!optk_debug)
- read_ccs_int(DEBUG_PATH, &cfgk_debug);
- if (!optk_timewarn)
- read_ccs_int(TIMEWARN_PATH, &cfgk_timewarn);
- if (!optk_protocol)
- read_ccs_protocol(PROTOCOL_PATH, &cfgk_protocol);
- if (!optd_groupd_compat)
- read_ccs_int(GROUPD_COMPAT_PATH, &cfgd_groupd_compat);
- if (!optd_enable_fencing)
- read_ccs_int(ENABLE_FENCING_PATH, &cfgd_enable_fencing);
- if (!optd_enable_quorum)
- read_ccs_int(ENABLE_QUORUM_PATH, &cfgd_enable_quorum);
- if (!optd_enable_deadlk)
- read_ccs_int(ENABLE_DEADLK_PATH, &cfgd_enable_deadlk);
- if (!optd_enable_plock)
- read_ccs_int(ENABLE_PLOCK_PATH, &cfgd_enable_plock);
- if (!optd_plock_ownership) {
- rv = read_ccs_int(PLOCK_OWNERSHIP_PATH, &cfgd_plock_ownership);
- if (rv < 0)
- read_ccs_int(GFS_PLOCK_OWNERSHIP_PATH, &cfgd_plock_ownership);
- }
-
- /* The following can be changed while running */
- update:
- if (!optd_plock_debug) {
- read_ccs_int(PLOCK_DEBUG_PATH, &cfgd_plock_debug);
- }
- if (!optd_plock_rate_limit) {
- rv = read_ccs_int(PLOCK_RATE_LIMIT_PATH, &cfgd_plock_rate_limit);
- if (rv < 0)
- read_ccs_int(GFS_PLOCK_RATE_LIMIT_PATH, &cfgd_plock_rate_limit);
- }
- if (!optd_drop_resources_time) {
- rv = read_ccs_int(DROP_RESOURCES_TIME_PATH, &cfgd_drop_resources_time);
- if (rv < 0)
- read_ccs_int(GFS_DROP_RESOURCES_TIME_PATH, &cfgd_drop_resources_time);
- }
- if (!optd_drop_resources_count) {
- rv = read_ccs_int(DROP_RESOURCES_COUNT_PATH, &cfgd_drop_resources_count);
- if (rv < 0)
- read_ccs_int(GFS_DROP_RESOURCES_COUNT_PATH, &cfgd_drop_resources_count);
- }
- if (!optd_drop_resources_age) {
- rv = read_ccs_int(DROP_RESOURCES_AGE_PATH, &cfgd_drop_resources_age);
- if (rv < 0)
- read_ccs_int(GFS_DROP_RESOURCES_AGE_PATH, &cfgd_drop_resources_age);
- }
-
- return 0;
-}
-
-void close_ccs(void)
-{
- ccs_disconnect(ccs_handle);
-}
-
diff --git a/group/dlm_controld/config.h b/group/dlm_controld/config.h
deleted file mode 100644
index 19a0bf8..0000000
--- a/group/dlm_controld/config.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef __CONFIG_DOT_H__
-#define __CONFIG_DOT_H__
-
-/* the kernel has default values for debug, timewarn and protocol;
- we only change them if new values are given on command line or in ccs */
-
-#define DEFAULT_GROUPD_COMPAT 0
-#define DEFAULT_DEBUG_LOGFILE 0
-#define DEFAULT_ENABLE_FENCING 1
-#define DEFAULT_ENABLE_QUORUM 0
-#define DEFAULT_ENABLE_DEADLK 0
-#define DEFAULT_ENABLE_PLOCK 1
-#define DEFAULT_PLOCK_DEBUG 0
-#define DEFAULT_PLOCK_RATE_LIMIT 0
-#define DEFAULT_PLOCK_OWNERSHIP 1
-#define DEFAULT_DROP_RESOURCES_TIME 10000 /* 10 sec */
-#define DEFAULT_DROP_RESOURCES_COUNT 10
-#define DEFAULT_DROP_RESOURCES_AGE 10000 /* 10 sec */
-
-extern int optk_debug;
-extern int optk_timewarn;
-extern int optk_protocol;
-extern int optd_groupd_compat;
-extern int optd_debug_logfile;
-extern int optd_enable_fencing;
-extern int optd_enable_quorum;
-extern int optd_enable_deadlk;
-extern int optd_enable_plock;
-extern int optd_plock_debug;
-extern int optd_plock_rate_limit;
-extern int optd_plock_ownership;
-extern int optd_drop_resources_time;
-extern int optd_drop_resources_count;
-extern int optd_drop_resources_age;
-
-extern int cfgk_debug;
-extern int cfgk_timewarn;
-extern int cfgk_protocol;
-extern int cfgd_groupd_compat;
-extern int cfgd_debug_logfile;
-extern int cfgd_enable_fencing;
-extern int cfgd_enable_quorum;
-extern int cfgd_enable_deadlk;
-extern int cfgd_enable_plock;
-extern int cfgd_plock_debug;
-extern int cfgd_plock_rate_limit;
-extern int cfgd_plock_ownership;
-extern int cfgd_drop_resources_time;
-extern int cfgd_drop_resources_count;
-extern int cfgd_drop_resources_age;
-
-#endif
-
diff --git a/group/dlm_controld/cpg.c b/group/dlm_controld/cpg.c
deleted file mode 100644
index ffb55b4..0000000
--- a/group/dlm_controld/cpg.c
+++ /dev/null
@@ -1,2631 +0,0 @@
-#include "dlm_daemon.h"
-#include "config.h"
-
-struct protocol_version {
- uint16_t major;
- uint16_t minor;
- uint16_t patch;
- uint16_t flags;
-};
-
-struct protocol {
- union {
- struct protocol_version dm_ver;
- uint16_t daemon_max[4];
- };
- union {
- struct protocol_version km_ver;
- uint16_t kernel_max[4];
- };
- union {
- struct protocol_version dr_ver;
- uint16_t daemon_run[4];
- };
- union {
- struct protocol_version kr_ver;
- uint16_t kernel_run[4];
- };
-};
-
-struct member {
- struct list_head list;
- int nodeid;
- int start; /* 1 if we received a start message for this change */
- int added; /* 1 if added by this change */
- int failed; /* 1 if failed in this change */
- int disallowed;
- uint32_t start_flags;
-};
-
-struct node {
- struct list_head list;
- int nodeid;
- int check_fencing;
- int check_quorum;
- int check_fs;
- int fs_notified;
- uint64_t add_time;
- uint64_t fail_time;
- uint64_t fence_time; /* for debug */
- uint64_t cluster_add_time;
- uint64_t cluster_remove_time;
- uint32_t fence_queries; /* for debug */
- uint32_t added_seq; /* for queries */
- uint32_t removed_seq; /* for queries */
- int failed_reason; /* for queries */
-
- struct protocol proto;
-};
-
-/* One of these change structs is created for every confchg a cpg gets. */
-
-#define CGST_WAIT_CONDITIONS 1
-#define CGST_WAIT_MESSAGES 2
-
-struct change {
- struct list_head list;
- struct list_head members;
- struct list_head removed; /* nodes removed by this change */
- int member_count;
- int joined_count;
- int remove_count;
- int failed_count;
- int state;
- int we_joined;
- uint32_t seq; /* used as a reference for debugging, and for queries */
- uint32_t combined_seq; /* for queries */
- uint64_t create_time;
-};
-
-struct ls_info {
- uint32_t ls_info_size;
- uint32_t id_info_size;
- uint32_t id_info_count;
-
- uint32_t started_count;
-
- int member_count;
- int joined_count;
- int remove_count;
- int failed_count;
-};
-
-struct id_info {
- int nodeid;
-};
-
-int message_flow_control_on;
-static cpg_handle_t cpg_handle_daemon;
-static int cpg_fd_daemon;
-static struct protocol our_protocol;
-static struct list_head daemon_nodes;
-static struct cpg_address daemon_member[MAX_NODES];
-static int daemon_member_count;
-
-static void log_config(const struct cpg_name *group_name,
- const struct cpg_address *member_list,
- size_t member_list_entries,
- const struct cpg_address *left_list,
- size_t left_list_entries,
- const struct cpg_address *joined_list,
- size_t joined_list_entries)
-{
- char m_buf[128];
- char j_buf[32];
- char l_buf[32];
- size_t i, len, pos;
- int ret;
-
- memset(m_buf, 0, sizeof(m_buf));
- memset(j_buf, 0, sizeof(j_buf));
- memset(l_buf, 0, sizeof(l_buf));
-
- len = sizeof(m_buf);
- pos = 0;
- for (i = 0; i < member_list_entries; i++) {
- ret = snprintf(m_buf + pos, len - pos, " %d",
- member_list[i].nodeid);
- if (ret >= len - pos)
- break;
- pos += ret;
- }
-
- len = sizeof(j_buf);
- pos = 0;
- for (i = 0; i < joined_list_entries; i++) {
- ret = snprintf(j_buf + pos, len - pos, " %d",
- joined_list[i].nodeid);
- if (ret >= len - pos)
- break;
- pos += ret;
- }
-
- len = sizeof(l_buf);
- pos = 0;
- for (i = 0; i < left_list_entries; i++) {
- ret = snprintf(l_buf + pos, len - pos, " %d",
- left_list[i].nodeid);
- if (ret >= len - pos)
- break;
- pos += ret;
- }
-
- log_debug("%s conf %zu %zu %zu memb%s join%s left%s", group_name->value,
- member_list_entries, joined_list_entries, left_list_entries,
- m_buf, j_buf, l_buf);
-}
-
-static void ls_info_in(struct ls_info *li)
-{
- li->ls_info_size = le32_to_cpu(li->ls_info_size);
- li->id_info_size = le32_to_cpu(li->id_info_size);
- li->id_info_count = le32_to_cpu(li->id_info_count);
- li->started_count = le32_to_cpu(li->started_count);
- li->member_count = le32_to_cpu(li->member_count);
- li->joined_count = le32_to_cpu(li->joined_count);
- li->remove_count = le32_to_cpu(li->remove_count);
- li->failed_count = le32_to_cpu(li->failed_count);
-}
-
-static void id_info_in(struct id_info *id)
-{
- id->nodeid = le32_to_cpu(id->nodeid);
-}
-
-static void ids_in(struct ls_info *li, struct id_info *ids)
-{
- struct id_info *id;
- int i;
-
- id = ids;
- for (i = 0; i < li->id_info_count; i++) {
- id_info_in(id);
- id = (struct id_info *)((char *)id + li->id_info_size);
- }
-}
-
-const char *msg_name(int type)
-{
- switch (type) {
- case DLM_MSG_PROTOCOL:
- return "protocol";
- case DLM_MSG_START:
- return "start";
- case DLM_MSG_PLOCK:
- return "plock";
- case DLM_MSG_PLOCK_OWN:
- return "plock_own";
- case DLM_MSG_PLOCK_DROP:
- return "plock_drop";
- case DLM_MSG_PLOCK_SYNC_LOCK:
- return "plock_sync_lock";
- case DLM_MSG_PLOCK_SYNC_WAITER:
- return "plock_sync_waiter";
- case DLM_MSG_PLOCKS_STORED:
- return "plocks_stored";
- case DLM_MSG_DEADLK_CYCLE_START:
- return "deadlk_cycle_start";
- case DLM_MSG_DEADLK_CYCLE_END:
- return "deadlk_cycle_end";
- case DLM_MSG_DEADLK_CHECKPOINT_READY:
- return "deadlk_checkpoint_ready";
- case DLM_MSG_DEADLK_CANCEL_LOCK:
- return "deadlk_cancel_lock";
- default:
- return "unknown";
- }
-}
-
-static int _send_message(cpg_handle_t h, void *buf, int len, int type)
-{
- struct iovec iov;
- cpg_error_t error;
- int retries = 0;
-
- iov.iov_base = buf;
- iov.iov_len = len;
-
- retry:
- error = cpg_mcast_joined(h, CPG_TYPE_AGREED, &iov, 1);
- if (error == CPG_ERR_TRY_AGAIN) {
- retries++;
- usleep(1000);
- if (!(retries % 100))
- log_error("cpg_mcast_joined retry %d %s",
- retries, msg_name(type));
- goto retry;
- }
- if (error != CPG_OK) {
- log_error("cpg_mcast_joined error %d handle %llx %s",
- error, (unsigned long long)h, msg_name(type));
- return -1;
- }
-
- if (retries)
- log_debug("cpg_mcast_joined retried %d %s",
- retries, msg_name(type));
-
- return 0;
-}
-
-/* header fields caller needs to set: type, to_nodeid, flags, msgdata */
-
-void dlm_send_message(struct lockspace *ls, char *buf, int len)
-{
- struct dlm_header *hd = (struct dlm_header *) buf;
- int type = hd->type;
-
- hd->version[0] = cpu_to_le16(our_protocol.daemon_run[0]);
- hd->version[1] = cpu_to_le16(our_protocol.daemon_run[1]);
- hd->version[2] = cpu_to_le16(our_protocol.daemon_run[2]);
- hd->type = cpu_to_le16(hd->type);
- hd->nodeid = cpu_to_le32(our_nodeid);
- hd->to_nodeid = cpu_to_le32(hd->to_nodeid);
- hd->global_id = cpu_to_le32(ls->global_id);
- hd->flags = cpu_to_le32(hd->flags);
- hd->msgdata = cpu_to_le32(hd->msgdata);
- hd->msgdata2 = cpu_to_le32(hd->msgdata2);
-
- _send_message(ls->cpg_handle, buf, len, type);
-}
-
-static struct member *find_memb(struct change *cg, int nodeid)
-{
- struct member *memb;
-
- list_for_each_entry(memb, &cg->members, list) {
- if (memb->nodeid == nodeid)
- return memb;
- }
- return NULL;
-}
-
-static struct lockspace *find_ls_handle(cpg_handle_t h)
-{
- struct lockspace *ls;
-
- list_for_each_entry(ls, &lockspaces, list) {
- if (ls->cpg_handle == h)
- return ls;
- }
- return NULL;
-}
-
-static struct lockspace *find_ls_ci(int ci)
-{
- struct lockspace *ls;
-
- list_for_each_entry(ls, &lockspaces, list) {
- if (ls->cpg_client == ci)
- return ls;
- }
- return NULL;
-}
-
-static void free_cg(struct change *cg)
-{
- struct member *memb, *safe;
-
- list_for_each_entry_safe(memb, safe, &cg->members, list) {
- list_del(&memb->list);
- free(memb);
- }
- list_for_each_entry_safe(memb, safe, &cg->removed, list) {
- list_del(&memb->list);
- free(memb);
- }
- free(cg);
-}
-
-static void free_ls(struct lockspace *ls)
-{
- struct change *cg, *cg_safe;
- struct node *node, *node_safe;
-
- list_for_each_entry_safe(cg, cg_safe, &ls->changes, list) {
- list_del(&cg->list);
- free_cg(cg);
- }
-
- if (ls->started_change)
- free_cg(ls->started_change);
-
- list_for_each_entry_safe(node, node_safe, &ls->node_history, list) {
- list_del(&node->list);
- free(node);
- }
-
- free(ls);
-}
-
-
-/* Problem scenario:
- nodes A,B,C are in fence domain
- node C has gfs foo mounted
- node C fails
- nodes A,B begin fencing C (slow, not completed)
- node B mounts gfs foo
-
- We may end up having gfs foo mounted and being used on B before
- C has been fenced. C could wake up corrupt fs.
-
- So, we need to prevent any new gfs mounts while there are any
- outstanding, incomplete fencing operations.
-
- We also need to check that the specific failed nodes we know about have
- been fenced (since fenced may not even have been notified that the node
- has failed yet).
-
- So, check that:
- 1. has fenced fenced the node since we saw it fail?
- 2. fenced has no outstanding fencing ops
-
- For 1:
- - node X fails
- - we see node X fail and X has non-zero add_time,
- set check_fencing and record the fail time
- - wait for X to be removed from all dlm cpg's (probably not necessary)
- - check that the fencing time is later than the recorded time above
-
- Tracking fencing state when there are spurious partitions/merges...
-
- from a spurious leave/join of node X, a lockspace will see:
- - node X is a lockspace member
- - node X fails, may be waiting for all cpgs to see failure or for fencing to
- complete
- - node X joins the lockspace - we want to process the change as usual, but
- don't want to disrupt the code waiting for the fencing, and we want to
- continue running properly once the remerged node is properly reset
-
- ls->node_history
- when we see a node not in this list, add entry for it with zero add_time
- record the time we get a good start message from the node, add_time
- clear add_time if the node leaves
- if node fails with non-zero add_time, set check_fencing
- when a node is fenced, clear add_time and clear check_fencing
- if a node remerges after this, no good start message, no new add_time set
- if a node fails with zero add_time, it doesn't need fencing
- if a node remerges before it's been fenced, no good start message, no new
- add_time set
-*/
-
-static struct node *get_node_history(struct lockspace *ls, int nodeid)
-{
- struct node *node;
-
- list_for_each_entry(node, &ls->node_history, list) {
- if (node->nodeid == nodeid)
- return node;
- }
- return NULL;
-}
-
-static void node_history_init(struct lockspace *ls, int nodeid,
- struct change *cg)
-{
- struct node *node;
-
- node = get_node_history(ls, nodeid);
- if (node)
- goto out;
-
- node = malloc(sizeof(struct node));
- if (!node)
- return;
- memset(node, 0, sizeof(struct node));
-
- node->nodeid = nodeid;
- node->add_time = 0;
- list_add_tail(&node->list, &ls->node_history);
- out:
- if (cg)
- node->added_seq = cg->seq; /* for queries */
-}
-
-void node_history_cluster_add(int nodeid)
-{
- struct lockspace *ls;
- struct node *node;
-
- list_for_each_entry(ls, &lockspaces, list) {
- node_history_init(ls, nodeid, NULL);
-
- node = get_node_history(ls, nodeid);
- if (!node) {
- log_error("node_history_cluster_add no nodeid %d",
- nodeid);
- return;
- }
-
- node->cluster_add_time = time(NULL);
- }
-}
-
-void node_history_cluster_remove(int nodeid)
-{
- struct lockspace *ls;
- struct node *node;
-
- list_for_each_entry(ls, &lockspaces, list) {
- node = get_node_history(ls, nodeid);
- if (!node) {
- log_error("node_history_cluster_remove no nodeid %d",
- nodeid);
- return;
- }
-
- node->cluster_remove_time = time(NULL);
- }
-}
-
-static void node_history_start(struct lockspace *ls, int nodeid)
-{
- struct node *node;
-
- node = get_node_history(ls, nodeid);
- if (!node) {
- log_error("node_history_start no nodeid %d", nodeid);
- return;
- }
-
- node->add_time = time(NULL);
-}
-
-static void node_history_left(struct lockspace *ls, int nodeid,
- struct change *cg)
-{
- struct node *node;
-
- node = get_node_history(ls, nodeid);
- if (!node) {
- log_error("node_history_left no nodeid %d", nodeid);
- return;
- }
-
- node->add_time = 0;
- node->removed_seq = cg->seq; /* for queries */
-}
-
-static void node_history_fail(struct lockspace *ls, int nodeid,
- struct change *cg, int reason)
-{
- struct node *node;
-
- node = get_node_history(ls, nodeid);
- if (!node) {
- log_error("node_history_fail no nodeid %d", nodeid);
- return;
- }
-
- if (cfgd_enable_fencing && node->add_time) {
- node->check_fencing = 1;
- node->fence_time = 0;
- node->fence_queries = 0;
- node->fail_time = time(NULL);
- }
-
- /* fenced will take care of making sure the quorum value
- is adjusted for all the failures */
-
- if (cfgd_enable_quorum && !cfgd_enable_fencing)
- node->check_quorum = 1;
-
- if (ls->fs_registered) {
- log_group(ls, "check_fs nodeid %d set", nodeid);
- node->check_fs = 1;
- }
-
- node->removed_seq = cg->seq; /* for queries */
- node->failed_reason = reason; /* for queries */
-}
-
-static int check_fencing_done(struct lockspace *ls)
-{
- struct node *node;
- uint64_t last_fenced_time;
- int in_progress, wait_count = 0;
- int rv;
-
- if (!cfgd_enable_fencing) {
- log_group(ls, "check_fencing disabled");
- return 1;
- }
-
- list_for_each_entry(node, &ls->node_history, list) {
- if (!node->check_fencing)
- continue;
-
- /* check with fenced to see if the node has been
- fenced since node->add_time */
-
- rv = fence_node_time(node->nodeid, &last_fenced_time);
- if (rv < 0)
- log_error("fenced_node_info error %d", rv);
-
- /* need >= not just > because in at least one case
- we've seen fenced_time within the same second as
- fail_time: with external fencing, e.g. fence_node */
-
- if (last_fenced_time >= node->fail_time) {
- log_group(ls, "check_fencing %d done "
- "add %llu fail %llu last %llu",
- node->nodeid,
- (unsigned long long)node->add_time,
- (unsigned long long)node->fail_time,
- (unsigned long long)last_fenced_time);
- node->check_fencing = 0;
- node->add_time = 0;
- node->fence_time = last_fenced_time;
- } else {
- if (!node->fence_queries ||
- node->fence_time != last_fenced_time) {
- log_group(ls, "check_fencing %d wait "
- "add %llu fail %llu last %llu",
- node->nodeid,
- (unsigned long long)node->add_time,
- (unsigned long long)node->fail_time,
- (unsigned long long)last_fenced_time);
- node->fence_queries++;
- node->fence_time = last_fenced_time;
- }
- wait_count++;
- }
- }
-
- if (wait_count)
- return 0;
-
- /* now check if there are any outstanding fencing ops (for nodes
- we may not have seen in any lockspace), and return 0 if there
- are any */
-
- rv = fence_in_progress(&in_progress);
- if (rv < 0) {
- log_error("fenced_domain_info error %d", rv);
- return 0;
- }
-
- if (in_progress)
- return 0;
-
- log_group(ls, "check_fencing done");
- return 1;
-}
-
-static int check_quorum_done(struct lockspace *ls)
-{
- struct node *node;
- int wait_count = 0;
-
- if (!cfgd_enable_quorum) {
- log_group(ls, "check_quorum disabled");
- return 1;
- }
-
- /* wait for quorum system (cman) to see all the same nodes failed, so
- we know that cluster_quorate is adjusted for the same failures we've
- seen (see comment in fenced about the assumption here) */
-
- list_for_each_entry(node, &ls->node_history, list) {
- if (!node->check_quorum)
- continue;
-
- if (!is_cluster_member(node->nodeid)) {
- node->check_quorum = 0;
- } else {
- log_group(ls, "check_quorum nodeid %d is_cluster_member",
- node->nodeid);
- wait_count++;
- }
- }
-
- if (wait_count)
- return 0;
-
- if (!cluster_quorate) {
- log_group(ls, "check_quorum not quorate");
- return 0;
- }
-
- log_group(ls, "check_quorum done");
- return 1;
-}
-
-/* wait for local fs_controld to ack each failed node */
-
-static int check_fs_done(struct lockspace *ls)
-{
- struct node *node;
- int wait_count = 0;
-
- /* no corresponding fs for this lockspace */
- if (!ls->fs_registered) {
- log_group(ls, "check_fs none registered");
- return 1;
- }
-
- list_for_each_entry(node, &ls->node_history, list) {
- if (!node->check_fs)
- continue;
-
- if (node->fs_notified) {
- log_group(ls, "check_fs nodeid %d clear", node->nodeid);
- node->check_fs = 0;
- node->fs_notified = 0;
- } else {
- log_group(ls, "check_fs nodeid %d needs fs notify",
- node->nodeid);
- wait_count++;
- }
- }
-
- if (wait_count)
- return 0;
-
- log_group(ls, "check_fs done");
- return 1;
-}
-
-static int member_ids[MAX_NODES];
-static int member_count;
-static int renew_ids[MAX_NODES];
-static int renew_count;
-
-static void format_member_ids(struct lockspace *ls)
-{
- struct change *cg = list_first_entry(&ls->changes, struct change, list);
- struct member *memb;
-
- memset(member_ids, 0, sizeof(member_ids));
- member_count = 0;
-
- list_for_each_entry(memb, &cg->members, list)
- member_ids[member_count++] = memb->nodeid;
-}
-
-/* list of nodeids that have left and rejoined since last start_kernel;
- is any member of startcg in the left list of any other cg's?
- (if it is, then it presumably must be flagged added in another) */
-
-static void format_renew_ids(struct lockspace *ls)
-{
- struct change *cg, *startcg;
- struct member *memb, *leftmemb;
-
- startcg = list_first_entry(&ls->changes, struct change, list);
-
- memset(renew_ids, 0, sizeof(renew_ids));
- renew_count = 0;
-
- list_for_each_entry(memb, &startcg->members, list) {
- list_for_each_entry(cg, &ls->changes, list) {
- if (cg == startcg)
- continue;
- list_for_each_entry(leftmemb, &cg->removed, list) {
- if (memb->nodeid == leftmemb->nodeid) {
- renew_ids[renew_count++] = memb->nodeid;
- }
- }
- }
- }
-
-}
-
-static void start_kernel(struct lockspace *ls)
-{
- struct change *cg = list_first_entry(&ls->changes, struct change, list);
-
- if (!ls->kernel_stopped) {
- log_error("start_kernel cg %u not stopped", cg->seq);
- return;
- }
-
- log_group(ls, "start_kernel cg %u member_count %d",
- cg->seq, cg->member_count);
-
- /* needs to happen before setting control which starts recovery */
- if (ls->joining)
- set_sysfs_id(ls->name, ls->global_id);
-
- format_member_ids(ls);
- format_renew_ids(ls);
- set_configfs_members(ls->name, member_count, member_ids,
- renew_count, renew_ids);
- set_sysfs_control(ls->name, 1);
- ls->kernel_stopped = 0;
-
- if (ls->joining) {
- set_sysfs_event_done(ls->name, 0);
- ls->joining = 0;
- }
-}
-
-static void stop_kernel(struct lockspace *ls, uint32_t seq)
-{
- if (!ls->kernel_stopped) {
- log_group(ls, "stop_kernel cg %u", seq);
- set_sysfs_control(ls->name, 0);
- ls->kernel_stopped = 1;
- }
-}
-
-/* the first condition is that the local lockspace is stopped which we
- don't need to check for because stop_kernel(), which is synchronous,
- was done when the change was created */
-
-static int wait_conditions_done(struct lockspace *ls)
-{
- /* the fencing/quorum/fs conditions need to account for all the changes
- that have occured since the last change applied to dlm-kernel, not
- just the latest change */
-
- if (!check_fencing_done(ls)) {
- poll_fencing++;
- return 0;
- }
-
- /* fencing waits for quorum, so we don't need to check quorum for any
- reasons related to safety or protection, so enable_quorum defaults
- to 0. This does mean that lockspaces (and cluster fs's) can be
- started/enabled in an inquorate cluster if there are no outstanding
- fencing operations. Some users or apps may want lockspaces/fs's to
- only be enabled in a quorate cluster; enable_quorum can be set to 1
- to get that behavior. The main advantage of not waiting for quorum
- here is to allow lockspaces to be shut down (and cluster fs's
- unmounted) in an inquorate cluster. */
-
- if (!check_quorum_done(ls)) {
- poll_quorum++;
- return 0;
- }
-
- if (!check_fs_done(ls)) {
- poll_fs++;
- return 0;
- }
-
- return 1;
-}
-
-static int wait_messages_done(struct lockspace *ls)
-{
- struct change *cg = list_first_entry(&ls->changes, struct change, list);
- struct member *memb;
- int need = 0, total = 0;
-
- list_for_each_entry(memb, &cg->members, list) {
- if (!memb->start)
- need++;
- total++;
- }
-
- if (need) {
- log_group(ls, "wait_messages cg %u need %d of %d",
- cg->seq, need, total);
- return 0;
- }
-
- log_group(ls, "wait_messages cg %u got all %d", cg->seq, total);
- return 1;
-}
-
-static void cleanup_changes(struct lockspace *ls)
-{
- struct change *cg = list_first_entry(&ls->changes, struct change, list);
- struct change *safe;
-
- list_del(&cg->list);
- if (ls->started_change)
- free_cg(ls->started_change);
- ls->started_change = cg;
-
- ls->started_count++;
- if (!ls->started_count)
- ls->started_count++;
-
- cg->combined_seq = cg->seq; /* for queries */
-
- list_for_each_entry_safe(cg, safe, &ls->changes, list) {
- ls->started_change->combined_seq = cg->seq; /* for queries */
- list_del(&cg->list);
- free_cg(cg);
- }
-}
-
-/* There's a stream of confchg and messages. At one of these
- messages, the low node needs to store plocks and new nodes
- need to begin saving plock messages. A second message is
- needed to say that the plocks are ready to be read.
-
- When the last start message is recvd for a change, the low node
- stores plocks and the new nodes begin saving messages. When the
- store is done, low node sends plocks_stored message. When
- new nodes recv this, they read the plocks and their saved messages.
- plocks_stored message should identify a specific change, like start
- messages do; if it doesn't match ls->started_change, then it's ignored.
-
- If a confchg adding a new node arrives after plocks are stored but
- before plocks_stored msg recvd, then the message is ignored. The low
- node will send another plocks_stored message for the latest change
- (although it may be able to reuse the ckpt if no plock state has changed).
-*/
-
-static void set_plock_ckpt_node(struct lockspace *ls)
-{
- struct change *cg = list_first_entry(&ls->changes, struct change, list);
- struct member *memb;
- int low = 0;
-
- list_for_each_entry(memb, &cg->members, list) {
- if (!(memb->start_flags & DLM_MFLG_HAVEPLOCK))
- continue;
-
- if (!low || memb->nodeid < low)
- low = memb->nodeid;
- }
-
- log_group(ls, "set_plock_ckpt_node from %d to %d",
- ls->plock_ckpt_node, low);
-
- if (ls->plock_ckpt_node == our_nodeid && low != our_nodeid) {
- /* Close ckpt so it will go away when the new ckpt_node
- unlinks it prior to creating a new one; if we fail
- our open ckpts are automatically closed. At this point
- the ckpt has not been unlinked, but won't be held open by
- anyone. We use the max "retentionDuration" to stop the
- system from cleaning up ckpts that are open by no one. */
- close_plock_checkpoint(ls);
- }
-
- ls->plock_ckpt_node = low;
-}
-
-static struct id_info *get_id_struct(struct id_info *ids, int count, int size,
- int nodeid)
-{
- struct id_info *id = ids;
- int i;
-
- for (i = 0; i < count; i++) {
- if (id->nodeid == nodeid)
- return id;
- id = (struct id_info *)((char *)id + size);
- }
- return NULL;
-}
-
-/* do the change details in the message match the details of the given change */
-
-static int match_change(struct lockspace *ls, struct change *cg,
- struct dlm_header *hd, struct ls_info *li,
- struct id_info *ids)
-{
- struct id_info *id;
- struct member *memb;
- struct node *node;
- uint32_t seq = hd->msgdata;
- int i, members_mismatch;
-
- /* We can ignore messages if we're not in the list of members.
- The one known time this will happen is after we've joined
- the cpg, we can get messages for changes prior to the change
- in which we're added. */
-
- id = get_id_struct(ids, li->id_info_count, li->id_info_size,our_nodeid);
-
- if (!id) {
- log_group(ls, "match_change %d:%u skip %u we are not in members",
- hd->nodeid, seq, cg->seq);
- return 0;
- }
-
- memb = find_memb(cg, hd->nodeid);
- if (!memb) {
- log_group(ls, "match_change %d:%u skip %u sender not member",
- hd->nodeid, seq, cg->seq);
- return 0;
- }
-
- if (memb->start_flags & DLM_MFLG_NACK) {
- log_group(ls, "match_change %d:%u skip %u is nacked",
- hd->nodeid, seq, cg->seq);
- return 0;
- }
-
- if (memb->start && hd->type == DLM_MSG_START) {
- log_group(ls, "match_change %d:%u skip %u already start",
- hd->nodeid, seq, cg->seq);
- return 0;
- }
-
- /* a node's start can't match a change if the node joined the cluster
- more recently than the change was created */
-
- node = get_node_history(ls, hd->nodeid);
- if (!node) {
- log_group(ls, "match_change %d:%u skip cg %u no node history",
- hd->nodeid, seq, cg->seq);
- return 0;
- }
-
- if (node->cluster_add_time > cg->create_time) {
- log_group(ls, "match_change %d:%u skip cg %u created %llu "
- "cluster add %llu", hd->nodeid, seq, cg->seq,
- (unsigned long long)cg->create_time,
- (unsigned long long)node->cluster_add_time);
-
- /* nacks can apply to older cg's */
- if (!(hd->flags & DLM_MFLG_NACK)) {
- return 0;
- } else {
- log_group(ls, "match_change %d:%u unskip cg %u for nack",
- hd->nodeid, seq, cg->seq);
- }
- }
-
- /* verify this is the right change by matching the counts
- and the nodeids of the current members */
-
- if (li->member_count != cg->member_count ||
- li->joined_count != cg->joined_count ||
- li->remove_count != cg->remove_count ||
- li->failed_count != cg->failed_count) {
- log_group(ls, "match_change %d:%u skip %u expect counts "
- "%d %d %d %d", hd->nodeid, seq, cg->seq,
- cg->member_count, cg->joined_count,
- cg->remove_count, cg->failed_count);
- return 0;
- }
-
- members_mismatch = 0;
- id = ids;
-
- for (i = 0; i < li->id_info_count; i++) {
- memb = find_memb(cg, id->nodeid);
- if (!memb) {
- log_group(ls, "match_change %d:%u skip %u no memb %d",
- hd->nodeid, seq, cg->seq, id->nodeid);
- members_mismatch = 1;
- break;
- }
- id = (struct id_info *)((char *)id + li->id_info_size);
- }
-
- if (members_mismatch)
- return 0;
-
- log_group(ls, "match_change %d:%u matches cg %u", hd->nodeid, seq,
- cg->seq);
- return 1;
-}
-
-/* Unfortunately, there's no really simple way to match a message with the
- specific change that it was sent for. We hope that by passing all the
- details of the change in the message, we will be able to uniquely match the
- it to the correct change. */
-
-/* A start message will usually be for the first (current) change on our list.
- In some cases it will be for a non-current change, and we can ignore it:
-
- 1. A,B,C get confchg1 adding C
- 2. C sends start for confchg1
- 3. A,B,C get confchg2 adding D
- 4. A,B,C,D recv start from C for confchg1 - ignored
- 5. C,D send start for confchg2
- 6. A,B send start for confchg2
- 7. A,B,C,D recv all start messages for confchg2, and start kernel
-
- In step 4, how do the nodes know whether the start message from C is
- for confchg1 or confchg2? Hopefully by comparing the counts and members. */
-
-static struct change *find_change(struct lockspace *ls, struct dlm_header *hd,
- struct ls_info *li, struct id_info *ids)
-{
- struct change *cg;
-
- list_for_each_entry_reverse(cg, &ls->changes, list) {
- if (!match_change(ls, cg, hd, li, ids))
- continue;
- return cg;
- }
-
- log_group(ls, "find_change %d:%u no match", hd->nodeid, hd->msgdata);
- return NULL;
-}
-
-static int is_added(struct lockspace *ls, int nodeid)
-{
- struct change *cg;
- struct member *memb;
-
- list_for_each_entry(cg, &ls->changes, list) {
- memb = find_memb(cg, nodeid);
- if (memb && memb->added)
- return 1;
- }
- return 0;
-}
-
-static void receive_start(struct lockspace *ls, struct dlm_header *hd, int len)
-{
- struct change *cg;
- struct member *memb;
- struct ls_info *li;
- struct id_info *ids;
- uint32_t seq = hd->msgdata;
- int added;
-
- log_group(ls, "receive_start %d:%u len %d", hd->nodeid, seq, len);
-
- li = (struct ls_info *)((char *)hd + sizeof(struct dlm_header));
- ids = (struct id_info *)((char *)li + sizeof(struct ls_info));
-
- ls_info_in(li);
- ids_in(li, ids);
-
- cg = find_change(ls, hd, li, ids);
- if (!cg)
- return;
-
- memb = find_memb(cg, hd->nodeid);
- if (!memb) {
- /* this should never happen since match_change checks it */
- log_error("receive_start no member %d", hd->nodeid);
- return;
- }
-
- memb->start_flags = hd->flags;
-
- added = is_added(ls, hd->nodeid);
-
- if (added && li->started_count && ls->started_count) {
- log_error("receive_start %d:%u add node with started_count %u",
- hd->nodeid, seq, li->started_count);
-
- /* see comment in fence/fenced/cpg.c */
- memb->disallowed = 1;
- return;
- }
-
- if (memb->start_flags & DLM_MFLG_NACK) {
- log_group(ls, "receive_start %d:%u is NACK", hd->nodeid, seq);
- return;
- }
-
- node_history_start(ls, hd->nodeid);
- memb->start = 1;
-}
-
-static void receive_plocks_stored(struct lockspace *ls, struct dlm_header *hd,
- int len)
-{
- struct ls_info *li;
- struct id_info *ids;
- uint32_t sig;
-
- log_group(ls, "receive_plocks_stored %d:%u flags %x sig %x "
- "need_plocks %d", hd->nodeid, hd->msgdata, hd->flags,
- hd->msgdata2, ls->need_plocks);
-
- log_plock(ls, "receive_plocks_stored %d:%u flags %x sig %x "
- "need_plocks %d", hd->nodeid, hd->msgdata, hd->flags,
- hd->msgdata2, ls->need_plocks);
-
- ls->last_plock_sig = hd->msgdata2;
-
- if (!ls->need_plocks)
- return;
-
- /* a confchg arrived between the last start and the plocks_stored msg,
- so we ignore this plocks_stored msg and wait to read the ckpt until
- the next plocks_stored msg following the current start */
-
- if (!list_empty(&ls->changes) || !ls->started_change) {
- log_group(ls, "receive_plocks_stored %d:%u ignore",
- hd->nodeid, hd->msgdata);
- return;
- }
-
- li = (struct ls_info *)((char *)hd + sizeof(struct dlm_header));
- ids = (struct id_info *)((char *)li + sizeof(struct ls_info));
- ls_info_in(li);
- ids_in(li, ids);
-
- if (!match_change(ls, ls->started_change, hd, li, ids)) {
- log_group(ls, "receive_plocks_stored %d:%u ignore no match",
- hd->nodeid, hd->msgdata);
- return;
- }
-
- retrieve_plocks(ls, &sig);
-
- if ((hd->flags & DLM_MFLG_PLOCK_SIG) && (sig != hd->msgdata2)) {
- log_error("lockspace %s plock disabled our sig %x "
- "nodeid %d sig %x", ls->name, sig, hd->nodeid,
- hd->msgdata2);
- ls->disable_plock = 1;
- ls->need_plocks = 1; /* don't set HAVEPLOCK */
- ls->save_plocks = 0;
- return;
- }
-
- process_saved_plocks(ls);
- ls->need_plocks = 0;
- ls->save_plocks = 0;
-}
-
-static void send_info(struct lockspace *ls, struct change *cg, int type,
- uint32_t flags, uint32_t msgdata2)
-{
- struct dlm_header *hd;
- struct ls_info *li;
- struct id_info *id;
- struct member *memb;
- char *buf;
- int len, id_count;
-
- id_count = cg->member_count;
-
- len = sizeof(struct dlm_header) + sizeof(struct ls_info) +
- id_count * sizeof(struct id_info);
-
- buf = malloc(len);
- if (!buf) {
- log_error("send_info len %d no mem", len);
- return;
- }
- memset(buf, 0, len);
-
- hd = (struct dlm_header *)buf;
- li = (struct ls_info *)(buf + sizeof(*hd));
- id = (struct id_info *)(buf + sizeof(*hd) + sizeof(*li));
-
- /* fill in header (dlm_send_message handles part of header) */
-
- hd->type = type;
- hd->msgdata = cg->seq;
- hd->flags = flags;
- hd->msgdata2 = msgdata2;
-
- if (ls->joining)
- hd->flags |= DLM_MFLG_JOINING;
- if (!ls->need_plocks)
- hd->flags |= DLM_MFLG_HAVEPLOCK;
-
- /* fill in ls_info */
-
- li->ls_info_size = cpu_to_le32(sizeof(struct ls_info));
- li->id_info_size = cpu_to_le32(sizeof(struct id_info));
- li->id_info_count = cpu_to_le32(id_count);
- li->started_count = cpu_to_le32(ls->started_count);
- li->member_count = cpu_to_le32(cg->member_count);
- li->joined_count = cpu_to_le32(cg->joined_count);
- li->remove_count = cpu_to_le32(cg->remove_count);
- li->failed_count = cpu_to_le32(cg->failed_count);
-
- /* fill in id_info entries */
-
- list_for_each_entry(memb, &cg->members, list) {
- id->nodeid = cpu_to_le32(memb->nodeid);
- id++;
- }
-
- log_group(ls, "send_%s cg %u flags %x data2 %x counts %u %d %d %d %d",
- type == DLM_MSG_START ? "start" : "plocks_stored",
- cg->seq, hd->flags, hd->msgdata2, ls->started_count,
- cg->member_count, cg->joined_count, cg->remove_count,
- cg->failed_count);
-
- dlm_send_message(ls, buf, len);
-
- free(buf);
-}
-
-static void send_start(struct lockspace *ls)
-{
- struct change *cg = list_first_entry(&ls->changes, struct change, list);
-
- send_info(ls, cg, DLM_MSG_START, 0, 0);
-}
-
-static void send_plocks_stored(struct lockspace *ls, uint32_t sig)
-{
- struct change *cg = list_first_entry(&ls->changes, struct change, list);
-
- send_info(ls, cg, DLM_MSG_PLOCKS_STORED, DLM_MFLG_PLOCK_SIG, sig);
-}
-
-static int same_members(struct change *cg1, struct change *cg2)
-{
- struct member *memb;
-
- list_for_each_entry(memb, &cg1->members, list) {
- if (!find_memb(cg2, memb->nodeid))
- return 0;
- }
- return 1;
-}
-
-static void send_nacks(struct lockspace *ls, struct change *startcg)
-{
- struct change *cg;
-
- list_for_each_entry(cg, &ls->changes, list) {
- if (cg->seq < startcg->seq &&
- cg->member_count == startcg->member_count &&
- cg->joined_count == startcg->joined_count &&
- cg->remove_count == startcg->remove_count &&
- cg->failed_count == startcg->failed_count &&
- same_members(cg, startcg)) {
- log_group(ls, "send nack old cg %u new cg %u",
- cg->seq, startcg->seq);
- send_info(ls, cg, DLM_MSG_START, DLM_MFLG_NACK, 0);
- }
- }
-}
-
-static int nodes_added(struct lockspace *ls)
-{
- struct change *cg;
-
- list_for_each_entry(cg, &ls->changes, list) {
- if (cg->joined_count)
- return 1;
- }
- return 0;
-}
-
-static void prepare_plocks(struct lockspace *ls)
-{
- struct change *cg = list_first_entry(&ls->changes, struct change, list);
- struct member *memb;
- uint32_t sig;
-
- log_plock(ls, "prepare_plocks");
-
- if (!cfgd_enable_plock || ls->disable_plock)
- return;
-
- /* if we're the only node in the lockspace, then we are the ckpt_node
- and we don't need plocks */
-
- if (cg->member_count == 1) {
- list_for_each_entry(memb, &cg->members, list) {
- if (memb->nodeid != our_nodeid) {
- log_error("prepare_plocks other member %d",
- memb->nodeid);
- }
- }
- ls->plock_ckpt_node = our_nodeid;
- ls->need_plocks = 0;
- return;
- }
-
- /* the low node that indicated it had plock state in its last
- start message is the ckpt_node */
-
- set_plock_ckpt_node(ls);
-
- /* there is no node with plock state, so there's no syncing to do */
-
- if (!ls->plock_ckpt_node) {
- ls->need_plocks = 0;
- ls->save_plocks = 0;
- return;
- }
-
- /* We save all plock messages from the time that the low node saves
- existing plock state in the ckpt to the time that we read that state
- from the ckpt. */
-
- if (ls->need_plocks) {
- ls->save_plocks = 1;
- return;
- }
-
- if (ls->plock_ckpt_node != our_nodeid)
- return;
-
- /* At each start, a ckpt is written if there have been nodes added
- since the last start/ckpt. If no nodes have been added, no one
- does anything with ckpts. If the node that wrote the last ckpt
- is no longer the ckpt_node, the new ckpt_node will unlink and
- write a new one. If the node that wrote the last ckpt is still
- the ckpt_node and no plock state has changed since the last ckpt,
- it will just leave the old ckpt and not write a new one.
-
- A new ckpt_node will send a stored message even if it doesn't
- write a ckpt because new nodes in the previous start may be
- waiting to read the ckpt from the previous ckpt_node after ignoring
- the previous stored message. They will read the ckpt from the
- previous ckpt_node upon receiving the stored message from us. */
-
- if (nodes_added(ls)) {
- store_plocks(ls, &sig);
- ls->last_plock_sig = sig;
- } else {
- sig = ls->last_plock_sig;
- }
- send_plocks_stored(ls, sig);
-}
-
-static void apply_changes(struct lockspace *ls)
-{
- struct change *cg;
-
- if (list_empty(&ls->changes))
- return;
- cg = list_first_entry(&ls->changes, struct change, list);
-
- switch (cg->state) {
-
- case CGST_WAIT_CONDITIONS:
- if (wait_conditions_done(ls)) {
- send_nacks(ls, cg);
- send_start(ls);
- cg->state = CGST_WAIT_MESSAGES;
- }
- break;
-
- case CGST_WAIT_MESSAGES:
- if (wait_messages_done(ls)) {
- start_kernel(ls);
- prepare_plocks(ls);
- cleanup_changes(ls);
- }
- break;
-
- default:
- log_error("apply_changes invalid state %d", cg->state);
- }
-}
-
-void process_lockspace_changes(void)
-{
- struct lockspace *ls, *safe;
-
- poll_fencing = 0;
- poll_quorum = 0;
- poll_fs = 0;
-
- list_for_each_entry_safe(ls, safe, &lockspaces, list) {
- if (!list_empty(&ls->changes))
- apply_changes(ls);
- }
-}
-
-static int add_change(struct lockspace *ls,
- const struct cpg_address *member_list,
- size_t member_list_entries,
- const struct cpg_address *left_list,
- size_t left_list_entries,
- const struct cpg_address *joined_list,
- size_t joined_list_entries,
- struct change **cg_out)
-{
- struct change *cg;
- struct member *memb;
- int i, error;
-
- cg = malloc(sizeof(struct change));
- if (!cg)
- goto fail_nomem;
- memset(cg, 0, sizeof(struct change));
- INIT_LIST_HEAD(&cg->members);
- INIT_LIST_HEAD(&cg->removed);
- cg->state = CGST_WAIT_CONDITIONS;
- cg->create_time = time(NULL);
- cg->seq = ++ls->change_seq;
- if (!cg->seq)
- cg->seq = ++ls->change_seq;
-
- cg->member_count = member_list_entries;
- cg->joined_count = joined_list_entries;
- cg->remove_count = left_list_entries;
-
- for (i = 0; i < member_list_entries; i++) {
- memb = malloc(sizeof(struct member));
- if (!memb)
- goto fail_nomem;
- memset(memb, 0, sizeof(struct member));
- memb->nodeid = member_list[i].nodeid;
- list_add_tail(&memb->list, &cg->members);
- }
-
- for (i = 0; i < left_list_entries; i++) {
- memb = malloc(sizeof(struct member));
- if (!memb)
- goto fail_nomem;
- memset(memb, 0, sizeof(struct member));
- memb->nodeid = left_list[i].nodeid;
- if (left_list[i].reason == CPG_REASON_NODEDOWN ||
- left_list[i].reason == CPG_REASON_PROCDOWN) {
- memb->failed = 1;
- cg->failed_count++;
- }
- list_add_tail(&memb->list, &cg->removed);
-
- if (memb->failed)
- node_history_fail(ls, memb->nodeid, cg,
- left_list[i].reason);
- else
- node_history_left(ls, memb->nodeid, cg);
-
- log_group(ls, "add_change cg %u remove nodeid %d reason %d",
- cg->seq, memb->nodeid, left_list[i].reason);
-
- if (left_list[i].reason == CPG_REASON_PROCDOWN)
- kick_node_from_cluster(memb->nodeid);
- }
-
- for (i = 0; i < joined_list_entries; i++) {
- memb = find_memb(cg, joined_list[i].nodeid);
- if (!memb) {
- log_error("no member %d", joined_list[i].nodeid);
- error = -ENOENT;
- goto fail;
- }
- memb->added = 1;
-
- if (memb->nodeid == our_nodeid)
- cg->we_joined = 1;
- else
- node_history_init(ls, memb->nodeid, cg);
-
- log_group(ls, "add_change cg %u joined nodeid %d", cg->seq,
- memb->nodeid);
- }
-
- if (cg->we_joined) {
- log_group(ls, "add_change cg %u we joined", cg->seq);
- list_for_each_entry(memb, &cg->members, list)
- node_history_init(ls, memb->nodeid, cg);
- }
-
- log_group(ls, "add_change cg %u counts member %d joined %d remove %d "
- "failed %d", cg->seq, cg->member_count, cg->joined_count,
- cg->remove_count, cg->failed_count);
-
- list_add(&cg->list, &ls->changes);
- *cg_out = cg;
- return 0;
-
- fail_nomem:
- log_error("no memory");
- error = -ENOMEM;
- fail:
- free_cg(cg);
- return error;
-}
-
-static int we_left(const struct cpg_address *left_list,
- size_t left_list_entries)
-{
- int i;
-
- for (i = 0; i < left_list_entries; i++) {
- if (left_list[i].nodeid == our_nodeid)
- return 1;
- }
- return 0;
-}
-
-static void confchg_cb(cpg_handle_t handle,
- const struct cpg_name *group_name,
- const struct cpg_address *member_list,
- size_t member_list_entries,
- const struct cpg_address *left_list,
- size_t left_list_entries,
- const struct cpg_address *joined_list,
- size_t joined_list_entries)
-{
- struct lockspace *ls;
- struct change *cg;
- struct member *memb;
- int rv;
-
- log_config(group_name, member_list, member_list_entries,
- left_list, left_list_entries,
- joined_list, joined_list_entries);
-
- ls = find_ls_handle(handle);
- if (!ls) {
- log_error("confchg_cb no lockspace for cpg %s",
- group_name->value);
- return;
- }
-
- if (ls->leaving && we_left(left_list, left_list_entries)) {
- /* we called cpg_leave(), and this should be the final
- cpg callback we receive */
- log_group(ls, "confchg for our leave");
- stop_kernel(ls, 0);
- set_configfs_members(ls->name, 0, NULL, 0, NULL);
- set_sysfs_event_done(ls->name, 0);
- cpg_finalize(ls->cpg_handle);
- client_dead(ls->cpg_client);
- purge_plocks(ls, our_nodeid, 1);
- list_del(&ls->list);
- free_ls(ls);
- return;
- }
-
- rv = add_change(ls, member_list, member_list_entries,
- left_list, left_list_entries,
- joined_list, joined_list_entries, &cg);
- if (rv)
- return;
-
- stop_kernel(ls, cg->seq);
-
- list_for_each_entry(memb, &cg->removed, list)
- purge_plocks(ls, memb->nodeid, 0);
-
- apply_changes(ls);
-
- deadlk_confchg(ls, member_list, member_list_entries,
- left_list, left_list_entries,
- joined_list, joined_list_entries);
-
-}
-
-static void dlm_header_in(struct dlm_header *hd)
-{
- hd->version[0] = le16_to_cpu(hd->version[0]);
- hd->version[1] = le16_to_cpu(hd->version[1]);
- hd->version[2] = le16_to_cpu(hd->version[2]);
- hd->type = le16_to_cpu(hd->type);
- hd->nodeid = le32_to_cpu(hd->nodeid);
- hd->to_nodeid = le32_to_cpu(hd->to_nodeid);
- hd->global_id = le32_to_cpu(hd->global_id);
- hd->flags = le32_to_cpu(hd->flags);
- hd->msgdata = le32_to_cpu(hd->msgdata);
- hd->msgdata2 = le32_to_cpu(hd->msgdata2);
-}
-
-/* after our join confchg, we want to ignore plock messages (see need_plocks
- checks below) until the point in time where the ckpt_node saves plock
- state (final start message received); at this time we want to shift from
- ignoring plock messages to saving plock messages to apply on top of the
- plock state that we read. */
-
-static void deliver_cb(cpg_handle_t handle,
- const struct cpg_name *group_name,
- uint32_t nodeid, uint32_t pid,
- void *data, size_t len)
-{
- struct lockspace *ls;
- struct dlm_header *hd;
- int ignore_plock;
-
- ls = find_ls_handle(handle);
- if (!ls) {
- log_error("deliver_cb no ls for cpg %s", group_name->value);
- return;
- }
-
- if (len < sizeof(*hd)) {
- log_error("deliver_cb short message %zd", len);
- return;
- }
-
- hd = (struct dlm_header *)data;
- dlm_header_in(hd);
-
- if (hd->version[0] != our_protocol.daemon_run[0] ||
- hd->version[1] != our_protocol.daemon_run[1]) {
- log_error("reject message from %d version %u.%u.%u vs %u.%u.%u",
- nodeid, hd->version[0], hd->version[1],
- hd->version[2], our_protocol.daemon_run[0],
- our_protocol.daemon_run[1],
- our_protocol.daemon_run[2]);
- return;
- }
-
- if (hd->nodeid != nodeid) {
- log_error("bad msg nodeid %d %d", hd->nodeid, nodeid);
- return;
- }
-
- ignore_plock = 0;
-
- switch (hd->type) {
- case DLM_MSG_START:
- receive_start(ls, hd, len);
- break;
-
- case DLM_MSG_PLOCK:
- if (ls->disable_plock)
- break;
- if (ls->need_plocks && !ls->save_plocks) {
- ignore_plock = 1;
- break;
- }
- if (cfgd_enable_plock)
- receive_plock(ls, hd, len);
- else
- log_error("msg %d nodeid %d enable_plock %d",
- hd->type, nodeid, cfgd_enable_plock);
- break;
-
- case DLM_MSG_PLOCK_OWN:
- if (ls->disable_plock)
- break;
- if (ls->need_plocks && !ls->save_plocks) {
- ignore_plock = 1;
- break;
- }
- if (cfgd_enable_plock && cfgd_plock_ownership)
- receive_own(ls, hd, len);
- else
- log_error("msg %d nodeid %d enable_plock %d owner %d",
- hd->type, nodeid, cfgd_enable_plock,
- cfgd_plock_ownership);
- break;
-
- case DLM_MSG_PLOCK_DROP:
- if (ls->disable_plock)
- break;
- if (ls->need_plocks && !ls->save_plocks) {
- ignore_plock = 1;
- break;
- }
- if (cfgd_enable_plock && cfgd_plock_ownership)
- receive_drop(ls, hd, len);
- else
- log_error("msg %d nodeid %d enable_plock %d owner %d",
- hd->type, nodeid, cfgd_enable_plock,
- cfgd_plock_ownership);
- break;
-
- case DLM_MSG_PLOCK_SYNC_LOCK:
- case DLM_MSG_PLOCK_SYNC_WAITER:
- if (ls->disable_plock)
- break;
- if (ls->need_plocks && !ls->save_plocks) {
- ignore_plock = 1;
- break;
- }
- if (cfgd_enable_plock && cfgd_plock_ownership)
- receive_sync(ls, hd, len);
- else
- log_error("msg %d nodeid %d enable_plock %d owner %d",
- hd->type, nodeid, cfgd_enable_plock,
- cfgd_plock_ownership);
- break;
-
- case DLM_MSG_PLOCKS_STORED:
- if (ls->disable_plock)
- break;
- if (cfgd_enable_plock)
- receive_plocks_stored(ls, hd, len);
- else
- log_error("msg %d nodeid %d enable_plock %d",
- hd->type, nodeid, cfgd_enable_plock);
- break;
-
- case DLM_MSG_DEADLK_CYCLE_START:
- if (cfgd_enable_deadlk)
- receive_cycle_start(ls, hd, len);
- else
- log_error("msg %d nodeid %d enable_deadlk %d",
- hd->type, nodeid, cfgd_enable_deadlk);
- break;
-
- case DLM_MSG_DEADLK_CYCLE_END:
- if (cfgd_enable_deadlk)
- receive_cycle_end(ls, hd, len);
- else
- log_error("msg %d nodeid %d enable_deadlk %d",
- hd->type, nodeid, cfgd_enable_deadlk);
- break;
-
- case DLM_MSG_DEADLK_CHECKPOINT_READY:
- if (cfgd_enable_deadlk)
- receive_checkpoint_ready(ls, hd, len);
- else
- log_error("msg %d nodeid %d enable_deadlk %d",
- hd->type, nodeid, cfgd_enable_deadlk);
- break;
-
- case DLM_MSG_DEADLK_CANCEL_LOCK:
- if (cfgd_enable_deadlk)
- receive_cancel_lock(ls, hd, len);
- else
- log_error("msg %d nodeid %d enable_deadlk %d",
- hd->type, nodeid, cfgd_enable_deadlk);
- break;
-
- default:
- log_error("unknown msg type %d", hd->type);
- }
-
- if (ignore_plock)
- log_plock(ls, "msg %s nodeid %d need_plock ignore",
- msg_name(hd->type), nodeid);
-
- apply_changes(ls);
-}
-
-static cpg_callbacks_t cpg_callbacks = {
- .cpg_deliver_fn = deliver_cb,
- .cpg_confchg_fn = confchg_cb,
-};
-
-void update_flow_control_status(void)
-{
- cpg_flow_control_state_t flow_control_state;
- cpg_error_t error;
-
- error = cpg_flow_control_state_get(cpg_handle_daemon,
- &flow_control_state);
- if (error != CPG_OK) {
- log_error("cpg_flow_control_state_get %d", error);
- return;
- }
-
- if (flow_control_state == CPG_FLOW_CONTROL_ENABLED) {
- if (message_flow_control_on == 0) {
- log_debug("flow control on");
- }
- message_flow_control_on = 1;
- } else {
- if (message_flow_control_on) {
- log_debug("flow control off");
- }
- message_flow_control_on = 0;
- }
-}
-
-static void process_cpg_lockspace(int ci)
-{
- struct lockspace *ls;
- cpg_error_t error;
-
- ls = find_ls_ci(ci);
- if (!ls) {
- log_error("process_lockspace_cpg no lockspace for ci %d", ci);
- return;
- }
-
- error = cpg_dispatch(ls->cpg_handle, CPG_DISPATCH_ALL);
- if (error != CPG_OK) {
- log_error("cpg_dispatch error %d", error);
- return;
- }
-
- update_flow_control_status();
-}
-
-/* received an "online" uevent from dlm-kernel */
-
-int dlm_join_lockspace(struct lockspace *ls)
-{
- cpg_error_t error;
- cpg_handle_t h;
- struct cpg_name name;
- int i = 0, fd, ci, rv;
- int unused;
-
- rv = fence_in_progress(&unused);
- if (cfgd_enable_fencing && rv < 0) {
- log_error("dlm_join_lockspace no fence domain");
- rv = -1;
- goto fail_free;
- }
-
- error = cpg_initialize(&h, &cpg_callbacks);
- if (error != CPG_OK) {
- log_error("cpg_initialize error %d", error);
- rv = -1;
- goto fail_free;
- }
-
- cpg_fd_get(h, &fd);
-
- ci = client_add(fd, process_cpg_lockspace, NULL);
-
- list_add(&ls->list, &lockspaces);
-
- ls->cpg_handle = h;
- ls->cpg_client = ci;
- ls->cpg_fd = fd;
- ls->kernel_stopped = 1;
- ls->need_plocks = 1;
- ls->joining = 1;
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "dlm:ls:%s", ls->name);
- name.length = strlen(name.value) + 1;
-
- /* TODO: allow global_id to be set in cluster.conf? */
- ls->global_id = cpgname_to_crc(name.value, name.length);
-
- retry:
- error = cpg_join(h, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- sleep(1);
- if (!(++i % 10))
- log_error("cpg_join error retrying");
- goto retry;
- }
- if (error != CPG_OK) {
- log_error("cpg_join error %d", error);
- cpg_finalize(h);
- rv = -1;
- goto fail;
- }
-
- return 0;
-
- fail:
- list_del(&ls->list);
- client_dead(ci);
- cpg_finalize(h);
- fail_free:
- set_sysfs_event_done(ls->name, rv);
- free_ls(ls);
- return rv;
-}
-
-/* received an "offline" uevent from dlm-kernel */
-
-int dlm_leave_lockspace(struct lockspace *ls)
-{
- cpg_error_t error;
- struct cpg_name name;
- int i = 0;
-
- ls->leaving = 1;
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "dlm:ls:%s", ls->name);
- name.length = strlen(name.value) + 1;
-
- retry:
- error = cpg_leave(ls->cpg_handle, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- sleep(1);
- if (!(++i % 10))
- log_error("cpg_leave error retrying");
- goto retry;
- }
- if (error != CPG_OK)
- log_error("cpg_leave error %d", error);
-
- return 0;
-}
-
-static struct node *get_node_daemon(int nodeid)
-{
- struct node *node;
-
- list_for_each_entry(node, &daemon_nodes, list) {
- if (node->nodeid == nodeid)
- return node;
- }
- return NULL;
-}
-
-static void add_node_daemon(int nodeid)
-{
- struct node *node;
-
- if (get_node_daemon(nodeid))
- return;
-
- node = malloc(sizeof(struct node));
- if (!node) {
- log_error("add_node_daemon no mem");
- return;
- }
- memset(node, 0, sizeof(struct node));
- node->nodeid = nodeid;
- list_add_tail(&node->list, &daemon_nodes);
-}
-
-static void pv_in(struct protocol_version *pv)
-{
- pv->major = le16_to_cpu(pv->major);
- pv->minor = le16_to_cpu(pv->minor);
- pv->patch = le16_to_cpu(pv->patch);
- pv->flags = le16_to_cpu(pv->flags);
-}
-
-static void pv_out(struct protocol_version *pv)
-{
- pv->major = cpu_to_le16(pv->major);
- pv->minor = cpu_to_le16(pv->minor);
- pv->patch = cpu_to_le16(pv->patch);
- pv->flags = cpu_to_le16(pv->flags);
-}
-
-static void protocol_in(struct protocol *proto)
-{
- pv_in(&proto->dm_ver);
- pv_in(&proto->km_ver);
- pv_in(&proto->dr_ver);
- pv_in(&proto->kr_ver);
-}
-
-static void protocol_out(struct protocol *proto)
-{
- pv_out(&proto->dm_ver);
- pv_out(&proto->km_ver);
- pv_out(&proto->dr_ver);
- pv_out(&proto->kr_ver);
-}
-
-/* go through member list saved in last confchg, see if we have received a
- proto message from each */
-
-static int all_protocol_messages(void)
-{
- struct node *node;
- int i;
-
- if (!daemon_member_count)
- return 0;
-
- for (i = 0; i < daemon_member_count; i++) {
- node = get_node_daemon(daemon_member[i].nodeid);
- if (!node) {
- log_error("all_protocol_messages no node %d",
- daemon_member[i].nodeid);
- return 0;
- }
-
- if (!node->proto.daemon_max[0])
- return 0;
- }
- return 1;
-}
-
-static int pick_min_protocol(struct protocol *proto)
-{
- uint16_t mind[4];
- uint16_t mink[4];
- struct node *node;
- int i;
-
- memset(&mind, 0, sizeof(mind));
- memset(&mink, 0, sizeof(mink));
-
- /* first choose the minimum major */
-
- for (i = 0; i < daemon_member_count; i++) {
- node = get_node_daemon(daemon_member[i].nodeid);
- if (!node) {
- log_error("pick_min_protocol no node %d",
- daemon_member[i].nodeid);
- return -1;
- }
-
- if (!mind[0] || node->proto.daemon_max[0] < mind[0])
- mind[0] = node->proto.daemon_max[0];
-
- if (!mink[0] || node->proto.kernel_max[0] < mink[0])
- mink[0] = node->proto.kernel_max[0];
- }
-
- if (!mind[0] || !mink[0]) {
- log_error("pick_min_protocol zero major number");
- return -1;
- }
-
- /* second pick the minimum minor with the chosen major */
-
- for (i = 0; i < daemon_member_count; i++) {
- node = get_node_daemon(daemon_member[i].nodeid);
- if (!node)
- continue;
-
- if (mind[0] == node->proto.daemon_max[0]) {
- if (!mind[1] || node->proto.daemon_max[1] < mind[1])
- mind[1] = node->proto.daemon_max[1];
- }
-
- if (mink[0] == node->proto.kernel_max[0]) {
- if (!mink[1] || node->proto.kernel_max[1] < mink[1])
- mink[1] = node->proto.kernel_max[1];
- }
- }
-
- if (!mind[1] || !mink[1]) {
- log_error("pick_min_protocol zero minor number");
- return -1;
- }
-
- /* third pick the minimum patch with the chosen major.minor */
-
- for (i = 0; i < daemon_member_count; i++) {
- node = get_node_daemon(daemon_member[i].nodeid);
- if (!node)
- continue;
-
- if (mind[0] == node->proto.daemon_max[0] &&
- mind[1] == node->proto.daemon_max[1]) {
- if (!mind[2] || node->proto.daemon_max[2] < mind[2])
- mind[2] = node->proto.daemon_max[2];
- }
-
- if (mink[0] == node->proto.kernel_max[0] &&
- mink[1] == node->proto.kernel_max[1]) {
- if (!mink[2] || node->proto.kernel_max[2] < mink[2])
- mink[2] = node->proto.kernel_max[2];
- }
- }
-
- if (!mind[2] || !mink[2]) {
- log_error("pick_min_protocol zero patch number");
- return -1;
- }
-
- memcpy(&proto->daemon_run, &mind, sizeof(mind));
- memcpy(&proto->kernel_run, &mink, sizeof(mink));
- return 0;
-}
-
-static void receive_protocol(struct dlm_header *hd, int len)
-{
- struct protocol *p;
- struct node *node;
-
- p = (struct protocol *)((char *)hd + sizeof(struct dlm_header));
- protocol_in(p);
-
- if (len < sizeof(struct dlm_header) + sizeof(struct protocol)) {
- log_error("receive_protocol invalid len %d from %d",
- len, hd->nodeid);
- return;
- }
-
- /* zero is an invalid version value */
-
- if (!p->daemon_max[0] || !p->daemon_max[1] || !p->daemon_max[2] ||
- !p->kernel_max[0] || !p->kernel_max[1] || !p->kernel_max[2]) {
- log_error("receive_protocol invalid max value from %d "
- "daemon %u.%u.%u kernel %u.%u.%u", hd->nodeid,
- p->daemon_max[0], p->daemon_max[1], p->daemon_max[2],
- p->kernel_max[0], p->kernel_max[1], p->kernel_max[2]);
- return;
- }
-
- /* the run values will be zero until a version is set, after
- which none of the run values can be zero */
-
- if (p->daemon_run[0] && (!p->daemon_run[1] || !p->daemon_run[2] ||
- !p->kernel_run[0] || !p->kernel_run[1] || !p->kernel_run[2])) {
- log_error("receive_protocol invalid run value from %d "
- "daemon %u.%u.%u kernel %u.%u.%u", hd->nodeid,
- p->daemon_run[0], p->daemon_run[1], p->daemon_run[2],
- p->kernel_run[0], p->kernel_run[1], p->kernel_run[2]);
- return;
- }
-
- /* if we have zero run values, and this msg has non-zero run values,
- then adopt them as ours; otherwise save this proto message */
-
- if (our_protocol.daemon_run[0])
- return;
-
- if (p->daemon_run[0]) {
- memcpy(&our_protocol.daemon_run, &p->daemon_run,
- sizeof(struct protocol_version));
- memcpy(&our_protocol.kernel_run, &p->kernel_run,
- sizeof(struct protocol_version));
- log_debug("run protocol from nodeid %d", hd->nodeid);
- return;
- }
-
- /* save this node's proto so we can tell when we've got all, and
- use it to select a minimum protocol from all */
-
- node = get_node_daemon(hd->nodeid);
- if (!node) {
- log_error("receive_protocol no node %d", hd->nodeid);
- return;
- }
- memcpy(&node->proto, p, sizeof(struct protocol));
-}
-
-static void send_protocol(struct protocol *proto)
-{
- struct dlm_header *hd;
- struct protocol *pr;
- char *buf;
- int len;
-
- len = sizeof(struct dlm_header) + sizeof(struct protocol);
- buf = malloc(len);
- if (!buf) {
- log_error("send_protocol no mem %d", len);
- return;
- }
- memset(buf, 0, len);
-
- hd = (struct dlm_header *)buf;
- pr = (struct protocol *)(buf + sizeof(*hd));
-
- hd->type = cpu_to_le16(DLM_MSG_PROTOCOL);
- hd->nodeid = cpu_to_le32(our_nodeid);
-
- memcpy(pr, proto, sizeof(struct protocol));
- protocol_out(pr);
-
- _send_message(cpg_handle_daemon, buf, len, DLM_MSG_PROTOCOL);
-}
-
-int set_protocol(void)
-{
- struct protocol proto;
- struct pollfd pollfd;
- int sent_proposal = 0;
- int rv;
-
- memset(&pollfd, 0, sizeof(pollfd));
- pollfd.fd = cpg_fd_daemon;
- pollfd.events = POLLIN;
-
- while (1) {
- if (our_protocol.daemon_run[0])
- break;
-
- if (!sent_proposal && all_protocol_messages()) {
- /* propose a protocol; look through info from all
- nodes and pick the min for both daemon and kernel,
- and propose that */
-
- sent_proposal = 1;
-
- /* copy our max values */
- memcpy(&proto, &our_protocol, sizeof(struct protocol));
-
- rv = pick_min_protocol(&proto);
- if (rv < 0)
- return rv;
-
- log_debug("set_protocol member_count %d propose "
- "daemon %u.%u.%u kernel %u.%u.%u",
- daemon_member_count,
- proto.daemon_run[0], proto.daemon_run[1],
- proto.daemon_run[2], proto.kernel_run[0],
- proto.kernel_run[1], proto.kernel_run[2]);
-
- send_protocol(&proto);
- }
-
- /* only process messages/events from daemon cpg until protocol
- is established */
-
- rv = poll(&pollfd, 1, -1);
- if (rv == -1 && errno == EINTR) {
- if (daemon_quit)
- return -1;
- continue;
- }
- if (rv < 0) {
- log_error("set_protocol poll errno %d", errno);
- return -1;
- }
-
- if (pollfd.revents & POLLIN)
- process_cpg_daemon(0);
- if (pollfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
- log_error("set_protocol poll revents %u",
- pollfd.revents);
- return -1;
- }
- }
-
- if (our_protocol.daemon_run[0] != our_protocol.daemon_max[0] ||
- our_protocol.daemon_run[1] > our_protocol.daemon_max[1]) {
- log_error("incompatible daemon protocol run %u.%u.%u max %u.%u.%u",
- our_protocol.daemon_run[0],
- our_protocol.daemon_run[1],
- our_protocol.daemon_run[2],
- our_protocol.daemon_max[0],
- our_protocol.daemon_max[1],
- our_protocol.daemon_max[2]);
- return -1;
- }
-
- if (our_protocol.kernel_run[0] != our_protocol.kernel_max[0] ||
- our_protocol.kernel_run[1] > our_protocol.kernel_max[1]) {
- log_error("incompatible kernel protocol run %u.%u.%u max %u.%u.%u",
- our_protocol.kernel_run[0],
- our_protocol.kernel_run[1],
- our_protocol.kernel_run[2],
- our_protocol.kernel_max[0],
- our_protocol.kernel_max[1],
- our_protocol.kernel_max[2]);
- return -1;
- }
-
- log_debug("daemon run %u.%u.%u max %u.%u.%u "
- "kernel run %u.%u.%u max %u.%u.%u",
- our_protocol.daemon_run[0],
- our_protocol.daemon_run[1],
- our_protocol.daemon_run[2],
- our_protocol.daemon_max[0],
- our_protocol.daemon_max[1],
- our_protocol.daemon_max[2],
- our_protocol.kernel_run[0],
- our_protocol.kernel_run[1],
- our_protocol.kernel_run[2],
- our_protocol.kernel_max[0],
- our_protocol.kernel_max[1],
- our_protocol.kernel_max[2]);
-
- send_protocol(&our_protocol);
- return 0;
-}
-
-static void deliver_cb_daemon(cpg_handle_t handle,
- const struct cpg_name *group_name,
- uint32_t nodeid, uint32_t pid,
- void *data, size_t len)
-{
- struct dlm_header *hd;
-
- if (len < sizeof(*hd)) {
- log_error("deliver_cb short message %zd", len);
- return;
- }
-
- hd = (struct dlm_header *)data;
- dlm_header_in(hd);
-
- switch (hd->type) {
- case DLM_MSG_PROTOCOL:
- receive_protocol(hd, len);
- break;
- default:
- log_error("deliver_cb_daemon unknown msg type %d", hd->type);
- }
-}
-
-static void confchg_cb_daemon(cpg_handle_t handle,
- const struct cpg_name *group_name,
- const struct cpg_address *member_list,
- size_t member_list_entries,
- const struct cpg_address *left_list,
- size_t left_list_entries,
- const struct cpg_address *joined_list,
- size_t joined_list_entries)
-{
- int i;
-
- log_config(group_name, member_list, member_list_entries,
- left_list, left_list_entries,
- joined_list, joined_list_entries);
-
- if (joined_list_entries)
- send_protocol(&our_protocol);
-
- memset(&daemon_member, 0, sizeof(daemon_member));
- daemon_member_count = member_list_entries;
-
- for (i = 0; i < member_list_entries; i++) {
- daemon_member[i] = member_list[i];
- add_node_daemon(member_list[i].nodeid);
- }
-}
-
-static cpg_callbacks_t cpg_callbacks_daemon = {
- .cpg_deliver_fn = deliver_cb_daemon,
- .cpg_confchg_fn = confchg_cb_daemon,
-};
-
-void process_cpg_daemon(int ci)
-{
- cpg_error_t error;
-
- error = cpg_dispatch(cpg_handle_daemon, CPG_DISPATCH_ALL);
- if (error != CPG_OK)
- log_error("daemon cpg_dispatch error %d", error);
-}
-
-int setup_cpg_daemon(void)
-{
- cpg_error_t error;
- struct cpg_name name;
- int i = 0;
-
- INIT_LIST_HEAD(&daemon_nodes);
-
- memset(&our_protocol, 0, sizeof(our_protocol));
- our_protocol.daemon_max[0] = 1;
- our_protocol.daemon_max[1] = 1;
- our_protocol.daemon_max[2] = 1;
- our_protocol.kernel_max[0] = 1;
- our_protocol.kernel_max[1] = 1;
- our_protocol.kernel_max[2] = 1;
-
- error = cpg_initialize(&cpg_handle_daemon, &cpg_callbacks_daemon);
- if (error != CPG_OK) {
- log_error("daemon cpg_initialize error %d", error);
- return -1;
- }
-
- cpg_fd_get(cpg_handle_daemon, &cpg_fd_daemon);
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "dlm:controld");
- name.length = strlen(name.value) + 1;
-
- retry:
- error = cpg_join(cpg_handle_daemon, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- sleep(1);
- if (!(++i % 10))
- log_error("daemon cpg_join error retrying");
- goto retry;
- }
- if (error != CPG_OK) {
- log_error("daemon cpg_join error %d", error);
- goto fail;
- }
-
- log_debug("setup_cpg_daemon %d", cpg_fd_daemon);
- return cpg_fd_daemon;
-
- fail:
- cpg_finalize(cpg_handle_daemon);
- return -1;
-}
-
-void close_cpg_daemon(void)
-{
- struct lockspace *ls;
- cpg_error_t error;
- struct cpg_name name;
- int i = 0;
-
- if (!cpg_handle_daemon)
- return;
- if (cluster_down)
- goto fin;
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "dlm:controld");
- name.length = strlen(name.value) + 1;
-
- retry:
- error = cpg_leave(cpg_handle_daemon, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- sleep(1);
- if (!(++i % 10))
- log_error("daemon cpg_leave error retrying");
- goto retry;
- }
- if (error != CPG_OK)
- log_error("daemon cpg_leave error %d", error);
- fin:
- list_for_each_entry(ls, &lockspaces, list) {
- if (ls->cpg_handle)
- cpg_finalize(ls->cpg_handle);
- }
- cpg_finalize(cpg_handle_daemon);
-}
-
-/* fs_controld has seen nodedown for nodeid; it's now ok for dlm to do
- recovery for the failed node */
-
-int set_fs_notified(struct lockspace *ls, int nodeid)
-{
- struct node *node;
-
- /* this shouldn't happen */
- node = get_node_history(ls, nodeid);
- if (!node) {
- log_error("set_fs_notified no nodeid %d", nodeid);
- return -ESRCH;
- }
-
- if (!find_memb(ls->started_change, nodeid)) {
- log_group(ls, "set_fs_notified %d not in ls", nodeid);
- return 0;
- }
-
- /* this can happen, we haven't seen a nodedown for this node yet,
- but we should soon */
- if (!node->check_fs) {
- log_group(ls, "set_fs_notified %d zero check_fs", nodeid);
- return -EAGAIN;
- }
-
- log_group(ls, "set_fs_notified nodeid %d", nodeid);
- node->fs_notified = 1;
- return 0;
-}
-
-int set_lockspace_info(struct lockspace *ls, struct dlmc_lockspace *lockspace)
-{
- struct change *cg, *last = NULL;
-
- strncpy(lockspace->name, ls->name, DLM_LOCKSPACE_LEN);
- lockspace->global_id = ls->global_id;
-
- if (ls->joining)
- lockspace->flags |= DLMC_LF_JOINING;
- if (ls->leaving)
- lockspace->flags |= DLMC_LF_LEAVING;
- if (ls->kernel_stopped)
- lockspace->flags |= DLMC_LF_KERNEL_STOPPED;
- if (ls->fs_registered)
- lockspace->flags |= DLMC_LF_FS_REGISTERED;
- if (ls->need_plocks)
- lockspace->flags |= DLMC_LF_NEED_PLOCKS;
- if (ls->save_plocks)
- lockspace->flags |= DLMC_LF_SAVE_PLOCKS;
-
- if (!ls->started_change)
- goto next;
-
- cg = ls->started_change;
-
- lockspace->cg_prev.member_count = cg->member_count;
- lockspace->cg_prev.joined_count = cg->joined_count;
- lockspace->cg_prev.remove_count = cg->remove_count;
- lockspace->cg_prev.failed_count = cg->failed_count;
- lockspace->cg_prev.combined_seq = cg->combined_seq;
- lockspace->cg_prev.seq = cg->seq;
-
- next:
- if (list_empty(&ls->changes))
- goto out;
-
- list_for_each_entry(cg, &ls->changes, list)
- last = cg;
-
- cg = list_first_entry(&ls->changes, struct change, list);
-
- lockspace->cg_next.member_count = cg->member_count;
- lockspace->cg_next.joined_count = cg->joined_count;
- lockspace->cg_next.remove_count = cg->remove_count;
- lockspace->cg_next.failed_count = cg->failed_count;
- lockspace->cg_next.combined_seq = last->seq;
- lockspace->cg_next.seq = cg->seq;
-
- if (cg->state == CGST_WAIT_CONDITIONS)
- lockspace->cg_next.wait_condition = 4;
- if (poll_fencing)
- lockspace->cg_next.wait_condition = 1;
- else if (poll_quorum)
- lockspace->cg_next.wait_condition = 2;
- else if (poll_fs)
- lockspace->cg_next.wait_condition = 3;
-
- if (cg->state == CGST_WAIT_MESSAGES)
- lockspace->cg_next.wait_messages = 1;
- out:
- return 0;
-}
-
-static int _set_node_info(struct lockspace *ls, struct change *cg, int nodeid,
- struct dlmc_node *node)
-{
- struct member *m = NULL;
- struct node *n;
-
- node->nodeid = nodeid;
-
- if (cg)
- m = find_memb(cg, nodeid);
- if (!m)
- goto history;
-
- node->flags |= DLMC_NF_MEMBER;
-
- if (m->start)
- node->flags |= DLMC_NF_START;
- if (m->disallowed)
- node->flags |= DLMC_NF_DISALLOWED;
-
- history:
- n = get_node_history(ls, nodeid);
- if (!n)
- goto out;
-
- if (n->check_fencing)
- node->flags |= DLMC_NF_CHECK_FENCING;
- if (n->check_quorum)
- node->flags |= DLMC_NF_CHECK_QUORUM;
- if (n->check_fs)
- node->flags |= DLMC_NF_CHECK_FS;
-
- node->added_seq = n->added_seq;
- node->removed_seq = n->removed_seq;
- node->failed_reason = n->failed_reason;
- out:
- return 0;
-}
-
-int set_node_info(struct lockspace *ls, int nodeid, struct dlmc_node *node)
-{
- struct change *cg;
-
- if (!list_empty(&ls->changes)) {
- cg = list_first_entry(&ls->changes, struct change, list);
- return _set_node_info(ls, cg, nodeid, node);
- }
-
- return _set_node_info(ls, ls->started_change, nodeid, node);
-}
-
-int set_lockspaces(int *count, struct dlmc_lockspace **lss_out)
-{
- struct lockspace *ls;
- struct dlmc_lockspace *lss, *lsp;
- int ls_count = 0;
-
- list_for_each_entry(ls, &lockspaces, list)
- ls_count++;
-
- lss = malloc(ls_count * sizeof(struct dlmc_lockspace));
- if (!lss)
- return -ENOMEM;
- memset(lss, 0, ls_count * sizeof(struct dlmc_lockspace));
-
- lsp = lss;
- list_for_each_entry(ls, &lockspaces, list) {
- set_lockspace_info(ls, lsp++);
- }
-
- *count = ls_count;
- *lss_out = lss;
- return 0;
-}
-
-int set_lockspace_nodes(struct lockspace *ls, int option, int *node_count,
- struct dlmc_node **nodes_out)
-{
- struct change *cg;
- struct node *n;
- struct dlmc_node *nodes = NULL, *nodep;
- struct member *memb;
- int count = 0;
-
- if (option == DLMC_NODES_ALL) {
- if (!list_empty(&ls->changes))
- cg = list_first_entry(&ls->changes, struct change,list);
- else
- cg = ls->started_change;
-
- list_for_each_entry(n, &ls->node_history, list)
- count++;
-
- } else if (option == DLMC_NODES_MEMBERS) {
- if (!ls->started_change)
- goto out;
- cg = ls->started_change;
- count = cg->member_count;
-
- } else if (option == DLMC_NODES_NEXT) {
- if (list_empty(&ls->changes))
- goto out;
- cg = list_first_entry(&ls->changes, struct change, list);
- count = cg->member_count;
- } else
- goto out;
-
- nodes = malloc(count * sizeof(struct dlmc_node));
- if (!nodes)
- return -ENOMEM;
- memset(nodes, 0, count * sizeof(struct dlmc_node));
- nodep = nodes;
-
- if (option == DLMC_NODES_ALL) {
- list_for_each_entry(n, &ls->node_history, list)
- _set_node_info(ls, cg, n->nodeid, nodep++);
- } else {
- list_for_each_entry(memb, &cg->members, list)
- _set_node_info(ls, cg, memb->nodeid, nodep++);
- }
- out:
- *node_count = count;
- *nodes_out = nodes;
- return 0;
-}
-
diff --git a/group/dlm_controld/crc.c b/group/dlm_controld/crc.c
deleted file mode 100644
index ff8c1d3..0000000
--- a/group/dlm_controld/crc.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "dlm_daemon.h"
-
-static const uint32_t crc_32_tab[] = {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
- 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
- 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
- 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
- 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
- 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
- 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
- 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
- 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
- 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
- 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
- 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
- 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
- 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
- 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
- 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
- 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
- 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
- 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
- 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
- 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
- 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
-};
-
-/**
- *
- * Copied from:
- *
- * gfs2_disk_hash - hash an array of data
- * @data: the data to be hashed
- * @len: the length of data to be hashed
- *
- * This function must produce the same results as the one in the kernel:
- * crc32_le(0xFFFFFFFF, data, len) ^ 0xFFFFFFFF
- *
- * Take some data and convert it to a 32-bit hash.
- *
- * The hash function is a 32-bit CRC of the data. The algorithm uses
- * the crc_32_tab table above.
- *
- * This may not be the fastest hash function, but it does a fair bit better
- * at providing uniform results than the others I've looked at. That's
- * really important for efficient directories.
- *
- * Returns: the hash
- */
-
-uint32_t cpgname_to_crc(const char *data, int len)
-{
- uint32_t hash = 0xFFFFFFFF;
-
- for (; len--; data++)
- hash = crc_32_tab[(hash ^ *data) & 0xFF] ^ (hash >> 8);
-
- hash = ~hash;
-
- return hash;
-}
-
diff --git a/group/dlm_controld/deadlock.c b/group/dlm_controld/deadlock.c
deleted file mode 100644
index 288f909..0000000
--- a/group/dlm_controld/deadlock.c
+++ /dev/null
@@ -1,1550 +0,0 @@
-#include "dlm_daemon.h"
-#include "config.h"
-#include "libdlm.h"
-
-static SaCkptHandleT global_ckpt_h;
-static SaCkptCallbacksT callbacks = { 0, 0 };
-static SaVersionT version = { 'B', 1, 1 };
-static char section_buf[10 * 1024 * 1024]; /* 10MB of pack_lock's enough? */
-static uint32_t section_len;
-static uint32_t section_max;
-
-struct node {
- struct list_head list;
- int nodeid;
- int checkpoint_ready; /* we've read its ckpt */
- int in_cycle; /* participating in cycle */
-};
-
-enum {
- LOCAL_COPY = 1,
- MASTER_COPY = 2,
-};
-
-/* from linux/fs/dlm/dlm_internal.h */
-#define DLM_LKSTS_WAITING 1
-#define DLM_LKSTS_GRANTED 2
-#define DLM_LKSTS_CONVERT 3
-
-struct pack_lock {
- uint64_t xid;
- uint32_t id;
- int nodeid;
- uint32_t remid;
- int ownpid;
- uint32_t exflags;
- uint32_t flags;
- int8_t status;
- int8_t grmode;
- int8_t rqmode;
- int8_t copy;
-};
-
-struct dlm_rsb {
- struct list_head list;
- struct list_head locks;
- char name[DLM_RESNAME_MAXLEN];
- int len;
-};
-
-/* information is saved in the lkb, and lkb->lock, from the perspective of the
- local or master copy, not the process copy */
-
-struct dlm_lkb {
- struct list_head list; /* r->locks */
- struct pack_lock lock; /* data from debugfs/checkpoint */
- int home; /* node where the lock owner lives*/
- struct dlm_rsb *rsb; /* lock is on resource */
- struct trans *trans; /* lock owned by this transaction */
- struct list_head trans_list; /* tr->locks */
- struct trans *waitfor_trans; /* the trans that's holding the
- lock that's blocking us */
-};
-
-/* waitfor pointers alloc'ed 4 at at time */
-#define TR_NALLOC 4
-
-struct trans {
- struct list_head list;
- struct list_head locks;
- uint64_t xid;
- int others_waiting_on_us; /* count of trans's
- pointing to us in
- waitfor */
- int waitfor_alloc;
- int waitfor_count; /* count of in-use
- waitfor slots and
- num of trans's we're
- waiting on */
- struct trans **waitfor; /* waitfor_alloc trans
- pointers */
-};
-
-static const int __dlm_compat_matrix[8][8] = {
- /* UN NL CR CW PR PW EX PD */
- {1, 1, 1, 1, 1, 1, 1, 0}, /* UN */
- {1, 1, 1, 1, 1, 1, 1, 0}, /* NL */
- {1, 1, 1, 1, 1, 1, 0, 0}, /* CR */
- {1, 1, 1, 1, 0, 0, 0, 0}, /* CW */
- {1, 1, 1, 0, 1, 0, 0, 0}, /* PR */
- {1, 1, 1, 0, 0, 0, 0, 0}, /* PW */
- {1, 1, 0, 0, 0, 0, 0, 0}, /* EX */
- {0, 0, 0, 0, 0, 0, 0, 0} /* PD */
-};
-
-static inline int dlm_modes_compat(int mode1, int mode2)
-{
- return __dlm_compat_matrix[mode1 + 1][mode2 + 1];
-}
-
-static const char *status_str(int lksts)
-{
- switch (lksts) {
- case DLM_LKSTS_WAITING:
- return "W";
- case DLM_LKSTS_GRANTED:
- return "G";
- case DLM_LKSTS_CONVERT:
- return "C";
- }
- return "?";
-}
-
-static void free_resources(struct lockspace *ls)
-{
- struct dlm_rsb *r, *r_safe;
- struct dlm_lkb *lkb, *lkb_safe;
-
- list_for_each_entry_safe(r, r_safe, &ls->resources, list) {
- list_for_each_entry_safe(lkb, lkb_safe, &r->locks, list) {
- list_del(&lkb->list);
- if (!list_empty(&lkb->trans_list))
- list_del(&lkb->trans_list);
- free(lkb);
- }
- list_del(&r->list);
- free(r);
- }
-}
-
-static void free_transactions(struct lockspace *ls)
-{
- struct trans *tr, *tr_safe;
-
- list_for_each_entry_safe(tr, tr_safe, &ls->transactions, list) {
- list_del(&tr->list);
- if (tr->waitfor)
- free(tr->waitfor);
- free(tr);
- }
-}
-
-static void disable_deadlock(void)
-{
- log_error("FIXME: deadlock detection disabled");
-}
-
-void setup_deadlock(void)
-{
- SaAisErrorT rv;
-
- if (!cfgd_enable_deadlk)
- return;
-
- rv = saCkptInitialize(&global_ckpt_h, &callbacks, &version);
- if (rv != SA_AIS_OK)
- log_error("ckpt init error %d", rv);
-}
-
-static struct dlm_rsb *get_resource(struct lockspace *ls, char *name, int len)
-{
- struct dlm_rsb *r;
-
- list_for_each_entry(r, &ls->resources, list) {
- if (r->len == len && !strncmp(r->name, name, len))
- return r;
- }
-
- r = malloc(sizeof(struct dlm_rsb));
- if (!r) {
- log_error("get_resource: no memory");
- disable_deadlock();
- return NULL;
- }
- memset(r, 0, sizeof(struct dlm_rsb));
- memcpy(r->name, name, len);
- r->len = len;
- INIT_LIST_HEAD(&r->locks);
- list_add(&r->list, &ls->resources);
- return r;
-}
-
-static struct dlm_lkb *create_lkb(void)
-{
- struct dlm_lkb *lkb;
-
- lkb = malloc(sizeof(struct dlm_lkb));
- if (!lkb) {
- log_error("create_lkb: no memory");
- disable_deadlock();
- } else {
- memset(lkb, 0, sizeof(struct dlm_lkb));
- INIT_LIST_HEAD(&lkb->list);
- INIT_LIST_HEAD(&lkb->trans_list);
- }
- return lkb;
-}
-
-static void add_lkb(struct dlm_rsb *r, struct dlm_lkb *lkb)
-{
- list_add(&lkb->list, &r->locks);
- lkb->rsb = r;
-}
-
-/* from linux/fs/dlm/dlm_internal.h */
-#define IFL_MSTCPY 0x00010000
-
-/* called on a lock that's just been read from debugfs */
-
-static void set_copy(struct pack_lock *lock)
-{
- uint32_t id, remid;
-
- if (!lock->nodeid)
- lock->copy = LOCAL_COPY;
- else if (lock->flags & IFL_MSTCPY)
- lock->copy = MASTER_COPY;
- else {
- /* process copy lock is converted to a partial master copy
- lock that will be combined with the real master copy */
- lock->copy = MASTER_COPY;
- id = lock->id;
- remid = lock->remid;
- lock->id = remid;
- lock->remid = id;
- lock->nodeid = our_nodeid;
- }
-}
-
-/* xid is always zero in the real master copy, xid should always be non-zero
- in the partial master copy (what was a process copy) */
-/* TODO: confirm or enforce that the partial will always have non-zero xid */
-
-static int partial_master_copy(struct pack_lock *lock)
-{
- return (lock->xid != 0);
-}
-
-static struct dlm_lkb *get_lkb(struct dlm_rsb *r, struct pack_lock *lock)
-{
- struct dlm_lkb *lkb;
-
- if (lock->copy != MASTER_COPY)
- goto out;
-
- list_for_each_entry(lkb, &r->locks, list) {
- if (lkb->lock.nodeid == lock->nodeid &&
- lkb->lock.id == lock->id)
- return lkb;
- }
- out:
- return create_lkb();
-}
-
-static struct dlm_lkb *add_lock(struct lockspace *ls, struct dlm_rsb *r,
- int from_nodeid, struct pack_lock *lock)
-{
- struct dlm_lkb *lkb;
-
- lkb = get_lkb(r, lock);
- if (!lkb)
- return NULL;
-
- switch (lock->copy) {
- case LOCAL_COPY:
- lkb->lock.xid = lock->xid;
- lkb->lock.nodeid = lock->nodeid;
- lkb->lock.id = lock->id;
- lkb->lock.remid = lock->remid;
- lkb->lock.ownpid = lock->ownpid;
- lkb->lock.exflags = lock->exflags;
- lkb->lock.flags = lock->flags;
- lkb->lock.status = lock->status;
- lkb->lock.grmode = lock->grmode;
- lkb->lock.rqmode = lock->rqmode;
- lkb->lock.copy = LOCAL_COPY;
- lkb->home = from_nodeid;
-
- log_group(ls, "add %s local nodeid %d id %x remid %x xid %llx",
- r->name, lock->nodeid, lock->id, lock->remid,
- (unsigned long long)lock->xid);
- break;
-
- case MASTER_COPY:
- if (partial_master_copy(lock)) {
- lkb->lock.xid = lock->xid;
- lkb->lock.nodeid = lock->nodeid;
- lkb->lock.id = lock->id;
- lkb->lock.remid = lock->remid;
- lkb->lock.copy = MASTER_COPY;
- } else {
- /* only set xid from partial master copy above */
- lkb->lock.nodeid = lock->nodeid;
- lkb->lock.id = lock->id;
- lkb->lock.remid = lock->remid;
- lkb->lock.copy = MASTER_COPY;
- /* set other fields from real master copy */
- lkb->lock.ownpid = lock->ownpid;
- lkb->lock.exflags = lock->exflags;
- lkb->lock.flags = lock->flags;
- lkb->lock.status = lock->status;
- lkb->lock.grmode = lock->grmode;
- lkb->lock.rqmode = lock->rqmode;
- }
- lkb->home = lock->nodeid;
-
- log_group(ls, "add %s master nodeid %d id %x remid %x xid %llx",
- r->name, lock->nodeid, lock->id, lock->remid,
- (unsigned long long)lock->xid);
- break;
- }
-
- if (list_empty(&lkb->list))
- add_lkb(r, lkb);
- return lkb;
-}
-
-static void parse_r_name(char *line, char *name)
-{
- char *p;
- int i = 0;
- int begin = 0;
-
- for (p = line; ; p++) {
- if (*p == '"') {
- if (begin)
- break;
- begin = 1;
- continue;
- }
- if (begin)
- name[i++] = *p;
- }
-}
-
-#define LOCK_LINE_MAX 1024
-
-static int read_debugfs_locks(struct lockspace *ls)
-{
- FILE *file;
- char path[PATH_MAX];
- char line[LOCK_LINE_MAX];
- struct dlm_rsb *r;
- struct pack_lock lock;
- char r_name[65];
- unsigned long long xid;
- unsigned int waiting;
- int r_nodeid;
- int r_len;
- int rv;
-
- snprintf(path, PATH_MAX, "/sys/kernel/debug/dlm/%s_locks", ls->name);
-
- file = fopen(path, "r");
- if (!file)
- return -1;
-
- /* skip the header on the first line */
- if (!fgets(line, LOCK_LINE_MAX, file)) {
- log_error("Unable to read %s: %d", path, errno);
- goto out;
- }
-
- while (fgets(line, LOCK_LINE_MAX, file)) {
- memset(&lock, 0, sizeof(struct pack_lock));
-
- rv = sscanf(line, "%x %d %x %u %llu %x %x %hhd %hhd %hhd %u %d %d",
- &lock.id,
- &lock.nodeid,
- &lock.remid,
- &lock.ownpid,
- &xid,
- &lock.exflags,
- &lock.flags,
- &lock.status,
- &lock.grmode,
- &lock.rqmode,
- &waiting,
- &r_nodeid,
- &r_len);
-
- lock.xid = xid; /* hack to avoid warning */
-
- if (rv != 13) {
- log_error("invalid debugfs line %d: %s", rv, line);
- goto out;
- }
-
- memset(r_name, 0, sizeof(r_name));
- parse_r_name(line, r_name);
-
- r = get_resource(ls, r_name, r_len);
- if (!r)
- break;
-
- set_copy(&lock);
- add_lock(ls, r, our_nodeid, &lock);
- }
- out:
- fclose(file);
- return 0;
-}
-
-static int read_checkpoint_locks(struct lockspace *ls, int from_nodeid,
- char *numbuf, int buflen)
-{
- struct dlm_rsb *r;
- struct pack_lock *lock;
- int count = section_len / sizeof(struct pack_lock);
- int i;
-
- r = get_resource(ls, numbuf, buflen - 1);
- if (!r)
- return -1;
-
- lock = (struct pack_lock *) §ion_buf;
-
- for (i = 0; i < count; i++) {
- lock->xid = le64_to_cpu(lock->xid);
- lock->id = le32_to_cpu(lock->id);
- lock->nodeid = le32_to_cpu(lock->nodeid);
- lock->remid = le32_to_cpu(lock->remid);
- lock->ownpid = le32_to_cpu(lock->ownpid);
- lock->exflags = le32_to_cpu(lock->exflags);
- lock->flags = le32_to_cpu(lock->flags);
-
- add_lock(ls, r, from_nodeid, lock);
- lock++;
- }
- return 0;
-}
-
-static int pack_lkb_list(struct list_head *q, struct pack_lock **lockp)
-{
- struct dlm_lkb *lkb;
- struct pack_lock *lock = *lockp;
- int count = 0;
-
- list_for_each_entry(lkb, q, list) {
- if (count + 1 > section_max) {
- log_error("too many locks %d for ckpt buf", count);
- break;
- }
-
- lock->xid = cpu_to_le64(lkb->lock.xid);
- lock->id = cpu_to_le32(lkb->lock.id);
- lock->nodeid = cpu_to_le32(lkb->lock.nodeid);
- lock->remid = cpu_to_le32(lkb->lock.remid);
- lock->ownpid = cpu_to_le32(lkb->lock.ownpid);
- lock->exflags = cpu_to_le32(lkb->lock.exflags);
- lock->flags = cpu_to_le32(lkb->lock.flags);
- lock->status = lkb->lock.status;
- lock->grmode = lkb->lock.grmode;
- lock->rqmode = lkb->lock.rqmode;
- lock->copy = lkb->lock.copy;
-
- lock++;
- count++;
- }
- return count;
-}
-
-static void pack_section_buf(struct lockspace *ls, struct dlm_rsb *r)
-{
- struct pack_lock *lock;
- int count;
-
- memset(§ion_buf, 0, sizeof(section_buf));
- section_max = sizeof(section_buf) / sizeof(struct pack_lock);
-
- lock = (struct pack_lock *) §ion_buf;
-
- count = pack_lkb_list(&r->locks, &lock);
-
- section_len = count * sizeof(struct pack_lock);
-}
-
-static int _unlink_checkpoint(struct lockspace *ls, SaNameT *name)
-{
- SaCkptCheckpointHandleT h;
- SaCkptCheckpointDescriptorT s;
- SaAisErrorT rv;
- int ret = 0;
- int retries;
-
- h = (SaCkptCheckpointHandleT) ls->deadlk_ckpt_handle;
- log_group(ls, "unlink ckpt %llx", (unsigned long long)h);
-
- retries = 0;
- unlink_retry:
- rv = saCkptCheckpointUnlink(global_ckpt_h, name);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "unlink ckpt retry");
- sleep(1);
- if (retries++ < 10)
- goto unlink_retry;
- }
- if (rv == SA_AIS_OK)
- goto out_close;
- if (!h)
- goto out;
-
- log_error("unlink ckpt error %d %s", rv, ls->name);
- ret = -1;
-
- retries = 0;
- status_retry:
- rv = saCkptCheckpointStatusGet(h, &s);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "unlink ckpt status retry");
- sleep(1);
- if (retries++ < 10)
- goto status_retry;
- }
- if (rv != SA_AIS_OK) {
- log_error("unlink ckpt status error %d %s", rv, ls->name);
- goto out_close;
- }
-
- log_group(ls, "unlink ckpt status: size %llu, max sections %u, "
- "max section size %llu, section count %u, mem %u",
- (unsigned long long)s.checkpointCreationAttributes.checkpointSize,
- s.checkpointCreationAttributes.maxSections,
- (unsigned long long)s.checkpointCreationAttributes.maxSectionSize,
- s.numberOfSections, s.memoryUsed);
-
- out_close:
- retries = 0;
- close_retry:
- rv = saCkptCheckpointClose(h);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "unlink ckpt close retry");
- sleep(1);
- if (retries++ < 10)
- goto close_retry;
- }
- if (rv != SA_AIS_OK) {
- log_error("unlink ckpt %llx close err %d %s",
- (unsigned long long)h, rv, ls->name);
- }
- out:
- ls->deadlk_ckpt_handle = 0;
- return ret;
-}
-
-static int unlink_checkpoint(struct lockspace *ls)
-{
- SaNameT name;
- int len;
-
- len = snprintf((char *)name.value, SA_MAX_NAME_LENGTH, "dlmdeadlk.%s.%d",
- ls->name, our_nodeid);
- name.length = len;
-
- return _unlink_checkpoint(ls, &name);
-}
-
-static void read_checkpoint(struct lockspace *ls, int nodeid)
-{
- SaCkptCheckpointHandleT h;
- SaCkptSectionIterationHandleT itr;
- SaCkptSectionDescriptorT desc;
- SaCkptIOVectorElementT iov;
- SaNameT name;
- SaAisErrorT rv;
- char buf[DLM_RESNAME_MAXLEN];
- int len;
- int retries;
-
- if (nodeid == our_nodeid)
- return;
-
- log_group(ls, "read_checkpoint %d", nodeid);
-
- len = snprintf((char *)name.value, SA_MAX_NAME_LENGTH, "dlmdeadlk.%s.%d",
- ls->name, nodeid);
- name.length = len;
-
- retries = 0;
- open_retry:
- rv = saCkptCheckpointOpen(global_ckpt_h, &name, NULL,
- SA_CKPT_CHECKPOINT_READ, 0, &h);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "read_checkpoint: %d ckpt open retry", nodeid);
- sleep(1);
- if (retries++ < 10)
- goto open_retry;
- }
- if (rv != SA_AIS_OK) {
- log_error("read_checkpoint: %d ckpt open error %d", nodeid, rv);
- return;
- }
-
- retries = 0;
- init_retry:
- rv = saCkptSectionIterationInitialize(h, SA_CKPT_SECTIONS_ANY, 0, &itr);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "read_checkpoint: ckpt iterinit retry");
- sleep(1);
- if (retries++ < 10)
- goto init_retry;
- }
- if (rv != SA_AIS_OK) {
- log_error("read_checkpoint: %d ckpt iterinit error %d", nodeid, rv);
- goto out;
- }
-
- while (1) {
- retries = 0;
- next_retry:
- rv = saCkptSectionIterationNext(itr, &desc);
- if (rv == SA_AIS_ERR_NO_SECTIONS)
- break;
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "read_checkpoint: ckpt iternext retry");
- sleep(1);
- if (retries++ < 10)
- goto next_retry;
- }
- if (rv != SA_AIS_OK) {
- log_error("read_checkpoint: %d ckpt iternext error %d",
- nodeid, rv);
- goto out_it;
- }
-
- if (!desc.sectionSize)
- continue;
-
- iov.sectionId = desc.sectionId;
- iov.dataBuffer = §ion_buf;
- iov.dataSize = desc.sectionSize;
- iov.dataOffset = 0;
-
- memset(&buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "%s", desc.sectionId.id);
-
- log_group(ls, "read_checkpoint: section size %llu id %u \"%s\"",
- (unsigned long long)iov.dataSize,
- iov.sectionId.idLen, buf);
-
- retries = 0;
- read_retry:
- rv = saCkptCheckpointRead(h, &iov, 1, NULL);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "read_checkpoint: ckpt read retry");
- sleep(1);
- if (retries++ < 10)
- goto read_retry;
- }
- if (rv != SA_AIS_OK) {
- log_error("read_checkpoint: %d ckpt read error %d",
- nodeid, rv);
- goto out_it;
- }
-
- section_len = iov.readSize;
-
- if (!section_len)
- continue;
-
- if (section_len % sizeof(struct pack_lock)) {
- log_error("read_checkpoint: %d bad section len %d",
- nodeid, section_len);
- continue;
- }
-
- read_checkpoint_locks(ls, nodeid, (char *)desc.sectionId.id,
- desc.sectionId.idLen);
- }
-
- out_it:
- saCkptSectionIterationFinalize(itr);
- retries = 0;
- out:
- rv = saCkptCheckpointClose(h);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "read_checkpoint: unlink ckpt close retry");
- sleep(1);
- if (retries++ < 10)
- goto out;
- }
- if (rv != SA_AIS_OK)
- log_error("read_checkpoint: %d close error %d", nodeid, rv);
-}
-
-static void write_checkpoint(struct lockspace *ls)
-{
- SaCkptCheckpointCreationAttributesT attr;
- SaCkptCheckpointHandleT h;
- SaCkptSectionIdT section_id;
- SaCkptSectionCreationAttributesT section_attr;
- SaCkptCheckpointOpenFlagsT flags;
- SaNameT name;
- SaAisErrorT rv;
- char buf[DLM_RESNAME_MAXLEN];
- struct dlm_rsb *r;
- struct dlm_lkb *lkb;
- int r_count, lock_count, total_size, section_size, max_section_size;
- int len;
-
- len = snprintf((char *)name.value, SA_MAX_NAME_LENGTH, "dlmdeadlk.%s.%d",
- ls->name, our_nodeid);
- name.length = len;
-
- /* unlink an old checkpoint before we create a new one */
- if (ls->deadlk_ckpt_handle) {
- log_error("write_checkpoint: old ckpt");
- if (_unlink_checkpoint(ls, &name))
- return;
- }
-
- /* loop through all locks to figure out sizes to set in
- the attr fields */
-
- r_count = 0;
- lock_count = 0;
- total_size = 0;
- max_section_size = 0;
-
- list_for_each_entry(r, &ls->resources, list) {
- r_count++;
- section_size = 0;
- list_for_each_entry(lkb, &r->locks, list) {
- section_size += sizeof(struct pack_lock);
- lock_count++;
- }
- total_size += section_size;
- if (section_size > max_section_size)
- max_section_size = section_size;
- }
-
- log_group(ls, "write_checkpoint: r_count %d, lock_count %d",
- r_count, lock_count);
-
- log_group(ls, "write_checkpoint: total %d bytes, max_section %d bytes",
- total_size, max_section_size);
-
- attr.creationFlags = SA_CKPT_WR_ALL_REPLICAS;
- attr.checkpointSize = total_size;
- attr.retentionDuration = SA_TIME_MAX;
- attr.maxSections = r_count + 1; /* don't know why we need +1 */
- attr.maxSectionSize = max_section_size;
- attr.maxSectionIdSize = DLM_RESNAME_MAXLEN;
-
- flags = SA_CKPT_CHECKPOINT_READ |
- SA_CKPT_CHECKPOINT_WRITE |
- SA_CKPT_CHECKPOINT_CREATE;
-
- open_retry:
- rv = saCkptCheckpointOpen(global_ckpt_h, &name, &attr, flags, 0, &h);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "write_checkpoint: ckpt open retry");
- sleep(1);
- goto open_retry;
- }
- if (rv == SA_AIS_ERR_EXIST) {
- log_group(ls, "write_checkpoint: ckpt already exists");
- return;
- }
- if (rv != SA_AIS_OK) {
- log_group(ls, "write_checkpoint: ckpt open error %d", rv);
- return;
- }
-
- log_group(ls, "write_checkpoint: open ckpt handle %llx",
- (unsigned long long)h);
- ls->deadlk_ckpt_handle = (uint64_t) h;
-
- list_for_each_entry(r, &ls->resources, list) {
- memset(buf, 0, sizeof(buf));
- len = snprintf(buf, sizeof(buf), "%s", r->name);
-
- section_id.id = (void *)buf;
- section_id.idLen = len + 1;
- section_attr.sectionId = §ion_id;
- section_attr.expirationTime = SA_TIME_END;
-
- pack_section_buf(ls, r);
-
- log_group(ls, "write_checkpoint: section size %u id %u \"%s\"",
- section_len, section_id.idLen, buf);
-
- create_retry:
- rv = saCkptSectionCreate(h, §ion_attr, §ion_buf,
- section_len);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "write_checkpoint: ckpt create retry");
- sleep(1);
- goto create_retry;
- }
- if (rv == SA_AIS_ERR_EXIST) {
- /* this shouldn't happen in general */
- log_error("write_checkpoint: clearing old ckpt");
- saCkptCheckpointClose(h);
- _unlink_checkpoint(ls, &name);
- goto open_retry;
- }
- if (rv != SA_AIS_OK) {
- log_error("write_checkpoint: section create %d", rv);
- break;
- }
- }
-}
-
-static void send_message(struct lockspace *ls, int type,
- uint32_t to_nodeid, uint32_t msgdata)
-{
- struct dlm_header *hd;
- int len;
- char *buf;
-
- len = sizeof(struct dlm_header);
- buf = malloc(len);
- if (!buf) {
- log_error("send_message: no memory");
- disable_deadlock();
- return;
- }
- memset(buf, 0, len);
-
- hd = (struct dlm_header *)buf;
- hd->type = type;
- hd->to_nodeid = to_nodeid;
- hd->msgdata = msgdata;
-
- dlm_send_message(ls, buf, len);
-
- free(buf);
-}
-
-static void send_checkpoint_ready(struct lockspace *ls)
-{
- log_group(ls, "send_checkpoint_ready");
- send_message(ls, DLM_MSG_DEADLK_CHECKPOINT_READY, 0, 0);
-}
-
-void send_cycle_start(struct lockspace *ls)
-{
- log_group(ls, "send_cycle_start");
- send_message(ls, DLM_MSG_DEADLK_CYCLE_START, 0, 0);
-}
-
-static void send_cycle_end(struct lockspace *ls)
-{
- log_group(ls, "send_cycle_end");
- send_message(ls, DLM_MSG_DEADLK_CYCLE_END, 0, 0);
-}
-
-static void send_cancel_lock(struct lockspace *ls, struct trans *tr,
- struct dlm_lkb *lkb)
-{
- int to_nodeid;
- uint32_t lkid;
-
- if (!lkb->lock.nodeid)
- lkid = lkb->lock.id;
- else
- lkid = lkb->lock.remid;
- to_nodeid = lkb->home;
-
- log_group(ls, "send_cancel_lock to nodeid %d rsb %s id %x xid %llx",
- to_nodeid, lkb->rsb->name, lkid,
- (unsigned long long)lkb->lock.xid);
-
- send_message(ls, DLM_MSG_DEADLK_CANCEL_LOCK, to_nodeid, lkid);
-}
-
-static void dump_resources(struct lockspace *ls)
-{
- struct dlm_rsb *r;
- struct dlm_lkb *lkb;
-
- log_group(ls, "Resource dump:");
-
- list_for_each_entry(r, &ls->resources, list) {
- log_group(ls, "\"%s\" len %d", r->name, r->len);
- list_for_each_entry(lkb, &r->locks, list) {
- log_group(ls, " %s: nodeid %d id %08x remid %08x gr %s rq %s pid %u xid %llx",
- status_str(lkb->lock.status),
- lkb->lock.nodeid,
- lkb->lock.id,
- lkb->lock.remid,
- dlm_mode_str(lkb->lock.grmode),
- dlm_mode_str(lkb->lock.rqmode),
- lkb->lock.ownpid,
- (unsigned long long)lkb->lock.xid);
- }
- }
-}
-
-static void find_deadlock(struct lockspace *ls);
-
-static void run_deadlock(struct lockspace *ls)
-{
- struct node *node;
- int not_ready = 0;
- int low = -1;
-
- if (ls->all_checkpoints_ready)
- log_group(ls, "WARNING: run_deadlock all_checkpoints_ready");
-
- list_for_each_entry(node, &ls->deadlk_nodes, list) {
- if (!node->in_cycle)
- continue;
- if (!node->checkpoint_ready)
- not_ready++;
-
- log_group(ls, "nodeid %d checkpoint_ready = %d",
- node->nodeid, node->checkpoint_ready);
- }
- if (not_ready)
- return;
-
- ls->all_checkpoints_ready = 1;
-
- list_for_each_entry(node, &ls->deadlk_nodes, list) {
- if (!node->in_cycle)
- continue;
- if (node->nodeid < low || low == -1)
- low = node->nodeid;
- }
- ls->deadlk_low_nodeid = low;
-
- if (low == our_nodeid)
- find_deadlock(ls);
- else
- log_group(ls, "defer resolution to low nodeid %d", low);
-}
-
-void receive_checkpoint_ready(struct lockspace *ls, struct dlm_header *hd,
- int len)
-{
- struct node *node;
- int nodeid = hd->nodeid;
-
- log_group(ls, "receive_checkpoint_ready from %d", nodeid);
-
- read_checkpoint(ls, nodeid);
-
- list_for_each_entry(node, &ls->deadlk_nodes, list) {
- if (node->nodeid == nodeid) {
- node->checkpoint_ready = 1;
- break;
- }
- }
-
- run_deadlock(ls);
-}
-
-void receive_cycle_start(struct lockspace *ls, struct dlm_header *hd, int len)
-{
- struct node *node;
- int nodeid = hd->nodeid;
- int rv;
-
- log_group(ls, "receive_cycle_start from %d", nodeid);
-
- if (ls->cycle_running) {
- log_group(ls, "cycle already running");
- return;
- }
- ls->cycle_running = 1;
- gettimeofday(&ls->cycle_start_time, NULL);
-
- list_for_each_entry(node, &ls->deadlk_nodes, list)
- node->in_cycle = 1;
-
- rv = read_debugfs_locks(ls);
- if (rv < 0) {
- log_error("can't read dlm debugfs file: %s", strerror(errno));
- return;
- }
-
- write_checkpoint(ls);
- send_checkpoint_ready(ls);
-}
-
-static uint64_t dt_usec(struct timeval *start, struct timeval *stop)
-{
- uint64_t dt;
-
- dt = stop->tv_sec - start->tv_sec;
- dt *= 1000000;
- dt += stop->tv_usec - start->tv_usec;
- return dt;
-}
-
-/* TODO: nodes added during a cycle - what will they do with messages
- they recv from other nodes running the cycle? */
-
-void receive_cycle_end(struct lockspace *ls, struct dlm_header *hd, int len)
-{
- struct node *node;
- int nodeid = hd->nodeid;
- uint64_t usec;
-
- if (!ls->cycle_running) {
- log_error("receive_cycle_end %s from %d: no cycle running",
- ls->name, nodeid);
- return;
- }
-
- gettimeofday(&ls->cycle_end_time, NULL);
- usec = dt_usec(&ls->cycle_start_time, &ls->cycle_end_time);
- log_group(ls, "receive_cycle_end: from %d cycle time %.2f s",
- nodeid, usec * 1.e-6);
-
- ls->cycle_running = 0;
- ls->all_checkpoints_ready = 0;
-
- list_for_each_entry(node, &ls->deadlk_nodes, list)
- node->checkpoint_ready = 0;
-
- free_resources(ls);
- free_transactions(ls);
- unlink_checkpoint(ls);
-}
-
-void receive_cancel_lock(struct lockspace *ls, struct dlm_header *hd, int len)
-{
- dlm_lshandle_t h;
- int nodeid = hd->nodeid;
- uint32_t lkid = hd->msgdata;
- int rv;
-
- if (nodeid != our_nodeid)
- return;
-
- h = dlm_open_lockspace(ls->name);
- if (!h) {
- log_error("deadlock cancel %x from %d can't open lockspace %s",
- lkid, nodeid, ls->name);
- return;
- }
-
- log_group(ls, "receive_cancel_lock %x from %d", lkid, nodeid);
-
- rv = dlm_ls_deadlock_cancel(h, lkid, 0);
- if (rv < 0) {
- log_error("deadlock cancel %x from %x lib cancel errno %d",
- lkid, nodeid, errno);
- }
-
- dlm_close_lockspace(h);
-}
-
-static void node_joined(struct lockspace *ls, int nodeid)
-{
- struct node *node;
-
- node = malloc(sizeof(struct node));
- if (!node) {
- log_error("node_joined: no memory");
- disable_deadlock();
- return;
- }
- memset(node, 0, sizeof(struct node));
- node->nodeid = nodeid;
- list_add_tail(&node->list, &ls->deadlk_nodes);
- log_group(ls, "node %d joined deadlock cpg", nodeid);
-}
-
-static void node_left(struct lockspace *ls, int nodeid, int reason)
-{
- struct node *node, *safe;
-
- list_for_each_entry_safe(node, safe, &ls->deadlk_nodes, list) {
- if (node->nodeid != nodeid)
- continue;
-
- list_del(&node->list);
- free(node);
- log_group(ls, "node %d left deadlock cpg", nodeid);
- }
-}
-
-static void purge_locks(struct lockspace *ls, int nodeid);
-
-void deadlk_confchg(struct lockspace *ls,
- const struct cpg_address *member_list,
- size_t member_list_entries,
- const struct cpg_address *left_list,
- size_t left_list_entries,
- const struct cpg_address *joined_list,
- size_t joined_list_entries)
-{
- int i;
-
- if (!cfgd_enable_deadlk)
- return;
-
- if (!ls->deadlk_confchg_init) {
- ls->deadlk_confchg_init = 1;
- for (i = 0; i < member_list_entries; i++)
- node_joined(ls, member_list[i].nodeid);
- return;
- }
-
- /* nodes added during a cycle won't have node->in_cycle set so they
- won't be included in any of the cycle processing */
-
- for (i = 0; i < joined_list_entries; i++)
- node_joined(ls, joined_list[i].nodeid);
-
- for (i = 0; i < left_list_entries; i++)
- node_left(ls, left_list[i].nodeid, left_list[i].reason);
-
- if (!ls->cycle_running)
- return;
-
- if (!left_list_entries)
- return;
-
- if (!ls->all_checkpoints_ready) {
- run_deadlock(ls);
- return;
- }
-
- for (i = 0; i < left_list_entries; i++)
- purge_locks(ls, left_list[i].nodeid);
-
- for (i = 0; i < left_list_entries; i++) {
- if (left_list[i].nodeid != ls->deadlk_low_nodeid)
- continue;
- /* this will set a new low node which will call find_deadlock */
- run_deadlock(ls);
- break;
- }
-}
-
-/* would we ever call this after we've created the transaction lists?
- I don't think so; I think it can only be called between reading
- checkpoints */
-
-static void purge_locks(struct lockspace *ls, int nodeid)
-{
- struct dlm_rsb *r;
- struct dlm_lkb *lkb, *safe;
-
- list_for_each_entry(r, &ls->resources, list) {
- list_for_each_entry_safe(lkb, safe, &r->locks, list) {
- if (lkb->home == nodeid) {
- list_del(&lkb->list);
- if (list_empty(&lkb->trans_list))
- free(lkb);
- else
- log_group(ls, "purge %d %x on trans",
- nodeid, lkb->lock.id);
- }
- }
- }
-}
-
-static void add_lkb_trans(struct trans *tr, struct dlm_lkb *lkb)
-{
- list_add(&lkb->trans_list, &tr->locks);
- lkb->trans = tr;
-}
-
-static struct trans *get_trans(struct lockspace *ls, uint64_t xid)
-{
- struct trans *tr;
-
- list_for_each_entry(tr, &ls->transactions, list) {
- if (tr->xid == xid)
- return tr;
- }
-
- tr = malloc(sizeof(struct trans));
- if (!tr) {
- log_error("get_trans: no memory");
- disable_deadlock();
- return NULL;
- }
- memset(tr, 0, sizeof(struct trans));
- tr->xid = xid;
- tr->waitfor = NULL;
- tr->waitfor_alloc = 0;
- tr->waitfor_count = 0;
- INIT_LIST_HEAD(&tr->locks);
- list_add(&tr->list, &ls->transactions);
- return tr;
-}
-
-/* for each rsb, for each lock, find/create trans, add lkb to the trans list */
-
-static void create_trans_list(struct lockspace *ls)
-{
- struct dlm_rsb *r;
- struct dlm_lkb *lkb;
- struct trans *tr;
- int r_count = 0, lkb_count = 0;
-
- list_for_each_entry(r, &ls->resources, list) {
- r_count++;
- list_for_each_entry(lkb, &r->locks, list) {
- lkb_count++;
- tr = get_trans(ls, lkb->lock.xid);
- if (!tr)
- goto out;
- add_lkb_trans(tr, lkb);
- }
- }
- out:
- log_group(ls, "create_trans_list: r_count %d lkb_count %d",
- r_count, lkb_count);
-}
-
-static int locks_compat(struct dlm_lkb *waiting_lkb,
- struct dlm_lkb *granted_lkb)
-{
- if (waiting_lkb == granted_lkb) {
- log_debug("waiting and granted same lock");
- return 0;
- }
-
- if (waiting_lkb->trans->xid == granted_lkb->trans->xid) {
- log_debug("waiting and granted same trans %llx",
- (unsigned long long)waiting_lkb->trans->xid);
- return 0;
- }
-
- return dlm_modes_compat(granted_lkb->lock.grmode,
- waiting_lkb->lock.rqmode);
-}
-
-static int in_waitfor(struct trans *tr, struct trans *add_tr)
-{
- int i;
-
- for (i = 0; i < tr->waitfor_alloc; i++) {
- if (!tr->waitfor[i])
- continue;
- if (tr->waitfor[i] == add_tr)
- return 1;
- }
- return 0;
-}
-
-static void add_waitfor(struct lockspace *ls, struct dlm_lkb *waiting_lkb,
- struct dlm_lkb *granted_lkb)
-{
- struct trans *tr = waiting_lkb->trans;
- int i;
-
- if (locks_compat(waiting_lkb, granted_lkb))
- return;
-
- /* this shouldn't happen AFAIK */
- if (tr == granted_lkb->trans) {
- log_group(ls, "trans %llx waiting on self",
- (unsigned long long)tr->xid);
- return;
- }
-
- /* don't add the same trans to the waitfor list multiple times */
- if (tr->waitfor_count && in_waitfor(tr, granted_lkb->trans)) {
- log_group(ls, "trans %llx already waiting for trans %llx, "
- "waiting %x %s, granted %x %s",
- (unsigned long long)waiting_lkb->trans->xid,
- (unsigned long long)granted_lkb->trans->xid,
- waiting_lkb->lock.id, waiting_lkb->rsb->name,
- granted_lkb->lock.id, granted_lkb->rsb->name);
- return;
- }
-
- if (tr->waitfor_count == tr->waitfor_alloc) {
- struct trans **old_waitfor = tr->waitfor;
- tr->waitfor_alloc += TR_NALLOC;
- tr->waitfor = malloc(tr->waitfor_alloc * sizeof(tr));
- if (!tr->waitfor) {
- log_error("add_waitfor no mem %u", tr->waitfor_alloc);
- return;
- }
- memset(tr->waitfor, 0, tr->waitfor_alloc * sizeof(tr));
-
- /* copy then free old set of pointers */
- for (i = 0; i < tr->waitfor_count; i++)
- tr->waitfor[i] = old_waitfor[i];
- if (old_waitfor)
- free(old_waitfor);
- }
-
- tr->waitfor[tr->waitfor_count++] = granted_lkb->trans;
- granted_lkb->trans->others_waiting_on_us++;
- waiting_lkb->waitfor_trans = granted_lkb->trans;
-}
-
-/* for each trans, for each waiting lock, go to rsb of the lock,
- find granted locks on that rsb, then find the trans the
- granted lock belongs to, add that trans to our waitfor list */
-
-static void create_waitfor_graph(struct lockspace *ls)
-{
- struct dlm_lkb *waiting_lkb, *granted_lkb;
- struct dlm_rsb *r;
- struct trans *tr;
- int depend_count = 0;
-
- list_for_each_entry(tr, &ls->transactions, list) {
- list_for_each_entry(waiting_lkb, &tr->locks, trans_list) {
- if (waiting_lkb->lock.status == DLM_LKSTS_GRANTED)
- continue;
- /* waiting_lkb status is CONVERT or WAITING */
-
- r = waiting_lkb->rsb;
-
- list_for_each_entry(granted_lkb, &r->locks, list) {
- if (granted_lkb->lock.status==DLM_LKSTS_WAITING)
- continue;
- /* granted_lkb status is GRANTED or CONVERT */
- add_waitfor(ls, waiting_lkb, granted_lkb);
- depend_count++;
- }
- }
- }
-
- log_group(ls, "create_waitfor_graph: depend_count %d", depend_count);
-}
-
-/* Assume a transaction that's not waiting on any locks will complete, release
- all the locks it currently holds, and exit. Other transactions that were
- blocked waiting on the removed transaction's now-released locks may now be
- unblocked, complete, release all held locks and exit. Repeat this until
- no more transactions can be removed. If there are transactions remaining,
- then they are deadlocked. */
-
-static void remove_waitfor(struct trans *tr, struct trans *remove_tr)
-{
- int i;
-
- for (i = 0; i < tr->waitfor_alloc; i++) {
- if (!tr->waitfor_count)
- break;
-
- if (!tr->waitfor[i])
- continue;
-
- if (tr->waitfor[i] == remove_tr) {
- tr->waitfor[i] = NULL;
- tr->waitfor_count--;
- remove_tr->others_waiting_on_us--;
- }
- }
-}
-
-/* remove_tr is not waiting for anything, assume it completes and goes away
- and remove it from any other transaction's waitfor list */
-
-static void remove_trans(struct lockspace *ls, struct trans *remove_tr)
-{
- struct trans *tr;
-
- list_for_each_entry(tr, &ls->transactions, list) {
- if (tr == remove_tr)
- continue;
- if (!remove_tr->others_waiting_on_us)
- break;
- remove_waitfor(tr, remove_tr);
- }
-
- if (remove_tr->others_waiting_on_us)
- log_group(ls, "trans %llx removed others waiting %d",
- (unsigned long long)remove_tr->xid,
- remove_tr->others_waiting_on_us);
-}
-
-static int reduce_waitfor_graph(struct lockspace *ls)
-{
- struct trans *tr, *safe;
- int blocked = 0;
- int removed = 0;
-
- list_for_each_entry_safe(tr, safe, &ls->transactions, list) {
- if (tr->waitfor_count) {
- blocked++;
- continue;
- }
- remove_trans(ls, tr);
- list_del(&tr->list);
- if (tr->waitfor)
- free(tr->waitfor);
- free(tr);
- removed++;
- }
-
- log_group(ls, "reduce_waitfor_graph: %d blocked, %d removed",
- blocked, removed);
- return removed;
-}
-
-static void reduce_waitfor_graph_loop(struct lockspace *ls)
-{
- int removed;
-
- while (1) {
- removed = reduce_waitfor_graph(ls);
- if (!removed)
- break;
- }
-}
-
-static struct trans *find_trans_to_cancel(struct lockspace *ls)
-{
- struct trans *tr;
-
- list_for_each_entry(tr, &ls->transactions, list) {
- if (!tr->others_waiting_on_us)
- continue;
- return tr;
- }
- return NULL;
-}
-
-static void cancel_trans(struct lockspace *ls)
-{
- struct trans *tr;
- struct dlm_lkb *lkb;
- int removed;
-
- tr = find_trans_to_cancel(ls);
- if (!tr) {
- log_group(ls, "cancel_trans: no trans found");
- return;
- }
-
- list_for_each_entry(lkb, &tr->locks, trans_list) {
- if (lkb->lock.status == DLM_LKSTS_GRANTED)
- continue;
- send_cancel_lock(ls, tr, lkb);
-
- /* When this canceled trans has multiple locks all blocked by
- locks held by one other trans, that other trans is only
- added to tr->waitfor once, and only one of these waiting
- locks will have waitfor_trans set. So, the lkb with
- non-null waitfor_trans was the first one responsible
- for adding waitfor_trans to tr->waitfor.
-
- We could potentially forget about keeping track of lkb->
- waitfor_trans, forget about calling remove_waitfor()
- here and just set tr->waitfor_count = 0 after this loop.
- The loss would be that waitfor_trans->others_waiting_on_us
- would not get decremented. */
-
- if (lkb->waitfor_trans)
- remove_waitfor(tr, lkb->waitfor_trans);
- }
-
- /* this shouldn't happen, if it does something's not working right */
- if (tr->waitfor_count) {
- log_group(ls, "cancel_trans: %llx non-zero waitfor_count %d",
- (unsigned long long)tr->xid, tr->waitfor_count);
- }
-
- /* this should now remove the canceled trans since it now has a zero
- waitfor_count */
- removed = reduce_waitfor_graph(ls);
-
- if (!removed)
- log_group(ls, "canceled trans not removed from graph");
-
- /* now call reduce_waitfor_graph() in another loop and it
- should completely reduce */
-}
-
-static void dump_trans(struct lockspace *ls, struct trans *tr)
-{
- struct dlm_lkb *lkb;
- struct trans *wf;
- int i;
-
- log_group(ls, "trans xid %llx waitfor_count %d others_waiting_on_us %d",
- (unsigned long long)tr->xid, tr->waitfor_count,
- tr->others_waiting_on_us);
-
- log_group(ls, "locks:");
-
- list_for_each_entry(lkb, &tr->locks, trans_list) {
- log_group(ls, " %s: id %08x gr %s rq %s pid %u:%u \"%s\"",
- status_str(lkb->lock.status),
- lkb->lock.id,
- dlm_mode_str(lkb->lock.grmode),
- dlm_mode_str(lkb->lock.rqmode),
- lkb->home,
- lkb->lock.ownpid,
- lkb->rsb->name);
- }
-
- if (!tr->waitfor_count)
- return;
-
- log_group(ls, "waitfor:");
-
- for (i = 0; i < tr->waitfor_alloc; i++) {
- if (!tr->waitfor[i])
- continue;
- wf = tr->waitfor[i];
- log_group(ls, " xid %llx", (unsigned long long)wf->xid);
- }
-}
-
-static void dump_all_trans(struct lockspace *ls)
-{
- struct trans *tr;
-
- log_group(ls, "Transaction dump:");
-
- list_for_each_entry(tr, &ls->transactions, list)
- dump_trans(ls, tr);
-}
-
-static void find_deadlock(struct lockspace *ls)
-{
- if (list_empty(&ls->resources)) {
- log_group(ls, "no deadlock: no resources");
- goto out;
- }
-
- if (!list_empty(&ls->transactions)) {
- log_group(ls, "transactions list should be empty");
- goto out;
- }
-
- dump_resources(ls);
- create_trans_list(ls);
- create_waitfor_graph(ls);
- dump_all_trans(ls);
- reduce_waitfor_graph_loop(ls);
-
- if (list_empty(&ls->transactions)) {
- log_group(ls, "no deadlock: all transactions reduced");
- goto out;
- }
-
- log_group(ls, "found deadlock");
- dump_all_trans(ls);
-
- cancel_trans(ls);
- reduce_waitfor_graph_loop(ls);
-
- if (list_empty(&ls->transactions)) {
- log_group(ls, "resolved deadlock with cancel");
- goto out;
- }
-
- log_error("deadlock resolution failed");
- dump_all_trans(ls);
- out:
- send_cycle_end(ls);
-}
-
diff --git a/group/dlm_controld/dlm_controld.h b/group/dlm_controld/dlm_controld.h
deleted file mode 100644
index 73e4ecc..0000000
--- a/group/dlm_controld/dlm_controld.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef __DLM_CONTROLD_DOT_H__
-#define __DLM_CONTROLD_DOT_H__
-
-/* This defines the interface between dlm_controld and libdlmcontrol, and
- should only be used by libdlmcontrol. */
-
-#define DLMC_SOCK_PATH "dlmc_sock"
-#define DLMC_QUERY_SOCK_PATH "dlmc_query_sock"
-
-#define DLMC_MAGIC 0xD13CD13C
-#define DLMC_VERSION 0x00010001
-
-#define DLMC_CMD_DUMP_DEBUG 1
-#define DLMC_CMD_DUMP_PLOCKS 2
-#define DLMC_CMD_LOCKSPACE_INFO 3
-#define DLMC_CMD_NODE_INFO 4
-#define DLMC_CMD_LOCKSPACES 5
-#define DLMC_CMD_LOCKSPACE_NODES 6
-#define DLMC_CMD_FS_REGISTER 7
-#define DLMC_CMD_FS_UNREGISTER 8
-#define DLMC_CMD_FS_NOTIFIED 9
-#define DLMC_CMD_DEADLOCK_CHECK 10
-#define DLMC_CMD_DUMP_LOG_PLOCK 11
-
-struct dlmc_header {
- unsigned int magic;
- unsigned int version;
- unsigned int command;
- unsigned int option;
- unsigned int len;
- int data; /* embedded command-specific data, for convenience */
- int unused1;
- int unsued2;
- char name[DLM_LOCKSPACE_LEN]; /* no terminating null space */
-};
-
-#endif
-
diff --git a/group/dlm_controld/dlm_daemon.h b/group/dlm_controld/dlm_daemon.h
deleted file mode 100644
index 6f7711a..0000000
--- a/group/dlm_controld/dlm_daemon.h
+++ /dev/null
@@ -1,391 +0,0 @@
-#ifndef __DLM_DAEMON_DOT_H__
-#define __DLM_DAEMON_DOT_H__
-
-#include <sys/types.h>
-#include <asm/types.h>
-#include <sys/uio.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <sys/poll.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <unistd.h>
-#include <time.h>
-#include <syslog.h>
-#include <sched.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <dirent.h>
-#include <openais/saAis.h>
-#include <openais/saCkpt.h>
-
-#include <corosync/cpg.h>
-#include <liblogthread.h>
-
-#include <linux/dlmconstants.h>
-#include "libdlmcontrol.h"
-#include "dlm_controld.h"
-#include "list.h"
-#include "linux_endian.h"
-
-/* DLM_LOCKSPACE_LEN: maximum lockspace name length, from linux/dlmconstants.h.
- Copied in libdlm.h so apps don't need to include the kernel header.
- The libcpg limit is larger at CPG_MAX_NAME_LENGTH 128. Our cpg name includes
- a "dlm:" prefix before the lockspace name. */
-
-/* Maximum members of a ls, should match CPG_MEMBERS_MAX in corosync/cpg.h.
- There are no max defines in dlm-kernel for lockspace members. */
-
-#define MAX_NODES 128
-
-/* Maximum number of IP addresses per node, when using SCTP and multi-ring in
- corosync In dlm-kernel this is DLM_MAX_ADDR_COUNT, currently 3. */
-
-#define MAX_NODE_ADDRESSES 4
-
-/* Max string length printed on a line, for debugging/dump output. */
-
-#define MAXLINE 256
-
-/* group_mode */
-
-#define GROUP_LIBGROUP 2
-#define GROUP_LIBCPG 3
-
-/* cfgk_protocol */
-
-#define PROTO_TCP 0
-#define PROTO_SCTP 1
-#define PROTO_DETECT 2
-
-extern int daemon_debug_opt;
-extern int daemon_quit;
-extern int cluster_down;
-extern int poll_fencing;
-extern int poll_quorum;
-extern int poll_fs;
-extern int poll_ignore_plock;
-extern int poll_drop_plock;
-extern int plock_fd;
-extern int plock_ci;
-extern struct list_head lockspaces;
-extern int cluster_quorate;
-extern int our_nodeid;
-extern char plock_dump_buf[DLMC_DUMP_SIZE];
-extern int plock_dump_len;
-extern int group_mode;
-extern uint32_t control_minor;
-extern uint32_t monitor_minor;
-extern uint32_t plock_minor;
-extern uint32_t old_plock_minor;
-
-/* circular buffer of log_debug and log_error messages */
-extern char daemon_debug_buf[256];
-extern char dump_buf[DLMC_DUMP_SIZE];
-extern int dump_point;
-extern int dump_wrap;
-
-/* circular buffer of log_plock messages */
-extern char log_plock_line[256];
-extern char log_plock_buf[DLMC_DUMP_SIZE];
-extern int log_plock_point;
-extern int log_plock_wrap;
-
-void daemon_dump_save(void);
-void log_plock_save(void);
-
-#define log_level(lvl, fmt, args...) \
-do { \
- snprintf(daemon_debug_buf, 255, "%ld " fmt "\n", time(NULL), ##args); \
- daemon_dump_save(); \
- logt_print(lvl, fmt "\n", ##args); \
- if (daemon_debug_opt) \
- fprintf(stderr, "%s", daemon_debug_buf); \
-} while (0)
-
-#define log_debug(fmt, args...) log_level(LOG_DEBUG, fmt, ##args)
-#define log_error(fmt, args...) log_level(LOG_ERR, fmt, ##args)
-
-#define log_group(ls, fmt, args...) \
-do { \
- snprintf(daemon_debug_buf, 255, "%ld %s " fmt "\n", time(NULL), \
- (ls)->name, ##args); \
- daemon_dump_save(); \
- logt_print(LOG_DEBUG, "%s " fmt "\n", (ls)->name, ##args); \
- if (daemon_debug_opt) \
- fprintf(stderr, "%s", daemon_debug_buf); \
-} while (0)
-
-#define log_plock(ls, fmt, args...) \
-do { \
- snprintf(log_plock_line, 255, "%ld %s " fmt "\n", time(NULL), \
- (ls)->name, ##args); \
- log_plock_save(); \
- if (daemon_debug_opt && cfgd_plock_debug) \
- fprintf(stderr, "%s", log_plock_line); \
-} while (0)
-
-#define log_plock_error(ls, fmt, args...) \
-do { \
- log_level(LOG_ERR, fmt, ##args); \
- snprintf(log_plock_line, 255, "%ld %s " fmt "\n", time(NULL), \
- (ls)->name, ##args); \
- log_plock_save(); \
-} while (0)
-
-/* dlm_header types */
-enum {
- DLM_MSG_PROTOCOL = 1,
- DLM_MSG_START,
- DLM_MSG_PLOCK,
- DLM_MSG_PLOCK_OWN,
- DLM_MSG_PLOCK_DROP,
- DLM_MSG_PLOCK_SYNC_LOCK,
- DLM_MSG_PLOCK_SYNC_WAITER,
- DLM_MSG_PLOCKS_STORED,
- DLM_MSG_DEADLK_CYCLE_START,
- DLM_MSG_DEADLK_CYCLE_END,
- DLM_MSG_DEADLK_CHECKPOINT_READY,
- DLM_MSG_DEADLK_CANCEL_LOCK
-};
-
-/* dlm_header flags */
-#define DLM_MFLG_JOINING 1 /* accompanies start, we are joining */
-#define DLM_MFLG_HAVEPLOCK 2 /* accompanies start, we have plock state */
-#define DLM_MFLG_NACK 4 /* accompanies start, prevent wrong match when
- two outstanding changes are the same */
-#define DLM_MFLG_PLOCK_SIG 8 /* msgdata2 is a plock signature */
-
-struct dlm_header {
- uint16_t version[3];
- uint16_t type; /* DLM_MSG_ */
- uint32_t nodeid; /* sender */
- uint32_t to_nodeid; /* recipient, 0 for all */
- uint32_t global_id; /* global unique id for this lockspace */
- uint32_t flags; /* DLM_MFLG_ */
- uint32_t msgdata; /* in-header payload depends on MSG type; lkid
- for deadlock, seq for lockspace membership */
- uint32_t msgdata2; /* second MSG-specific data */
- uint64_t pad;
-};
-
-struct lockspace {
- struct list_head list;
- char name[DLM_LOCKSPACE_LEN+1];
- uint32_t global_id;
-
- /* lockspace membership stuff */
-
- cpg_handle_t cpg_handle;
- int cpg_client;
- int cpg_fd;
- int joining;
- int leaving;
- int kernel_stopped;
- int fs_registered;
- uint32_t change_seq;
- uint32_t started_count;
- struct change *started_change;
- struct list_head changes;
- struct list_head node_history;
-
- /* plock stuff */
-
- int plock_ckpt_node;
- int need_plocks;
- int save_plocks;
- int disable_plock;
- uint32_t associated_mg_id;
- struct list_head saved_messages;
- struct list_head plock_resources;
- time_t last_checkpoint_time;
- time_t last_plock_time;
- struct timeval drop_resources_last;
- uint64_t plock_ckpt_handle;
- uint64_t checkpoint_r_num_first;
- uint64_t checkpoint_r_num_last;
- uint32_t checkpoint_r_count;
- uint32_t checkpoint_p_count;
- uint32_t last_plock_sig;
-
- /* save copy of groupd member callback data for queries */
-
- int cb_member_count;
- int cb_members[MAX_NODES];
-
- /* deadlock stuff */
-
- int deadlk_low_nodeid;
- struct list_head deadlk_nodes;
- uint64_t deadlk_ckpt_handle;
- int deadlk_confchg_init;
- struct list_head transactions;
- struct list_head resources;
- struct timeval cycle_start_time;
- struct timeval cycle_end_time;
- struct timeval last_send_cycle_start;
- int cycle_running;
- int all_checkpoints_ready;
-};
-
-/* action.c */
-void set_associated_id(uint32_t mg_id);
-int set_sysfs_control(char *name, int val);
-int set_sysfs_event_done(char *name, int val);
-int set_sysfs_id(char *name, uint32_t id);
-int set_configfs_members(char *name, int new_count, int *new_members,
- int renew_count, int *renew_members);
-int add_configfs_node(int nodeid, char *addr, int addrlen, int local);
-void del_configfs_node(int nodeid);
-void clear_configfs(void);
-int setup_configfs(void);
-int check_uncontrolled_lockspaces(void);
-int setup_misc_devices(void);
-
-/* config.c */
-int setup_ccs(void);
-void close_ccs(void);
-void read_ccs_name(const char *path, char *name);
-void read_ccs_yesno(const char *path, int *yes, int *no);
-int read_ccs_int(const char *path, int *config_val);
-int get_weight(int nodeid, char *lockspace);
-
-/* cpg.c */
-int setup_cpg_daemon(void);
-void close_cpg_daemon(void);
-void process_cpg_daemon(int ci);
-int set_protocol(void);
-void process_lockspace_changes(void);
-void dlm_send_message(struct lockspace *ls, char *buf, int len);
-int dlm_join_lockspace(struct lockspace *ls);
-int dlm_leave_lockspace(struct lockspace *ls);
-const char *msg_name(int type);
-void update_flow_control_status(void);
-void node_history_cluster_add(int nodeid);
-void node_history_cluster_remove(int nodeid);
-int set_node_info(struct lockspace *ls, int nodeid, struct dlmc_node *node);
-int set_lockspace_info(struct lockspace *ls, struct dlmc_lockspace *lockspace);
-int set_lockspaces(int *count, struct dlmc_lockspace **lss_out);
-int set_lockspace_nodes(struct lockspace *ls, int option, int *node_count,
- struct dlmc_node **nodes_out);
-int set_fs_notified(struct lockspace *ls, int nodeid);
-
-/* deadlock.c */
-void setup_deadlock(void);
-void send_cycle_start(struct lockspace *ls);
-void receive_checkpoint_ready(struct lockspace *ls, struct dlm_header *hd,
- int len);
-void receive_cycle_start(struct lockspace *ls, struct dlm_header *hd, int len);
-void receive_cycle_end(struct lockspace *ls, struct dlm_header *hd, int len);
-void receive_cancel_lock(struct lockspace *ls, struct dlm_header *hd, int len);
-void deadlk_confchg(struct lockspace *ls,
- const struct cpg_address *member_list,
- size_t member_list_entries,
- const struct cpg_address *left_list,
- size_t left_list_entries,
- const struct cpg_address *joined_list,
- size_t joined_list_entries);
-
-/* main.c */
-int do_read(int fd, void *buf, size_t count);
-int do_write(int fd, void *buf, size_t count);
-void client_dead(int ci);
-int client_add(int fd, void (*workfn)(int ci), void (*deadfn)(int ci));
-int client_fd(int ci);
-void client_ignore(int ci, int fd);
-void client_back(int ci, int fd);
-struct lockspace *find_ls(char *name);
-struct lockspace *find_ls_id(uint32_t id);
-const char *dlm_mode_str(int mode);
-void cluster_dead(int ci);
-
-/* member_cman.c */
-int setup_cluster(void);
-void close_cluster(void);
-void process_cluster(int ci);
-void update_cluster(void);
-int is_cluster_member(int nodeid);
-char *nodeid2name(int nodeid);
-void kick_node_from_cluster(int nodeid);
-int fence_node_time(int nodeid, uint64_t *last_fenced_time);
-int fence_in_progress(int *count);
-
-/* netlink.c */
-int setup_netlink(void);
-void process_netlink(int ci);
-
-/* plock.c */
-int setup_plocks(void);
-void close_plocks(void);
-void process_plocks(int ci);
-void drop_resources_all(void);
-int limit_plocks(void);
-void receive_plock(struct lockspace *ls, struct dlm_header *hd, int len);
-void receive_own(struct lockspace *ls, struct dlm_header *hd, int len);
-void receive_sync(struct lockspace *ls, struct dlm_header *hd, int len);
-void receive_drop(struct lockspace *ls, struct dlm_header *hd, int len);
-void process_saved_plocks(struct lockspace *ls);
-void close_plock_checkpoint(struct lockspace *ls);
-void store_plocks(struct lockspace *ls, uint32_t *sig);
-void retrieve_plocks(struct lockspace *ls, uint32_t *sig);
-void purge_plocks(struct lockspace *ls, int nodeid, int unmount);
-int fill_plock_dump_buf(struct lockspace *ls);
-
-/* group.c */
-#define BUILD_GROUPD_COMPAT
-#ifdef BUILD_GROUPD_COMPAT
-int setup_groupd(void);
-void close_groupd(void);
-void process_groupd(int ci);
-int dlm_join_lockspace_group(struct lockspace *ls);
-int dlm_leave_lockspace_group(struct lockspace *ls);
-int set_node_info_group(struct lockspace *ls, int nodeid,
- struct dlmc_node *node);
-int set_lockspace_info_group(struct lockspace *ls,
- struct dlmc_lockspace *lockspace);
-int set_lockspaces_group(int *count,
- struct dlmc_lockspace **lss_out);
-int set_lockspace_nodes_group(struct lockspace *ls, int option,
- int *node_count, struct dlmc_node **nodes);
-int set_group_mode(void);
-#else
-static inline int setup_groupd(void) { return -1; }
-static inline void close_groupd(void) { }
-static inline void process_groupd(int ci) { }
-static inline int dlm_join_lockspace_group(struct lockspace *ls) { return -1; }
-static inline int dlm_leave_lockspace_group(struct lockspace *ls) { return -1; }
-static inline int set_node_info_group(struct lockspace *ls, int nodeid,
- struct dlmc_node *node) { return -1; }
-static inline int set_lockspace_info_group(struct lockspace *ls,
- struct dlmc_lockspace *lockspace) { return -1; }
-static inline int set_lockspaces_group(int *count,
- struct dlmc_lockspace **lss_out) { return -1; }
-static inline int set_lockspace_nodes_group(struct lockspace *ls, int option,
- int *node_count, struct dlmc_node **nodes) { return -1; }
-int inline void set_group_mode(void) { return 0; }
-#endif
-
-/* logging.c */
-void init_logging(void);
-void setup_logging(void);
-void close_logging(void);
-
-/* crc.c */
-uint32_t cpgname_to_crc(const char *data, int len);
-
-#endif
-
diff --git a/group/dlm_controld/group.c b/group/dlm_controld/group.c
deleted file mode 100644
index a5e2898..0000000
--- a/group/dlm_controld/group.c
+++ /dev/null
@@ -1,376 +0,0 @@
-#include "dlm_daemon.h"
-#include "config.h"
-#include "libgroup.h"
-
-#define DO_STOP 1
-#define DO_START 2
-#define DO_FINISH 3
-#define DO_TERMINATE 4
-#define DO_SETID 5
-
-#define GROUPD_TIMEOUT 10 /* seconds */
-
-/* save all the params from callback functions here because we can't
- do the processing within the callback function itself */
-
-group_handle_t gh;
-static int cb_action;
-static char cb_name[DLM_LOCKSPACE_LEN+1];
-static int cb_event_nr;
-static unsigned int cb_id;
-static int cb_type;
-static int cb_member_count;
-static int cb_members[MAX_NODES];
-
-
-static void stop_cbfn(group_handle_t h, void *private, char *name)
-{
- cb_action = DO_STOP;
- strcpy(cb_name, name);
-}
-
-static void start_cbfn(group_handle_t h, void *private, char *name,
- int event_nr, int type, int member_count, int *members)
-{
- int i;
-
- cb_action = DO_START;
- strcpy(cb_name, name);
- cb_event_nr = event_nr;
- cb_type = type;
- cb_member_count = member_count;
-
- for (i = 0; i < member_count; i++)
- cb_members[i] = members[i];
-}
-
-static void finish_cbfn(group_handle_t h, void *private, char *name,
- int event_nr)
-{
- cb_action = DO_FINISH;
- strcpy(cb_name, name);
- cb_event_nr = event_nr;
-}
-
-static void terminate_cbfn(group_handle_t h, void *private, char *name)
-{
- cb_action = DO_TERMINATE;
- strcpy(cb_name, name);
-}
-
-static void setid_cbfn(group_handle_t h, void *private, char *name,
- unsigned int id)
-{
- cb_action = DO_SETID;
- strcpy(cb_name, name);
- cb_id = id;
-}
-
-group_callbacks_t callbacks = {
- stop_cbfn,
- start_cbfn,
- finish_cbfn,
- terminate_cbfn,
- setid_cbfn
-};
-
-static char *str_members(void)
-{
- static char str_members_buf[MAXLINE];
- int i, ret, pos = 0, len = MAXLINE;
-
- memset(str_members_buf, 0, MAXLINE);
-
- for (i = 0; i < cb_member_count; i++) {
- if (i != 0) {
- ret = snprintf(str_members_buf + pos, len - pos, " ");
- if (ret >= len - pos)
- break;
- pos += ret;
- }
- ret = snprintf(str_members_buf + pos, len - pos, "%d",
- cb_members[i]);
- if (ret >= len - pos)
- break;
- pos += ret;
- }
- return str_members_buf;
-}
-
-static unsigned int replace_zero_global_id(char *name)
-{
- unsigned int new_id;
-
- new_id = cpgname_to_crc(name, strlen(name));
-
- log_error("replace zero id for %s with %u", name, new_id);
- return new_id;
-}
-
-void process_groupd(int ci)
-{
- struct lockspace *ls;
- int error = 0, val;
-
- group_dispatch(gh);
-
- if (!cb_action)
- goto out;
-
- ls = find_ls(cb_name);
- if (!ls) {
- log_error("callback %d group %s not found", cb_action, cb_name);
- error = -1;
- goto out;
- }
-
- switch (cb_action) {
- case DO_STOP:
- log_debug("groupd callback: stop %s", cb_name);
- ls->kernel_stopped = 1; /* for queries */
- set_sysfs_control(cb_name, 0);
- group_stop_done(gh, cb_name);
- break;
-
- case DO_START:
- log_debug("groupd callback: start %s count %d members %s",
- cb_name, cb_member_count, str_members());
-
- /* save in ls for queries */
- ls->cb_member_count = cb_member_count;
- memcpy(ls->cb_members, cb_members, sizeof(cb_members));
-
- set_configfs_members(cb_name, cb_member_count, cb_members,
- 0, NULL);
-
- /* this causes the dlm to do a "start" using the
- members we just set */
-
- ls->kernel_stopped = 0;
- set_sysfs_control(cb_name, 1);
-
- /* the dlm doesn't need/use a "finish" stage following
- start, so we can just do start_done immediately */
-
- group_start_done(gh, cb_name, cb_event_nr);
-
- if (!ls->joining)
- break;
-
- ls->joining = 0;
- log_debug("join event done %s", cb_name);
-
- /* this causes the dlm_new_lockspace() call (typically from
- mount) to complete */
- set_sysfs_event_done(cb_name, 0);
-
- break;
-
- case DO_SETID:
- log_debug("groupd callback: set_id %s %x", cb_name, cb_id);
- if (!cb_id)
- cb_id = replace_zero_global_id(cb_name);
- set_sysfs_id(cb_name, cb_id);
- ls->global_id = cb_id;
- break;
-
- case DO_TERMINATE:
- log_debug("groupd callback: terminate %s", cb_name);
-
- if (ls->joining) {
- val = -1;
- ls->joining = 0;
- log_debug("join event failed %s", cb_name);
- } else {
- val = 0;
- log_debug("leave event done %s", cb_name);
-
- /* remove everything under configfs */
- set_configfs_members(ls->name, 0, NULL, 0, NULL);
- }
-
- set_sysfs_event_done(cb_name, val);
- list_del(&ls->list);
- free(ls);
- break;
-
- case DO_FINISH:
- log_debug("groupd callback: finish %s (unused)", cb_name);
- break;
-
- default:
- error = -EINVAL;
- }
-
- cb_action = 0;
- out:
- return;
-}
-
-int dlm_join_lockspace_group(struct lockspace *ls)
-{
- int rv;
-
- ls->joining = 1;
- list_add(&ls->list, &lockspaces);
-
- rv = group_join(gh, ls->name);
- if (rv) {
- list_del(&ls->list);
- free(ls);
- }
-
- return rv;
-}
-
-int dlm_leave_lockspace_group(struct lockspace *ls)
-{
- ls->leaving = 1;
- group_leave(gh, ls->name);
- return 0;
-}
-
-int setup_groupd(void)
-{
- int rv;
-
- gh = group_init(NULL, "dlm", 1, &callbacks, GROUPD_TIMEOUT);
- if (!gh) {
- log_error("group_init error %p %d", gh, errno);
- return -ENOTCONN;
- }
-
- rv = group_get_fd(gh);
- if (rv < 0)
- log_error("group_get_fd error %d %d", rv, errno);
-
- return rv;
-}
-
-void close_groupd(void)
-{
- group_exit(gh);
-}
-
-/* most of the query info doesn't apply in the LIBGROUP mode, but we can
- emulate some basic parts of it */
-
-int set_lockspace_info_group(struct lockspace *ls,
- struct dlmc_lockspace *lockspace)
-{
- strncpy(lockspace->name, ls->name, DLM_LOCKSPACE_LEN);
- lockspace->global_id = ls->global_id;
-
- if (ls->joining)
- lockspace->flags |= DLMC_LF_JOINING;
- if (ls->leaving)
- lockspace->flags |= DLMC_LF_LEAVING;
- if (ls->kernel_stopped)
- lockspace->flags |= DLMC_LF_KERNEL_STOPPED;
-
- lockspace->cg_prev.member_count = ls->cb_member_count;
-
- /* we could save the previous cb_members and calculate
- joined_count and remove_count */
-
- return 0;
-}
-
-int set_node_info_group(struct lockspace *ls, int nodeid,
- struct dlmc_node *node)
-{
- node->nodeid = nodeid;
- node->flags = DLMC_NF_MEMBER;
- return 0;
-}
-
-int set_lockspaces_group(int *count, struct dlmc_lockspace **lss_out)
-{
- struct lockspace *ls;
- struct dlmc_lockspace *lss, *lsp;
- int ls_count = 0;
-
- list_for_each_entry(ls, &lockspaces, list)
- ls_count++;
-
- lss = malloc(ls_count * sizeof(struct dlmc_lockspace));
- if (!lss)
- return -ENOMEM;
- memset(lss, 0, ls_count * sizeof(struct dlmc_lockspace));
-
- lsp = lss;
- list_for_each_entry(ls, &lockspaces, list) {
- set_lockspace_info(ls, lsp++);
- }
-
- *count = ls_count;
- *lss_out = lss;
- return 0;
-}
-
-int set_lockspace_nodes_group(struct lockspace *ls, int option, int *node_count,
- struct dlmc_node **nodes_out)
-{
- struct dlmc_node *nodes = NULL, *nodep;
- int i, len;
-
- if (!ls->cb_member_count)
- goto out;
-
- len = ls->cb_member_count * sizeof(struct dlmc_node);
- nodes = malloc(len);
- if (!nodes)
- return -ENOMEM;
- memset(nodes, 0, len);
-
- nodep = nodes;
- for (i = 0; i < ls->cb_member_count; i++) {
- set_node_info_group(ls, ls->cb_members[i], nodep++);
- }
- out:
- *node_count = ls->cb_member_count;
- *nodes_out = nodes;
- return 0;
-}
-
-int set_group_mode(void)
-{
- int i = 0, rv, version, limit;
-
- while (1) {
- rv = group_get_version(&version);
-
- if (rv || version < 0) {
- /* we expect to get version of -EAGAIN while groupd
- is detecting the mode of everyone; don't retry
- as long if we're not getting anything back from
- groupd */
-
- log_debug("set_group_mode get_version %d ver %d",
- rv, version);
-
- limit = (version == -EAGAIN) ? 30 : 5;
-
- if (i++ > limit) {
- log_error("cannot get groupd compatibility "
- "mode rv %d ver %d", rv, version);
- return -1;
- }
- sleep(1);
- continue;
- }
-
-
- if (version == GROUP_LIBGROUP) {
- group_mode = GROUP_LIBGROUP;
- return 0;
- } else if (version == GROUP_LIBCPG) {
- group_mode = GROUP_LIBCPG;
- return 0;
- } else {
- log_error("set_group_mode invalid ver %d", version);
- return -1;
- }
- }
-}
-
diff --git a/group/dlm_controld/logging.c b/group/dlm_controld/logging.c
deleted file mode 100644
index cfcacb0..0000000
--- a/group/dlm_controld/logging.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "dlm_daemon.h"
-#include "config.h"
-#include "ccs.h"
-
-extern int ccs_handle;
-
-#define DAEMON_NAME "dlm_controld"
-#define DEFAULT_LOG_MODE LOG_MODE_OUTPUT_FILE|LOG_MODE_OUTPUT_SYSLOG
-#define DEFAULT_SYSLOG_FACILITY SYSLOGFACILITY
-#define DEFAULT_SYSLOG_PRIORITY SYSLOGLEVEL
-#define DEFAULT_LOGFILE_PRIORITY LOG_INFO /* ? */
-#define DEFAULT_LOGFILE LOGDIR "/" DAEMON_NAME ".log"
-
-static int log_mode;
-static int syslog_facility;
-static int syslog_priority;
-static int logfile_priority;
-static char logfile[PATH_MAX];
-
-void init_logging(void)
-{
- log_mode = DEFAULT_LOG_MODE;
- syslog_facility = DEFAULT_SYSLOG_FACILITY;
- syslog_priority = DEFAULT_SYSLOG_PRIORITY;
- logfile_priority = DEFAULT_LOGFILE_PRIORITY;
- strcpy(logfile, DEFAULT_LOGFILE);
-
- /* logfile_priority is the only one of these options that
- can be controlled from command line or environment variable */
-
- if (cfgd_debug_logfile)
- logfile_priority = LOG_DEBUG;
-
- log_debug("logging mode %d syslog f %d p %d logfile p %d %s",
- log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-
- logt_init(DAEMON_NAME, log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-}
-
-void setup_logging(void)
-{
- ccs_read_logging(ccs_handle, DAEMON_NAME,
- &cfgd_debug_logfile, &log_mode,
- &syslog_facility, &syslog_priority,
- &logfile_priority, logfile);
-
- log_debug("logging mode %d syslog f %d p %d logfile p %d %s",
- log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-
- logt_conf(DAEMON_NAME, log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-}
-
-void close_logging(void)
-{
- logt_exit();
-}
-
diff --git a/group/dlm_controld/main.c b/group/dlm_controld/main.c
deleted file mode 100644
index 1766537..0000000
--- a/group/dlm_controld/main.c
+++ /dev/null
@@ -1,1429 +0,0 @@
-#include "dlm_daemon.h"
-#include "config.h"
-#include <pthread.h>
-#include "copyright.cf"
-
-#include <linux/dlmconstants.h>
-#include <linux/netlink.h>
-#include <linux/genetlink.h>
-#include <linux/dlm_netlink.h>
-
-#define LOCKFILE_NAME "/var/run/dlm_controld.pid"
-#define CLIENT_NALLOC 32
-
-static int client_maxi;
-static int client_size = 0;
-static struct client *client = NULL;
-static struct pollfd *pollfd = NULL;
-static pthread_t query_thread;
-static pthread_mutex_t query_mutex;
-static struct list_head fs_register_list;
-static int kernel_monitor_fd;
-static int daemon_ready;
-
-struct client {
- int fd;
- void *workfn;
- void *deadfn;
- struct lockspace *ls;
-};
-
-int do_read(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- while (off < count) {
- rv = read(fd, (char *)buf + off, count - off);
- if (rv == 0)
- return -1;
- if (rv == -1 && errno == EINTR)
- continue;
- if (rv == -1)
- return -1;
- off += rv;
- }
- return 0;
-}
-
-int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, (char *)buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0) {
- log_error("write errno %d", errno);
- return rv;
- }
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-static void client_alloc(void)
-{
- int i;
-
- if (!client) {
- client = malloc(CLIENT_NALLOC * sizeof(struct client));
- pollfd = malloc(CLIENT_NALLOC * sizeof(struct pollfd));
- } else {
- client = realloc(client, (client_size + CLIENT_NALLOC) *
- sizeof(struct client));
- pollfd = realloc(pollfd, (client_size + CLIENT_NALLOC) *
- sizeof(struct pollfd));
- if (!pollfd)
- log_error("can't alloc for pollfd");
- }
- if (!client || !pollfd)
- log_error("can't alloc for client array");
-
- for (i = client_size; i < client_size + CLIENT_NALLOC; i++) {
- client[i].workfn = NULL;
- client[i].deadfn = NULL;
- client[i].fd = -1;
- pollfd[i].fd = -1;
- pollfd[i].revents = 0;
- }
- client_size += CLIENT_NALLOC;
-}
-
-void client_dead(int ci)
-{
- close(client[ci].fd);
- client[ci].workfn = NULL;
- client[ci].fd = -1;
- pollfd[ci].fd = -1;
-}
-
-int client_add(int fd, void (*workfn)(int ci), void (*deadfn)(int ci))
-{
- int i;
-
- if (!client)
- client_alloc();
- again:
- for (i = 0; i < client_size; i++) {
- if (client[i].fd == -1) {
- client[i].workfn = workfn;
- if (deadfn)
- client[i].deadfn = deadfn;
- else
- client[i].deadfn = client_dead;
- client[i].fd = fd;
- pollfd[i].fd = fd;
- pollfd[i].events = POLLIN;
- if (i > client_maxi)
- client_maxi = i;
- return i;
- }
- }
-
- client_alloc();
- goto again;
-}
-
-int client_fd(int ci)
-{
- return client[ci].fd;
-}
-
-void client_ignore(int ci, int fd)
-{
- pollfd[ci].fd = -1;
- pollfd[ci].events = 0;
-}
-
-void client_back(int ci, int fd)
-{
- pollfd[ci].fd = fd;
- pollfd[ci].events = POLLIN;
-}
-
-static void sigterm_handler(int sig)
-{
- daemon_quit = 1;
-}
-
-static struct lockspace *create_ls(char *name)
-{
- struct lockspace *ls;
-
- ls = malloc(sizeof(*ls));
- if (!ls)
- goto out;
- memset(ls, 0, sizeof(struct lockspace));
- strncpy(ls->name, name, DLM_LOCKSPACE_LEN);
-
- INIT_LIST_HEAD(&ls->changes);
- INIT_LIST_HEAD(&ls->node_history);
- INIT_LIST_HEAD(&ls->saved_messages);
- INIT_LIST_HEAD(&ls->plock_resources);
- INIT_LIST_HEAD(&ls->deadlk_nodes);
- INIT_LIST_HEAD(&ls->transactions);
- INIT_LIST_HEAD(&ls->resources);
- out:
- return ls;
-}
-
-struct lockspace *find_ls(char *name)
-{
- struct lockspace *ls;
-
- list_for_each_entry(ls, &lockspaces, list) {
- if ((strlen(ls->name) == strlen(name)) &&
- !strncmp(ls->name, name, strlen(name)))
- return ls;
- }
- return NULL;
-}
-
-struct lockspace *find_ls_id(uint32_t id)
-{
- struct lockspace *ls;
-
- list_for_each_entry(ls, &lockspaces, list) {
- if (ls->global_id == id)
- return ls;
- }
- return NULL;
-}
-
-struct fs_reg {
- struct list_head list;
- char name[DLM_LOCKSPACE_LEN+1];
-};
-
-static int fs_register_check(char *name)
-{
- struct fs_reg *fs;
- list_for_each_entry(fs, &fs_register_list, list) {
- if (!strcmp(name, fs->name))
- return 1;
- }
- return 0;
-}
-
-static int fs_register_add(char *name)
-{
- struct fs_reg *fs;
-
- if (fs_register_check(name))
- return -EALREADY;
-
- fs = malloc(sizeof(struct fs_reg));
- if (!fs)
- return -ENOMEM;
- strncpy(fs->name, name, DLM_LOCKSPACE_LEN);
- list_add(&fs->list, &fs_register_list);
- return 0;
-}
-
-static void fs_register_del(char *name)
-{
- struct fs_reg *fs;
- list_for_each_entry(fs, &fs_register_list, list) {
- if (!strcmp(name, fs->name)) {
- list_del(&fs->list);
- free(fs);
- return;
- }
- }
-}
-
-#define MAXARGS 8
-
-static char *get_args(char *buf, int *argc, char **argv, char sep, int want)
-{
- char *p = buf, *rp = NULL;
- int i;
-
- argv[0] = p;
-
- for (i = 1; i < MAXARGS; i++) {
- p = strchr(buf, sep);
- if (!p)
- break;
- *p = '\0';
-
- if (want == i) {
- rp = p + 1;
- break;
- }
-
- argv[i] = p + 1;
- buf = p + 1;
- }
- *argc = i;
-
- /* we ended by hitting \0, return the point following that */
- if (!rp)
- rp = strchr(buf, '\0') + 1;
-
- return rp;
-}
-
-const char *dlm_mode_str(int mode)
-{
- switch (mode) {
- case DLM_LOCK_IV:
- return "IV";
- case DLM_LOCK_NL:
- return "NL";
- case DLM_LOCK_CR:
- return "CR";
- case DLM_LOCK_CW:
- return "CW";
- case DLM_LOCK_PR:
- return "PR";
- case DLM_LOCK_PW:
- return "PW";
- case DLM_LOCK_EX:
- return "EX";
- }
- return "??";
-}
-
-/* recv "online" (join) and "offline" (leave)
- messages from dlm via uevents and pass them on to groupd */
-
-static void process_uevent(int ci)
-{
- struct lockspace *ls;
- char buf[MAXLINE];
- char *argv[MAXARGS], *act, *sys;
- int rv, argc = 0;
-
- memset(buf, 0, sizeof(buf));
- memset(argv, 0, sizeof(char *) * MAXARGS);
-
- retry_recv:
- rv = recv(client[ci].fd, &buf, sizeof(buf), 0);
- if (rv < 0) {
- if (errno == EINTR)
- goto retry_recv;
- if (errno != EAGAIN)
- log_error("uevent recv error %d errno %d", rv, errno);
- return;
- }
-
- if (!strstr(buf, "dlm"))
- return;
-
- log_debug("uevent: %s", buf);
-
- get_args(buf, &argc, argv, '/', 4);
- if (argc != 4)
- log_error("uevent message has %d args", argc);
- act = argv[0];
- sys = argv[2];
-
- if ((strlen(sys) != strlen("dlm")) || strcmp(sys, "dlm"))
- return;
-
- log_debug("kernel: %s %s", act, argv[3]);
-
- rv = 0;
-
- if (!strcmp(act, "online@")) {
- ls = find_ls(argv[3]);
- if (ls) {
- rv = -EEXIST;
- goto out;
- }
-
- ls = create_ls(argv[3]);
- if (!ls) {
- rv = -ENOMEM;
- goto out;
- }
-
- if (fs_register_check(ls->name))
- ls->fs_registered = 1;
-
- if (group_mode == GROUP_LIBGROUP)
- rv = dlm_join_lockspace_group(ls);
- else
- rv = dlm_join_lockspace(ls);
- if (rv) {
- /* ls already freed */
- goto out;
- }
-
- } else if (!strcmp(act, "offline@")) {
- ls = find_ls(argv[3]);
- if (!ls) {
- rv = -ENOENT;
- goto out;
- }
-
- if (group_mode == GROUP_LIBGROUP)
- dlm_leave_lockspace_group(ls);
- else
- dlm_leave_lockspace(ls);
- }
- out:
- if (rv < 0)
- log_error("process_uevent %s error %d errno %d",
- act, rv, errno);
-}
-
-static int setup_uevent(void)
-{
- struct sockaddr_nl snl;
- int s, rv;
-
- s = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
- if (s < 0) {
- log_error("uevent netlink socket");
- return s;
- }
-
- memset(&snl, 0, sizeof(snl));
- snl.nl_family = AF_NETLINK;
- snl.nl_pid = getpid();
- snl.nl_groups = 1;
-
- rv = bind(s, (struct sockaddr *) &snl, sizeof(snl));
- if (rv < 0) {
- log_error("uevent bind error %d errno %d", rv, errno);
- close(s);
- return rv;
- }
-
- return s;
-}
-
-static void init_header(struct dlmc_header *h, int cmd, char *name, int result,
- int extra_len)
-{
- memset(h, 0, sizeof(struct dlmc_header));
-
- h->magic = DLMC_MAGIC;
- h->version = DLMC_VERSION;
- h->len = sizeof(struct dlmc_header) + extra_len;
- h->command = cmd;
- h->data = result;
-
- if (name)
- strncpy(h->name, name, DLM_LOCKSPACE_LEN);
-}
-
-static void query_dump_debug(int fd)
-{
- struct dlmc_header h;
- int extra_len;
- int len;
-
- /* in the case of dump_wrap, extra_len will go in two writes,
- first the log tail, then the log head */
- if (dump_wrap)
- extra_len = DLMC_DUMP_SIZE;
- else
- extra_len = dump_point;
-
- init_header(&h, DLMC_CMD_DUMP_DEBUG, NULL, 0, extra_len);
- do_write(fd, &h, sizeof(h));
-
- if (dump_wrap) {
- len = DLMC_DUMP_SIZE - dump_point;
- do_write(fd, dump_buf + dump_point, len);
- len = dump_point;
- } else
- len = dump_point;
-
- /* NUL terminate the debug string */
- dump_buf[dump_point] = '\0';
-
- do_write(fd, dump_buf, len);
-}
-
-static void query_dump_log_plock(int fd)
-{
- struct dlmc_header h;
- int extra_len;
- int len;
-
- /* in the case of dump_wrap, extra_len will go in two writes,
- first the log tail, then the log head */
- if (log_plock_wrap)
- extra_len = DLMC_DUMP_SIZE;
- else
- extra_len = log_plock_point;
-
- init_header(&h, DLMC_CMD_DUMP_LOG_PLOCK, NULL, 0, extra_len);
- do_write(fd, &h, sizeof(h));
-
- if (log_plock_wrap) {
- len = DLMC_DUMP_SIZE - log_plock_point;
- do_write(fd, log_plock_buf + log_plock_point, len);
- len = log_plock_point;
- } else
- len = log_plock_point;
-
- /* NUL terminate the debug string */
- log_plock_buf[log_plock_point] = '\0';
-
- do_write(fd, log_plock_buf, len);
-}
-
-static void query_dump_plocks(int fd, char *name)
-{
- struct lockspace *ls;
- struct dlmc_header h;
- int rv;
-
- ls = find_ls(name);
- if (!ls) {
- plock_dump_len = 0;
- rv = -ENOENT;
- } else {
- /* writes to plock_dump_buf and sets plock_dump_len */
- rv = fill_plock_dump_buf(ls);
- }
-
- init_header(&h, DLMC_CMD_DUMP_PLOCKS, name, rv, plock_dump_len);
-
- do_write(fd, &h, sizeof(h));
-
- if (plock_dump_len)
- do_write(fd, plock_dump_buf, plock_dump_len);
-}
-
-/* combines a header and the data and sends it back to the client in
- a single do_write() call */
-
-static void do_reply(int fd, int cmd, char *name, int result, int option,
- char *buf, int buflen)
-{
- struct dlmc_header *h;
- char *reply;
- int reply_len;
-
- reply_len = sizeof(struct dlmc_header) + buflen;
- reply = malloc(reply_len);
- if (!reply)
- return;
- memset(reply, 0, reply_len);
- h = (struct dlmc_header *)reply;
-
- init_header(h, cmd, name, result, buflen);
- h->option = option;
-
- if (buf && buflen)
- memcpy(reply + sizeof(struct dlmc_header), buf, buflen);
-
- do_write(fd, reply, reply_len);
-
- free(reply);
-}
-
-static void query_lockspace_info(int fd, char *name)
-{
- struct lockspace *ls;
- struct dlmc_lockspace lockspace;
- int rv;
-
- ls = find_ls(name);
- if (!ls) {
- rv = -ENOENT;
- goto out;
- }
-
- memset(&lockspace, 0, sizeof(lockspace));
- lockspace.group_mode = group_mode;
-
- if (group_mode == GROUP_LIBGROUP)
- rv = set_lockspace_info_group(ls, &lockspace);
- else
- rv = set_lockspace_info(ls, &lockspace);
- out:
- do_reply(fd, DLMC_CMD_LOCKSPACE_INFO, name, rv, 0,
- (char *)&lockspace, sizeof(lockspace));
-}
-
-static void query_node_info(int fd, char *name, int nodeid)
-{
- struct lockspace *ls;
- struct dlmc_node node;
- int rv;
-
- ls = find_ls(name);
- if (!ls) {
- rv = -ENOENT;
- goto out;
- }
-
- memset(&node, 0, sizeof(node));
-
- if (group_mode == GROUP_LIBGROUP)
- rv = set_node_info_group(ls, nodeid, &node);
- else
- rv = set_node_info(ls, nodeid, &node);
- out:
- do_reply(fd, DLMC_CMD_NODE_INFO, name, rv, 0,
- (char *)&node, sizeof(node));
-}
-
-static void query_lockspaces(int fd, int max)
-{
- int ls_count = 0;
- struct dlmc_lockspace *lss = NULL;
- int rv, result;
-
- if (group_mode == GROUP_LIBGROUP)
- rv = set_lockspaces_group(&ls_count, &lss);
- else
- rv = set_lockspaces(&ls_count, &lss);
-
- if (rv < 0) {
- result = rv;
- ls_count = 0;
- goto out;
- }
-
- /* return error if daemon is not even ready to create lockspaces */
- if (!daemon_ready) {
- result = -1;
- goto out;
- }
-
- if (ls_count > max) {
- result = -E2BIG;
- ls_count = max;
- } else {
- result = ls_count;
- }
- out:
- do_reply(fd, DLMC_CMD_LOCKSPACES, NULL, result, 0,
- (char *)lss, ls_count * sizeof(struct dlmc_lockspace));
-
- if (lss)
- free(lss);
-}
-
-static void query_lockspace_nodes(int fd, char *name, int option, int max)
-{
- struct lockspace *ls;
- int node_count = 0;
- struct dlmc_node *nodes = NULL;
- int rv, result;
-
- ls = find_ls(name);
- if (!ls) {
- result = -ENOENT;
- node_count = 0;
- goto out;
- }
-
- if (group_mode == GROUP_LIBGROUP)
- rv = set_lockspace_nodes_group(ls, option, &node_count, &nodes);
- else
- rv = set_lockspace_nodes(ls, option, &node_count, &nodes);
-
- if (rv < 0) {
- result = rv;
- node_count = 0;
- goto out;
- }
-
- /* node_count is the number of structs copied/returned; the caller's
- max may be less than that, in which case we copy as many as they
- asked for and return -E2BIG */
-
- if (node_count > max) {
- result = -E2BIG;
- node_count = max;
- } else {
- result = node_count;
- }
- out:
- do_reply(fd, DLMC_CMD_LOCKSPACE_NODES, name, result, 0,
- (char *)nodes, node_count * sizeof(struct dlmc_node));
-
- if (nodes)
- free(nodes);
-}
-
-static void process_connection(int ci)
-{
- struct dlmc_header h;
- char *extra = NULL;
- int rv, extra_len;
- struct lockspace *ls;
-
- rv = do_read(client[ci].fd, &h, sizeof(h));
- if (rv < 0) {
- log_debug("connection %d read error %d", ci, rv);
- goto out;
- }
-
- if (h.magic != DLMC_MAGIC) {
- log_debug("connection %d magic error %x", ci, h.magic);
- goto out;
- }
-
- if ((h.version & 0xFFFF0000) != (DLMC_VERSION & 0xFFFF0000)) {
- log_debug("connection %d version error %x", ci, h.version);
- goto out;
- }
-
- if (h.len > sizeof(h)) {
- extra_len = h.len - sizeof(h);
- extra = malloc(extra_len);
- if (!extra) {
- log_error("process_connection no mem %d", extra_len);
- goto out;
- }
- memset(extra, 0, extra_len);
-
- rv = do_read(client[ci].fd, extra, extra_len);
- if (rv < 0) {
- log_debug("connection %d extra read error %d", ci, rv);
- goto out;
- }
- }
-
- switch (h.command) {
- case DLMC_CMD_FS_REGISTER:
- if (group_mode == GROUP_LIBGROUP) {
- rv = -EINVAL;
- } else {
- rv = fs_register_add(h.name);
- ls = find_ls(h.name);
- if (ls)
- ls->fs_registered = 1;
- }
- do_reply(client[ci].fd, DLMC_CMD_FS_REGISTER, h.name, rv, 0,
- NULL, 0);
- break;
-
- case DLMC_CMD_FS_UNREGISTER:
- if (group_mode == GROUP_LIBGROUP)
- break;
- fs_register_del(h.name);
- ls = find_ls(h.name);
- if (ls)
- ls->fs_registered = 0;
- break;
-
- case DLMC_CMD_FS_NOTIFIED:
- ls = find_ls(h.name);
- if (ls)
- rv = set_fs_notified(ls, h.data);
- else
- rv = -ENOENT;
- /* pass back the nodeid provided by caller in option field */
- do_reply(client[ci].fd, DLMC_CMD_FS_NOTIFIED, h.name, rv,
- h.data, NULL, 0);
- break;
-
- case DLMC_CMD_DEADLOCK_CHECK:
- ls = find_ls(h.name);
- if (ls)
- send_cycle_start(ls);
- client_dead(ci);
- break;
-
- default:
- log_error("process_connection %d unknown command %d",
- ci, h.command);
- }
- out:
- if (extra)
- free(extra);
-}
-
-static void process_listener(int ci)
-{
- int fd, i;
-
- fd = accept(client[ci].fd, NULL, NULL);
- if (fd < 0) {
- log_error("process_listener: accept error %d %d", fd, errno);
- return;
- }
-
- i = client_add(fd, process_connection, NULL);
-
- log_debug("client connection %d fd %d", i, fd);
-}
-
-static int setup_listener(const char *sock_path)
-{
- struct sockaddr_un addr;
- socklen_t addrlen;
- int rv, s;
-
- /* we listen for new client connections on socket s */
-
- s = socket(AF_LOCAL, SOCK_STREAM, 0);
- if (s < 0) {
- log_error("socket error %d %d", s, errno);
- return s;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- strcpy(&addr.sun_path[1], sock_path);
- addrlen = sizeof(sa_family_t) + strlen(addr.sun_path+1) + 1;
-
- rv = bind(s, (struct sockaddr *) &addr, addrlen);
- if (rv < 0) {
- log_error("bind error %d %d", rv, errno);
- close(s);
- return rv;
- }
-
- rv = listen(s, 5);
- if (rv < 0) {
- log_error("listen error %d %d", rv, errno);
- close(s);
- return rv;
- }
- return s;
-}
-
-static void query_lock(void)
-{
- pthread_mutex_lock(&query_mutex);
-}
-
-static void query_unlock(void)
-{
- pthread_mutex_unlock(&query_mutex);
-}
-
-/* This is a thread, so we have to be careful, don't call log_ functions.
- We need a thread to process queries because the main thread may block
- for long periods when writing to sysfs to stop dlm-kernel (any maybe
- other places). */
-
-static void *process_queries(void *arg)
-{
- struct dlmc_header h;
- int s, f, rv;
-
- rv = setup_listener(DLMC_QUERY_SOCK_PATH);
- if (rv < 0)
- return NULL;
-
- s = rv;
-
- for (;;) {
- f = accept(s, NULL, NULL);
- if (f < 0)
- return NULL;
-
- rv = do_read(f, &h, sizeof(h));
- if (rv < 0) {
- goto out;
- }
-
- if (h.magic != DLMC_MAGIC) {
- goto out;
- }
-
- if ((h.version & 0xFFFF0000) != (DLMC_VERSION & 0xFFFF0000)) {
- goto out;
- }
-
- query_lock();
-
- switch (h.command) {
- case DLMC_CMD_DUMP_DEBUG:
- query_dump_debug(f);
- break;
- case DLMC_CMD_DUMP_LOG_PLOCK:
- query_dump_log_plock(f);
- break;
- case DLMC_CMD_DUMP_PLOCKS:
- query_dump_plocks(f, h.name);
- break;
- case DLMC_CMD_LOCKSPACE_INFO:
- query_lockspace_info(f, h.name);
- break;
- case DLMC_CMD_NODE_INFO:
- query_node_info(f, h.name, h.data);
- break;
- case DLMC_CMD_LOCKSPACES:
- query_lockspaces(f, h.data);
- break;
- case DLMC_CMD_LOCKSPACE_NODES:
- query_lockspace_nodes(f, h.name, h.option, h.data);
- break;
- default:
- break;
- }
- query_unlock();
-
- out:
- close(f);
- }
-}
-
-static int setup_queries(void)
-{
- int rv;
-
- pthread_mutex_init(&query_mutex, NULL);
-
- rv = pthread_create(&query_thread, NULL, process_queries, NULL);
- if (rv < 0) {
- log_error("can't create query thread");
- return rv;
- }
- return 0;
-}
-
-/* The dlm in kernels before 2.6.28 do not have the monitor device. We
- keep this fd open as long as we're running. If we exit/terminate while
- lockspaces exist in the kernel, the kernel will detect a close on this
- fd and stop the lockspaces. */
-
-static void setup_monitor(void)
-{
- if (!monitor_minor)
- return;
-
- kernel_monitor_fd = open("/dev/misc/dlm-monitor", O_RDONLY);
- log_debug("/dev/misc/dlm-monitor fd %d", kernel_monitor_fd);
-}
-
-void cluster_dead(int ci)
-{
- if (!cluster_down)
- log_error("cluster is down, exiting");
- daemon_quit = 1;
- cluster_down = 1;
-}
-
-static void loop(void)
-{
- int poll_timeout = -1;
- int rv, i;
- void (*workfn) (int ci);
- void (*deadfn) (int ci);
-
- rv = setup_queries();
- if (rv < 0)
- goto out;
-
- rv = setup_listener(DLMC_SOCK_PATH);
- if (rv < 0)
- goto out;
- client_add(rv, process_listener, NULL);
-
- rv = setup_cluster();
- if (rv < 0)
- goto out;
- client_add(rv, process_cluster, cluster_dead);
-
- rv = setup_ccs();
- if (rv < 0)
- goto out;
-
- setup_logging();
-
- rv = check_uncontrolled_lockspaces();
- if (rv < 0)
- goto out;
-
- rv = setup_misc_devices();
- if (rv < 0)
- goto out;
-
- setup_monitor();
-
- rv = setup_configfs(); /* calls update_cluster() */
- if (rv < 0)
- goto out;
-
- rv = setup_uevent();
- if (rv < 0)
- goto out;
- client_add(rv, process_uevent, NULL);
-
- group_mode = GROUP_LIBCPG;
-
- if (cfgd_groupd_compat) {
- rv = setup_groupd();
- if (rv < 0)
- goto out;
- client_add(rv, process_groupd, cluster_dead);
-
- switch (cfgd_groupd_compat) {
- case 1:
- group_mode = GROUP_LIBGROUP;
- rv = 0;
- break;
- case 2:
- rv = set_group_mode();
- break;
- default:
- log_error("inval groupd_compat %d", cfgd_groupd_compat);
- rv = -1;
- break;
- }
- if (rv < 0)
- goto out;
- }
- log_debug("group_mode %d compat %d", group_mode, cfgd_groupd_compat);
-
- if (group_mode == GROUP_LIBCPG) {
- rv = setup_cpg_daemon();
- if (rv < 0)
- goto out;
- client_add(rv, process_cpg_daemon, cluster_dead);
-
- rv = set_protocol();
- if (rv < 0)
- goto out;
-
- if (cfgd_enable_deadlk) {
- rv = setup_netlink();
- if (rv < 0)
- goto out;
- client_add(rv, process_netlink, NULL);
-
- setup_deadlock();
- }
-
- rv = setup_plocks();
- if (rv < 0)
- goto out;
- plock_fd = rv;
- plock_ci = client_add(rv, process_plocks, NULL);
- }
-
- query_lock();
- daemon_ready = 1;
- query_unlock();
-
- for (;;) {
- rv = poll(pollfd, client_maxi + 1, poll_timeout);
- if (rv == -1 && errno == EINTR) {
- if (daemon_quit && list_empty(&lockspaces))
- goto out;
- daemon_quit = 0;
- continue;
- }
- if (rv < 0) {
- log_error("poll errno %d", errno);
- goto out;
- }
-
- query_lock();
-
- for (i = 0; i <= client_maxi; i++) {
- if (client[i].fd < 0)
- continue;
- if (pollfd[i].revents & POLLIN) {
- workfn = client[i].workfn;
- workfn(i);
- }
- if (pollfd[i].revents & (POLLERR | POLLHUP | POLLNVAL)) {
- deadfn = client[i].deadfn;
- deadfn(i);
- }
- }
- query_unlock();
-
- if (daemon_quit)
- break;
-
- query_lock();
-
- poll_timeout = -1;
-
- if (poll_fencing || poll_quorum || poll_fs) {
- process_lockspace_changes();
- poll_timeout = 1000;
- }
-
- if (poll_ignore_plock) {
- if (!limit_plocks()) {
- poll_ignore_plock = 0;
- client_back(plock_ci, plock_fd);
- }
- poll_timeout = 1000;
- }
-
- if (poll_drop_plock) {
- drop_resources_all();
- if (poll_drop_plock)
- poll_timeout = 1000;
- }
-
- query_unlock();
- }
- out:
- if (cfgd_groupd_compat)
- close_groupd();
- if (group_mode == GROUP_LIBCPG) {
- close_cpg_daemon();
- close_plocks();
- }
- clear_configfs();
- close_logging();
- close_ccs();
- close_cluster();
-
- if (!list_empty(&lockspaces))
- log_error("lockspaces abandoned");
-}
-
-static void lockfile(void)
-{
- int fd, error;
- struct flock lock;
- char buf[33];
-
- memset(buf, 0, 33);
-
- fd = open(LOCKFILE_NAME, O_CREAT|O_WRONLY,
- S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
- if (fd < 0) {
- 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, "dlm_controld 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 print_usage(void)
-{
- printf("Usage:\n");
- printf("\n");
- printf("dlm_controld [options]\n");
- printf("\n");
- printf("Options:\n");
- printf("\n");
- printf(" -D Enable debugging to stderr and don't fork\n");
- printf(" -L Enable debugging to log file\n");
- printf(" -K Enable kernel dlm debugging messages\n");
- printf(" -r <num> dlm kernel lowcomms protocol, 0 tcp, 1 sctp, 2 detect\n");
- printf(" 2 selects tcp if corosync rrp_mode is \"none\", otherwise sctp\n");
- printf(" Default is 2\n");
- printf(" -g <num> groupd compatibility mode, 0 off, 1 on, 2 detect\n");
- printf(" 0: use libcpg, no backward compat, best performance\n");
- printf(" 1: use libgroup for compat with cluster2/rhel5\n");
- printf(" 2: use groupd to detect old, or mode 1, nodes that\n"
- " require compat, use libcpg if none found\n");
- printf(" Default is %d\n", DEFAULT_GROUPD_COMPAT);
- printf(" -f <num> Enable (1) or disable (0) fencing recovery dependency\n");
- printf(" Default is %d\n", DEFAULT_ENABLE_FENCING);
- printf(" -q <num> Enable (1) or disable (0) quorum recovery dependency\n");
- printf(" Default is %d\n", DEFAULT_ENABLE_QUORUM);
- printf(" -d <num> Enable (1) or disable (0) deadlock detection code\n");
- printf(" Default is %d\n", DEFAULT_ENABLE_DEADLK);
- printf(" -p <num> Enable (1) or disable (0) plock code for cluster fs\n");
- printf(" Default is %d\n", DEFAULT_ENABLE_PLOCK);
- printf(" -P Enable plock debugging\n");
- printf(" -l <limit> Limit the rate of plock operations\n");
- printf(" Default is %d, set to 0 for no limit\n", DEFAULT_PLOCK_RATE_LIMIT);
- printf(" -o <n> Enable (1) or disable (0) plock ownership\n");
- printf(" Default is %d\n", DEFAULT_PLOCK_OWNERSHIP);
- printf(" -t <ms> plock ownership drop resources time (milliseconds)\n");
- printf(" Default is %u\n", DEFAULT_DROP_RESOURCES_TIME);
- printf(" -c <num> plock ownership drop resources count\n");
- printf(" Default is %u\n", DEFAULT_DROP_RESOURCES_COUNT);
- printf(" -a <ms> plock ownership drop resources age (milliseconds)\n");
- printf(" Default is %u\n", DEFAULT_DROP_RESOURCES_AGE);
- printf(" -h Print this help, then exit\n");
- printf(" -V Print program version information, then exit\n");
-}
-
-#define OPTION_STRING "LDKg:f:q:d:p:Pl:o:t:c:a:hVr:"
-
-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':
- daemon_debug_opt = 1;
- break;
-
- case 'L':
- optd_debug_logfile = 1;
- cfgd_debug_logfile = 1;
- break;
-
- case 'g':
- optd_groupd_compat = 1;
- cfgd_groupd_compat = atoi(optarg);
- break;
-
- case 'K':
- optk_debug = 1;
- cfgk_debug = 1;
- break;
-
- case 'r':
- optk_protocol = 1;
- cfgk_protocol = atoi(optarg);
- break;
-
- case 'f':
- optd_enable_fencing = 1;
- cfgd_enable_fencing = atoi(optarg);
- break;
-
- case 'q':
- optd_enable_quorum = 1;
- cfgd_enable_quorum = atoi(optarg);
- break;
-
- case 'd':
- optd_enable_deadlk = 1;
- cfgd_enable_deadlk = atoi(optarg);
- break;
-
- case 'p':
- optd_enable_plock = 1;
- cfgd_enable_plock = atoi(optarg);
- break;
-
- case 'P':
- optd_plock_debug = 1;
- cfgd_plock_debug = 1;
- break;
-
- case 'l':
- optd_plock_rate_limit = 1;
- cfgd_plock_rate_limit = atoi(optarg);
- break;
-
- case 'o':
- optd_plock_ownership = 1;
- cfgd_plock_ownership = atoi(optarg);
- break;
-
- case 't':
- optd_drop_resources_time = 1;
- cfgd_drop_resources_time = atoi(optarg);
- break;
-
- case 'c':
- optd_drop_resources_count = 1;
- cfgd_drop_resources_count = atoi(optarg);
- break;
-
- case 'a':
- optd_drop_resources_age = 1;
- cfgd_drop_resources_age = atoi(optarg);
- break;
-
- case 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case 'V':
- printf("dlm_controld %s (built %s %s)\n",
- RELEASE_VERSION, __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- break;
-
- case ':':
- case '?':
- fprintf(stderr, "Please use '-h' for usage.\n");
- exit(EXIT_FAILURE);
- break;
-
- case EOF:
- cont = 0;
- break;
-
- default:
- fprintf(stderr, "unknown option: %c\n", optchar);
- exit(EXIT_FAILURE);
- break;
- };
- }
-
- if (getenv("DLM_CONTROLD_DEBUG")) {
- optd_debug_logfile = 1;
- cfgd_debug_logfile = 1;
- }
-}
-
-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)
- log_error("could not set SCHED_RR priority %d err %d",
- sched_param.sched_priority, errno);
- } else {
- log_error("could not get maximum scheduler priority err %d",
- errno);
- }
-}
-
-int main(int argc, char **argv)
-{
- INIT_LIST_HEAD(&lockspaces);
- INIT_LIST_HEAD(&fs_register_list);
-
- read_arguments(argc, argv);
-
- if (!daemon_debug_opt) {
- if (daemon(0, 0) < 0) {
- perror("daemon error");
- exit(EXIT_FAILURE);
- }
- }
- lockfile();
- init_logging();
- log_level(LOG_INFO, "dlm_controld %s started", RELEASE_VERSION);
- signal(SIGTERM, sigterm_handler);
- set_scheduler();
-
- loop();
-
- unlink(LOCKFILE_NAME);
- return 0;
-}
-
-void daemon_dump_save(void)
-{
- int len, i;
-
- len = strlen(daemon_debug_buf);
-
- for (i = 0; i < len; i++) {
- dump_buf[dump_point++] = daemon_debug_buf[i];
-
- if (dump_point == DLMC_DUMP_SIZE) {
- dump_point = 0;
- dump_wrap = 1;
- }
- }
-}
-
-void log_plock_save(void)
-{
- int len, i;
-
- len = strlen(log_plock_line);
-
- for (i = 0; i < len; i++) {
- log_plock_buf[log_plock_point++] = log_plock_line[i];
-
- if (log_plock_point == DLMC_DUMP_SIZE) {
- log_plock_point = 0;
- log_plock_wrap = 1;
- }
- }
-}
-
-int daemon_debug_opt;
-int daemon_quit;
-int cluster_down;
-int poll_fencing;
-int poll_quorum;
-int poll_fs;
-int poll_ignore_plock;
-int poll_drop_plock;
-int plock_fd;
-int plock_ci;
-struct list_head lockspaces;
-int cluster_quorate;
-int our_nodeid;
-char plock_dump_buf[DLMC_DUMP_SIZE];
-int plock_dump_len;
-int group_mode;
-uint32_t control_minor;
-uint32_t monitor_minor;
-uint32_t plock_minor;
-uint32_t old_plock_minor;
-char daemon_debug_buf[256];
-char dump_buf[DLMC_DUMP_SIZE];
-int dump_point;
-int dump_wrap;
-char log_plock_line[256];
-char log_plock_buf[DLMC_DUMP_SIZE];
-int log_plock_point;
-int log_plock_wrap;
-
-/* was a config value set on command line?, 0 or 1.
- optk is a kernel option, optd is a daemon option */
-
-int optk_debug;
-int optk_timewarn;
-int optk_protocol;
-int optd_groupd_compat;
-int optd_debug_logfile;
-int optd_enable_fencing;
-int optd_enable_quorum;
-int optd_enable_deadlk;
-int optd_enable_plock;
-int optd_plock_debug;
-int optd_plock_rate_limit;
-int optd_plock_ownership;
-int optd_drop_resources_time;
-int optd_drop_resources_count;
-int optd_drop_resources_age;
-
-/* actual config value from command line, cluster.conf, or default.
- cfgk is a kernel config value, cfgd is a daemon config value */
-
-int cfgk_debug = -1;
-int cfgk_timewarn = -1;
-int cfgk_protocol = PROTO_DETECT;
-int cfgd_groupd_compat = DEFAULT_GROUPD_COMPAT;
-int cfgd_debug_logfile = DEFAULT_DEBUG_LOGFILE;
-int cfgd_enable_fencing = DEFAULT_ENABLE_FENCING;
-int cfgd_enable_quorum = DEFAULT_ENABLE_QUORUM;
-int cfgd_enable_deadlk = DEFAULT_ENABLE_DEADLK;
-int cfgd_enable_plock = DEFAULT_ENABLE_PLOCK;
-int cfgd_plock_debug = DEFAULT_PLOCK_DEBUG;
-int cfgd_plock_rate_limit = DEFAULT_PLOCK_RATE_LIMIT;
-int cfgd_plock_ownership = DEFAULT_PLOCK_OWNERSHIP;
-int cfgd_drop_resources_time = DEFAULT_DROP_RESOURCES_TIME;
-int cfgd_drop_resources_count = DEFAULT_DROP_RESOURCES_COUNT;
-int cfgd_drop_resources_age = DEFAULT_DROP_RESOURCES_AGE;
-
diff --git a/group/dlm_controld/member_cman.c b/group/dlm_controld/member_cman.c
deleted file mode 100644
index 2b115d5..0000000
--- a/group/dlm_controld/member_cman.c
+++ /dev/null
@@ -1,350 +0,0 @@
-#include "dlm_daemon.h"
-#include "config.h"
-#include <libcman.h>
-#include "libfenced.h"
-
-static cman_handle_t ch;
-static cman_handle_t ch_admin;
-static cman_node_t old_nodes[MAX_NODES];
-static int old_node_count;
-static cman_node_t cman_nodes[MAX_NODES];
-static int cman_node_count;
-static uint32_t cluster_ringid_seq;
-
-void kick_node_from_cluster(int nodeid)
-{
- if (!nodeid) {
- log_error("telling cman to shut down cluster locally");
- cman_shutdown(ch_admin, CMAN_SHUTDOWN_ANYWAY);
- } else {
- log_error("telling cman to remove nodeid %d from cluster",
- nodeid);
- cman_kill_node(ch_admin, nodeid);
- }
-}
-
-static cman_node_t *get_node(cman_node_t *node_list, int count, int nodeid)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- if (node_list[i].cn_nodeid == nodeid)
- return &node_list[i];
- }
- return NULL;
-}
-
-static int is_member(cman_node_t *node_list, int count, int nodeid)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- if (node_list[i].cn_nodeid == nodeid)
- return node_list[i].cn_member;
- }
- return 0;
-}
-
-static int is_old_member(int nodeid)
-{
- return is_member(old_nodes, old_node_count, nodeid);
-}
-
-int is_cluster_member(int nodeid)
-{
- return is_member(cman_nodes, cman_node_count, nodeid);
-}
-
-static cman_node_t *find_cman_node(int nodeid)
-{
- int i;
-
- for (i = 0; i < cman_node_count; i++) {
- if (cman_nodes[i].cn_nodeid == nodeid)
- return &cman_nodes[i];
- }
- return NULL;
-}
-
-char *nodeid2name(int nodeid)
-{
- cman_node_t *cn;
-
- cn = find_cman_node(nodeid);
- if (!cn)
- return NULL;
- return cn->cn_name;
-}
-
-/* add a configfs dir for cluster members that don't have one,
- del the configfs dir for cluster members that are now gone */
-
-static void statechange(void)
-{
- cman_cluster_t info;
- cman_node_t *old;
- int i, j, rv;
- struct cman_node_address addrs[MAX_NODE_ADDRESSES];
- int num_addrs;
- struct cman_node_address *addrptr = addrs;
-
- rv = cman_get_cluster(ch, &info);
- if (rv < 0) {
- log_error("cman_get_cluster error %d %d", rv, errno);
- /* keep going, this is just informational */
- memset(&info, 0, sizeof(info));
- }
- cluster_ringid_seq = info.ci_generation;
-
- cluster_quorate = cman_is_quorate(ch);
-
- old_node_count = cman_node_count;
- memcpy(&old_nodes, &cman_nodes, sizeof(old_nodes));
-
- cman_node_count = 0;
- memset(&cman_nodes, 0, sizeof(cman_nodes));
- rv = cman_get_nodes(ch, MAX_NODES, &cman_node_count, cman_nodes);
- if (rv < 0) {
- log_debug("cman_get_nodes error %d %d", rv, errno);
- return;
- }
-
- /* Never allow node ID 0 to be considered a member #315711 */
- for (i = 0; i < cman_node_count; i++) {
- if (cman_nodes[i].cn_nodeid == 0) {
- cman_nodes[i].cn_member = 0;
- break;
- }
- }
-
- for (i = 0; i < old_node_count; i++) {
- if (old_nodes[i].cn_member &&
- !is_cluster_member(old_nodes[i].cn_nodeid)) {
-
- log_debug("cluster node %d removed seq %u",
- old_nodes[i].cn_nodeid, cluster_ringid_seq);
-
- node_history_cluster_remove(old_nodes[i].cn_nodeid);
-
- del_configfs_node(old_nodes[i].cn_nodeid);
- }
- }
-
- for (i = 0; i < cman_node_count; i++) {
- if (cman_nodes[i].cn_member &&
- !is_old_member(cman_nodes[i].cn_nodeid)) {
-
- log_debug("cluster node %d added seq %u",
- cman_nodes[i].cn_nodeid, cluster_ringid_seq);
-
- rv = cman_get_node_addrs(ch, cman_nodes[i].cn_nodeid,
- MAX_NODE_ADDRESSES,
- &num_addrs, addrs);
- if (rv < 0) {
- log_debug("cman_get_node_addrs failed, falling back to single-homed. ");
- num_addrs = 1;
- addrptr = &cman_nodes[i].cn_address;
- }
-
- node_history_cluster_add(cman_nodes[i].cn_nodeid);
-
- for (j = 0; j < num_addrs; j++) {
- add_configfs_node(cman_nodes[i].cn_nodeid,
- addrptr[j].cna_address,
- addrptr[j].cna_addrlen,
- (cman_nodes[i].cn_nodeid ==
- our_nodeid));
- }
- } else {
- /* look for any nodes that were members of both
- * old and new but have a new incarnation number
- * from old to new, indicating they left and rejoined
- * in between */
-
- old = get_node(old_nodes, old_node_count, cman_nodes[i].cn_nodeid);
-
- if (!old)
- continue;
- if (cman_nodes[i].cn_incarnation == old->cn_incarnation)
- continue;
-
- log_debug("cluster node %d removed and added seq %u "
- "old %u new %u",
- cman_nodes[i].cn_nodeid, cluster_ringid_seq,
- old->cn_incarnation,
- cman_nodes[i].cn_incarnation);
-
- /*
- * remove (copied from above)
- */
-
- node_history_cluster_remove(old_nodes[i].cn_nodeid);
-
- del_configfs_node(old_nodes[i].cn_nodeid);
-
- /*
- * add (copied from above)
- */
-
- rv = cman_get_node_addrs(ch, cman_nodes[i].cn_nodeid,
- MAX_NODE_ADDRESSES,
- &num_addrs, addrs);
- if (rv < 0) {
- log_debug("cman_get_node_addrs failed, falling back to single-homed. ");
- num_addrs = 1;
- addrptr = &cman_nodes[i].cn_address;
- }
-
- node_history_cluster_add(cman_nodes[i].cn_nodeid);
-
- for (j = 0; j < num_addrs; j++) {
- add_configfs_node(cman_nodes[i].cn_nodeid,
- addrptr[j].cna_address,
- addrptr[j].cna_addrlen,
- (cman_nodes[i].cn_nodeid ==
- our_nodeid));
- }
- }
- }
-}
-
-static void cman_callback(cman_handle_t h, void *private, int reason, int arg)
-{
- switch (reason) {
- case CMAN_REASON_TRY_SHUTDOWN:
- if (list_empty(&lockspaces))
- cman_replyto_shutdown(ch, 1);
- else {
- log_debug("no to cman shutdown");
- cman_replyto_shutdown(ch, 0);
- }
- break;
- case CMAN_REASON_STATECHANGE:
- statechange();
- break;
- case CMAN_REASON_CONFIG_UPDATE:
- setup_logging();
- setup_ccs();
- break;
- }
-}
-
-void process_cluster(int ci)
-{
- int rv;
-
- rv = cman_dispatch(ch, CMAN_DISPATCH_ALL);
- if (rv == -1 && errno == EHOSTDOWN)
- cluster_dead(0);
-}
-
-int setup_cluster(void)
-{
- cman_node_t node;
- int rv, fd;
- int init = 0, active = 0;
-
- retry_init:
- ch_admin = cman_admin_init(NULL);
- if (!ch_admin) {
- if (init++ < 2) {
- sleep(1);
- goto retry_init;
- }
- log_error("cman_admin_init error %d", errno);
- return -ENOTCONN;
- }
-
- ch = cman_init(NULL);
- if (!ch) {
- log_error("cman_init error %d", errno);
- cman_finish(ch_admin);
- return -ENOTCONN;
- }
-
- retry_active:
- rv = cman_is_active(ch);
- if (!rv) {
- if (active++ < 2) {
- sleep(1);
- goto retry_active;
- }
- log_error("cman_is_active error %d", errno);
- cman_finish(ch);
- cman_finish(ch_admin);
- return -ENOTCONN;
- }
-
- rv = cman_start_notification(ch, cman_callback);
- if (rv < 0) {
- log_error("cman_start_notification error %d %d", rv, errno);
- cman_finish(ch);
- cman_finish(ch_admin);
- return rv;
- }
-
- fd = cman_get_fd(ch);
-
- /* FIXME: wait here for us to be a member of the cluster */
- memset(&node, 0, sizeof(node));
- rv = cman_get_node(ch, CMAN_NODEID_US, &node);
- if (rv < 0) {
- log_error("cman_get_node us error %d %d", rv, errno);
- cman_stop_notification(ch);
- cman_finish(ch);
- cman_finish(ch_admin);
- fd = rv;
- goto out;
- }
- our_nodeid = node.cn_nodeid;
-
- old_node_count = 0;
- memset(&old_nodes, 0, sizeof(old_nodes));
- cman_node_count = 0;
- memset(&cman_nodes, 0, sizeof(cman_nodes));
- out:
- return fd;
-}
-
-void close_cluster(void)
-{
- cman_finish(ch);
- cman_finish(ch_admin);
-}
-
-/* Force re-read of cman nodes */
-void update_cluster(void)
-{
- statechange();
-}
-
-int fence_node_time(int nodeid, uint64_t *last_fenced_time)
-{
- struct fenced_node nodeinfo;
- int rv;
-
- memset(&nodeinfo, 0, sizeof(nodeinfo));
-
- rv = fenced_node_info(nodeid, &nodeinfo);
- if (rv < 0)
- return rv;
-
- *last_fenced_time = nodeinfo.last_fenced_time;
- return 0;
-}
-
-int fence_in_progress(int *count)
-{
- struct fenced_domain domain;
- int rv;
-
- memset(&domain, 0, sizeof(domain));
-
- rv = fenced_domain_info(&domain);
- if (rv < 0)
- return rv;
-
- *count = domain.victim_count;
- return 0;
-}
-
diff --git a/group/dlm_controld/netlink.c b/group/dlm_controld/netlink.c
deleted file mode 100644
index 63122f7..0000000
--- a/group/dlm_controld/netlink.c
+++ /dev/null
@@ -1,225 +0,0 @@
-#include "dlm_daemon.h"
-#include "config.h"
-#include <linux/dlm.h>
-#include <linux/netlink.h>
-#include <linux/genetlink.h>
-#include <linux/dlm_netlink.h>
-
-#define DEADLOCK_CHECK_SECS 10
-
-/* FIXME: look into using libnl/libnetlink */
-
-#define GENLMSG_DATA(glh) ((void *)((char *)NLMSG_DATA(glh) + GENL_HDRLEN))
-#define GENLMSG_PAYLOAD(glh) (NLMSG_PAYLOAD(glh, 0) - GENL_HDRLEN)
-#define NLA_DATA(na) ((void *)((char*)(na) + NLA_HDRLEN))
-#define NLA_PAYLOAD(len) (len - NLA_HDRLEN)
-
-/* Maximum size of response requested or message sent */
-#define MAX_MSG_SIZE 1024
-
-struct msgtemplate {
- struct nlmsghdr n;
- struct genlmsghdr g;
- char buf[MAX_MSG_SIZE];
-};
-
-static int send_genetlink_cmd(int sd, uint16_t nlmsg_type, uint32_t nlmsg_pid,
- uint8_t genl_cmd, uint16_t nla_type,
- void *nla_data, int nla_len)
-{
- struct nlattr *na;
- struct sockaddr_nl nladdr;
- int r, buflen;
- char *buf;
-
- struct msgtemplate msg;
-
- msg.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
- msg.n.nlmsg_type = nlmsg_type;
- msg.n.nlmsg_flags = NLM_F_REQUEST;
- msg.n.nlmsg_seq = 0;
- msg.n.nlmsg_pid = nlmsg_pid;
- msg.g.cmd = genl_cmd;
- msg.g.version = 0x1;
- na = (struct nlattr *) GENLMSG_DATA(&msg);
- na->nla_type = nla_type;
- na->nla_len = nla_len + 1 + NLA_HDRLEN;
- if (nla_data)
- memcpy(NLA_DATA(na), nla_data, nla_len);
- msg.n.nlmsg_len += NLMSG_ALIGN(na->nla_len);
-
- buf = (char *) &msg;
- buflen = msg.n.nlmsg_len ;
- memset(&nladdr, 0, sizeof(nladdr));
- nladdr.nl_family = AF_NETLINK;
- while ((r = sendto(sd, buf, buflen, 0, (struct sockaddr *) &nladdr,
- sizeof(nladdr))) < buflen) {
- if (r > 0) {
- buf += r;
- buflen -= r;
- } else if (errno != EAGAIN)
- return -1;
- }
- return 0;
-}
-
-/*
- * Probe the controller in genetlink to find the family id
- * for the DLM family
- */
-static int get_family_id(int sd)
-{
- char genl_name[100];
- struct {
- struct nlmsghdr n;
- struct genlmsghdr g;
- char buf[256];
- } ans;
-
- int id = 0, rc;
- struct nlattr *na;
- int rep_len;
-
- strcpy(genl_name, DLM_GENL_NAME);
- rc = send_genetlink_cmd(sd, GENL_ID_CTRL, getpid(), CTRL_CMD_GETFAMILY,
- CTRL_ATTR_FAMILY_NAME, (void *)genl_name,
- strlen(DLM_GENL_NAME)+1);
-
- rep_len = recv(sd, &ans, sizeof(ans), 0);
- if (ans.n.nlmsg_type == NLMSG_ERROR ||
- (rep_len < 0) || !NLMSG_OK((&ans.n), rep_len))
- return 0;
-
- na = (struct nlattr *) GENLMSG_DATA(&ans);
- na = (struct nlattr *) ((char *) na + NLA_ALIGN(na->nla_len));
- if (na->nla_type == CTRL_ATTR_FAMILY_ID) {
- id = *(uint16_t *) NLA_DATA(na);
- }
- return id;
-}
-
-/* genetlink messages are timewarnings used as part of deadlock detection */
-
-int setup_netlink(void)
-{
- struct sockaddr_nl snl;
- int s, rv;
- uint16_t id;
-
- s = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
- if (s < 0) {
- log_error("generic netlink socket");
- return s;
- }
-
- memset(&snl, 0, sizeof(snl));
- snl.nl_family = AF_NETLINK;
-
- rv = bind(s, (struct sockaddr *) &snl, sizeof(snl));
- if (rv < 0) {
- log_error("gen netlink bind error %d errno %d", rv, errno);
- close(s);
- return rv;
- }
-
- id = get_family_id(s);
- if (!id) {
- log_error("Error getting family id, errno %d", errno);
- close(s);
- return -1;
- }
-
- rv = send_genetlink_cmd(s, id, getpid(), DLM_CMD_HELLO, 0, NULL, 0);
- if (rv < 0) {
- log_error("error sending hello cmd, errno %d", errno);
- close(s);
- return -1;
- }
-
- return s;
-}
-
-static void process_timewarn(struct dlm_lock_data *data)
-{
- struct lockspace *ls;
- struct timeval now;
- unsigned int sec;
-
- ls = find_ls_id(data->lockspace_id);
- if (!ls)
- return;
-
- data->resource_name[data->resource_namelen] = '\0';
-
- log_group(ls, "timewarn: lkid %x pid %d name %s",
- data->id, data->ownpid, data->resource_name);
-
- /* Problem: we don't want to get a timewarn, assume it's resolved
- by the current cycle, but in fact it's from a deadlock that
- formed after the checkpoints for the current cycle. Then we'd
- have to hope for another warning (that may not come) to trigger
- a new cycle to catch the deadlock. If our last cycle ckpt
- was say N (~5?) sec before we receive the timewarn, then we
- can be confident that the cycle included the lock in question.
- Otherwise, we're not sure if the warning is for a new deadlock
- that's formed since our last cycle ckpt (unless it's a long
- enough time since the last cycle that we're confident it *is*
- a new deadlock). When there is a deadlock, I suspect it will
- be common to receive warnings before, during, and possibly
- after the cycle that resolves it. Wonder if we should record
- timewarns and match them with deadlock cycles so we can tell
- which timewarns are addressed by a given cycle and which aren't. */
-
-
- gettimeofday(&now, NULL);
-
- /* don't send a new start until at least SECS after the last
- we sent, and at least SECS after the last completed cycle */
-
- sec = now.tv_sec - ls->last_send_cycle_start.tv_sec;
-
- if (sec < DEADLOCK_CHECK_SECS) {
- log_group(ls, "skip send: recent send cycle %d sec", sec);
- return;
- }
-
- sec = now.tv_sec - ls->cycle_end_time.tv_sec;
-
- if (sec < DEADLOCK_CHECK_SECS) {
- log_group(ls, "skip send: recent cycle end %d sec", sec);
- return;
- }
-
- gettimeofday(&ls->last_send_cycle_start, NULL);
-
- if (cfgd_enable_deadlk)
- send_cycle_start(ls);
-}
-
-void process_netlink(int ci)
-{
- struct msgtemplate msg;
- struct nlattr *na;
- int len;
- int fd;
-
- fd = client_fd(ci);
-
- len = recv(fd, &msg, sizeof(msg), 0);
-
- if (len < 0) {
- log_error("nonfatal netlink error: errno %d", errno);
- return;
- }
-
- if (msg.n.nlmsg_type == NLMSG_ERROR || !NLMSG_OK((&msg.n), len)) {
- struct nlmsgerr *err = NLMSG_DATA(&msg);
- log_error("fatal netlink error: errno %d", err->error);
- return;
- }
-
- na = (struct nlattr *) GENLMSG_DATA(&msg);
-
- process_timewarn((struct dlm_lock_data *) NLA_DATA(na));
-}
-
diff --git a/group/dlm_controld/plock.c b/group/dlm_controld/plock.c
deleted file mode 100644
index fbfe1b0..0000000
--- a/group/dlm_controld/plock.c
+++ /dev/null
@@ -1,2388 +0,0 @@
-#include "dlm_daemon.h"
-#include "config.h"
-
-#include <linux/dlm_plock.h>
-
-/* FIXME: remove this once everyone is using the version of
- * dlm_plock.h which defines it */
-
-#ifndef DLM_PLOCK_FL_CLOSE
-#warning DLM_PLOCK_FL_CLOSE undefined. Enabling build workaround.
-#define DLM_PLOCK_FL_CLOSE 1
-#define DLM_PLOCK_BUILD_WORKAROUND 1
-#endif
-
-static uint32_t plock_read_count;
-static uint32_t plock_recv_count;
-static uint32_t plock_rate_delays;
-static struct timeval plock_read_time;
-static struct timeval plock_recv_time;
-static struct timeval plock_rate_last;
-
-static int plock_device_fd = -1;
-static SaCkptHandleT system_ckpt_handle;
-static SaCkptCallbacksT callbacks = { 0, 0 };
-static SaVersionT version = { 'B', 1, 1 };
-static char section_buf[1024 * 1024];
-static uint32_t section_len;
-static int need_fsid_translation = 0;
-
-extern int message_flow_control_on;
-
-struct pack_plock {
- uint64_t start;
- uint64_t end;
- uint64_t owner;
- uint32_t pid;
- uint32_t nodeid;
- uint8_t ex;
- uint8_t waiter;
- uint16_t pad1;
- uint32_t pad;
-};
-
-#define R_GOT_UNOWN 0x00000001 /* have received owner=0 message */
-#define R_SEND_UNOWN 0x00000002 /* have sent owner=0 message */
-#define R_SEND_OWN 0x00000004 /* have sent owner=our_nodeid message */
-#define R_PURGE_UNOWN 0x00000008 /* set owner=0 in purge */
-#define R_SEND_DROP 0x00000010
-
-struct resource {
- struct list_head list; /* list of resources */
- uint64_t number;
- int owner; /* nodeid or 0 for unowned */
- uint32_t flags;
- struct timeval last_access;
- struct list_head locks; /* one lock for each range */
- struct list_head waiters;
- struct list_head pending; /* discovering r owner */
-};
-
-#define P_SYNCING 0x00000001 /* plock has been sent as part of sync but not
- yet received */
-
-struct posix_lock {
- struct list_head list; /* resource locks or waiters list */
- uint32_t pid;
- uint64_t owner;
- uint64_t start;
- uint64_t end;
- int ex;
- int nodeid;
- uint32_t flags;
-};
-
-struct lock_waiter {
- struct list_head list;
- uint32_t flags;
- struct dlm_plock_info info;
-};
-
-struct save_msg {
- struct list_head list;
- int nodeid;
- int len;
- int type;
- char buf[0];
-};
-
-
-static void send_own(struct lockspace *ls, struct resource *r, int owner);
-static void save_pending_plock(struct lockspace *ls, struct resource *r,
- struct dlm_plock_info *in);
-
-
-static int got_unown(struct resource *r)
-{
- return !!(r->flags & R_GOT_UNOWN);
-}
-
-static void info_bswap_out(struct dlm_plock_info *i)
-{
- i->version[0] = cpu_to_le32(i->version[0]);
- i->version[1] = cpu_to_le32(i->version[1]);
- i->version[2] = cpu_to_le32(i->version[2]);
- i->pid = cpu_to_le32(i->pid);
- i->nodeid = cpu_to_le32(i->nodeid);
- i->rv = cpu_to_le32(i->rv);
- i->fsid = cpu_to_le32(i->fsid);
- i->number = cpu_to_le64(i->number);
- i->start = cpu_to_le64(i->start);
- i->end = cpu_to_le64(i->end);
- i->owner = cpu_to_le64(i->owner);
-}
-
-static void info_bswap_in(struct dlm_plock_info *i)
-{
- i->version[0] = le32_to_cpu(i->version[0]);
- i->version[1] = le32_to_cpu(i->version[1]);
- i->version[2] = le32_to_cpu(i->version[2]);
- i->pid = le32_to_cpu(i->pid);
- i->nodeid = le32_to_cpu(i->nodeid);
- i->rv = le32_to_cpu(i->rv);
- i->fsid = le32_to_cpu(i->fsid);
- i->number = le64_to_cpu(i->number);
- i->start = le64_to_cpu(i->start);
- i->end = le64_to_cpu(i->end);
- i->owner = le64_to_cpu(i->owner);
-}
-
-static const char *op_str(int optype)
-{
- switch (optype) {
- case DLM_PLOCK_OP_LOCK:
- return "LK";
- case DLM_PLOCK_OP_UNLOCK:
- return "UN";
- case DLM_PLOCK_OP_GET:
- return "GET";
- default:
- return "??";
- }
-}
-
-static const char *ex_str(int optype, int ex)
-{
- if (optype == DLM_PLOCK_OP_UNLOCK || optype == DLM_PLOCK_OP_GET)
- return "-";
- if (ex)
- return "WR";
- else
- return "RD";
-}
-
-/*
- * In kernels before 2.6.26, plocks came from gfs2's lock_dlm module.
- * Reading plocks from there as well should allow us to use cluster3
- * on old (RHEL5) kernels. In this case, the fsid we read in plock_info
- * structs is the mountgroup id, which we need to translate to the ls id.
- */
-
-int setup_plocks(void)
-{
- SaAisErrorT err;
-
- plock_read_count = 0;
- plock_recv_count = 0;
- plock_rate_delays = 0;
- gettimeofday(&plock_read_time, NULL);
- gettimeofday(&plock_recv_time, NULL);
- gettimeofday(&plock_rate_last, NULL);
-
- err = saCkptInitialize(&system_ckpt_handle, &callbacks, &version);
- if (err != SA_AIS_OK) {
- log_error("ckpt init error %d", err);
- cfgd_enable_plock = 0;
-
- /* still try to open and read the control device so that we can
- send ENOSYS back to the kernel if it tries to do a plock */
- }
-
- if (plock_minor) {
- plock_device_fd = open("/dev/misc/dlm_plock", O_RDWR);
- } else if (old_plock_minor) {
- log_debug("setup_plocks using old lock_dlm interface");
- need_fsid_translation = 1;
- plock_device_fd = open("/dev/misc/lock_dlm_plock", O_RDWR);
- }
-
- if (plock_device_fd < 0) {
- log_error("Failure to open plock device: %s", strerror(errno));
- return -1;
- }
-
- log_debug("plocks %d", plock_device_fd);
- log_debug("plock cpg message size: %u bytes",
- (unsigned int) (sizeof(struct dlm_header) +
- sizeof(struct dlm_plock_info)));
-
- return plock_device_fd;
-}
-
-void close_plocks(void)
-{
- if (system_ckpt_handle)
- saCkptFinalize(system_ckpt_handle);
- if (plock_device_fd > 0)
- close(plock_device_fd);
-
-}
-
-static uint32_t mg_to_ls_id(uint32_t fsid)
-{
- struct lockspace *ls;
- int do_set = 1;
-
- retry:
- list_for_each_entry(ls, &lockspaces, list) {
- if (ls->associated_mg_id == fsid)
- return ls->global_id;
- }
-
- if (do_set) {
- do_set = 0;
- set_associated_id(fsid);
- goto retry;
- }
-
- return fsid;
-}
-
-/* FIXME: unify these two */
-
-static unsigned long time_diff_ms(struct timeval *begin, struct timeval *end)
-{
- struct timeval result;
- timersub(end, begin, &result);
- return (result.tv_sec * 1000) + (result.tv_usec / 1000);
-}
-
-static uint64_t dt_usec(struct timeval *start, struct timeval *stop)
-{
- uint64_t dt;
-
- dt = stop->tv_sec - start->tv_sec;
- dt *= 1000000;
- dt += stop->tv_usec - start->tv_usec;
- return dt;
-}
-
-static struct resource *search_resource(struct lockspace *ls, uint64_t number)
-{
- struct resource *r;
-
- list_for_each_entry(r, &ls->plock_resources, list) {
- if (r->number == number)
- return r;
- }
- return NULL;
-}
-
-static int find_resource(struct lockspace *ls, uint64_t number, int create,
- struct resource **r_out)
-{
- struct resource *r = NULL;
- int rv = 0;
-
- r = search_resource(ls, number);
- if (r)
- goto out;
-
- if (create == 0) {
- rv = -ENOENT;
- goto out;
- }
-
- r = malloc(sizeof(struct resource));
- if (!r) {
- log_plock_error(ls, "find_resource no memory %d", errno);
- rv = -ENOMEM;
- goto out;
- }
-
- memset(r, 0, sizeof(struct resource));
- r->number = number;
- INIT_LIST_HEAD(&r->locks);
- INIT_LIST_HEAD(&r->waiters);
- INIT_LIST_HEAD(&r->pending);
-
- if (cfgd_plock_ownership)
- r->owner = -1;
- else
- r->owner = 0;
-
- list_add_tail(&r->list, &ls->plock_resources);
- out:
- if (r)
- gettimeofday(&r->last_access, NULL);
- *r_out = r;
- return rv;
-}
-
-static void put_resource(struct resource *r)
-{
- /* with ownership, resources are only freed via drop messages */
- if (cfgd_plock_ownership)
- return;
-
- if (list_empty(&r->locks) && list_empty(&r->waiters)) {
- list_del(&r->list);
- free(r);
- }
-}
-
-static inline int ranges_overlap(uint64_t start1, uint64_t end1,
- uint64_t start2, uint64_t end2)
-{
- if (end1 < start2 || start1 > end2)
- return 0;
- return 1;
-}
-
-/**
- * overlap_type - returns a value based on the type of overlap
- * @s1 - start of new lock range
- * @e1 - end of new lock range
- * @s2 - start of existing lock range
- * @e2 - end of existing lock range
- *
- */
-
-static int overlap_type(uint64_t s1, uint64_t e1, uint64_t s2, uint64_t e2)
-{
- int ret;
-
- /*
- * ---r1---
- * ---r2---
- */
-
- if (s1 == s2 && e1 == e2)
- ret = 0;
-
- /*
- * --r1--
- * ---r2---
- */
-
- else if (s1 == s2 && e1 < e2)
- ret = 1;
-
- /*
- * --r1--
- * ---r2---
- */
-
- else if (s1 > s2 && e1 == e2)
- ret = 1;
-
- /*
- * --r1--
- * ---r2---
- */
-
- else if (s1 > s2 && e1 < e2)
- ret = 2;
-
- /*
- * ---r1--- or ---r1--- or ---r1---
- * --r2-- --r2-- --r2--
- */
-
- else if (s1 <= s2 && e1 >= e2)
- ret = 3;
-
- /*
- * ---r1---
- * ---r2---
- */
-
- else if (s1 > s2 && e1 > e2)
- ret = 4;
-
- /*
- * ---r1---
- * ---r2---
- */
-
- else if (s1 < s2 && e1 < e2)
- ret = 4;
-
- else
- ret = -1;
-
- return ret;
-}
-
-/* shrink the range start2:end2 by the partially overlapping start:end */
-
-static int shrink_range2(uint64_t *start2, uint64_t *end2,
- uint64_t start, uint64_t end)
-{
- int error = 0;
-
- if (*start2 < start)
- *end2 = start - 1;
- else if (*end2 > end)
- *start2 = end + 1;
- else
- error = -1;
- return error;
-}
-
-static int shrink_range(struct posix_lock *po, uint64_t start, uint64_t end)
-{
- return shrink_range2(&po->start, &po->end, start, end);
-}
-
-static int is_conflict(struct resource *r, struct dlm_plock_info *in, int get)
-{
- struct posix_lock *po;
-
- list_for_each_entry(po, &r->locks, list) {
- if (po->nodeid == in->nodeid && po->owner == in->owner)
- continue;
- if (!ranges_overlap(po->start, po->end, in->start, in->end))
- continue;
-
- if (in->ex || po->ex) {
- if (get) {
- in->ex = po->ex;
- in->pid = po->pid;
- in->start = po->start;
- in->end = po->end;
- }
- return 1;
- }
- }
- return 0;
-}
-
-static int add_lock(struct resource *r, uint32_t nodeid, uint64_t owner,
- uint32_t pid, int ex, uint64_t start, uint64_t end)
-{
- struct posix_lock *po;
-
- po = malloc(sizeof(struct posix_lock));
- if (!po)
- return -ENOMEM;
- memset(po, 0, sizeof(struct posix_lock));
-
- po->start = start;
- po->end = end;
- po->nodeid = nodeid;
- po->owner = owner;
- po->pid = pid;
- po->ex = ex;
- list_add_tail(&po->list, &r->locks);
-
- return 0;
-}
-
-/* RN within RE (and starts or ends on RE boundary)
- 1. add new lock for non-overlap area of RE, orig mode
- 2. convert RE to RN range and mode */
-
-static int lock_case1(struct posix_lock *po, struct resource *r,
- struct dlm_plock_info *in)
-{
- uint64_t start2, end2;
- int rv;
-
- /* non-overlapping area start2:end2 */
- start2 = po->start;
- end2 = po->end;
- rv = shrink_range2(&start2, &end2, in->start, in->end);
- if (rv)
- goto out;
-
- po->start = in->start;
- po->end = in->end;
- po->ex = in->ex;
-
- rv = add_lock(r, in->nodeid, in->owner, in->pid, !in->ex, start2, end2);
- out:
- return rv;
-}
-
-/* RN within RE (RE overlaps RN on both sides)
- 1. add new lock for front fragment, orig mode
- 2. add new lock for back fragment, orig mode
- 3. convert RE to RN range and mode */
-
-static int lock_case2(struct posix_lock *po, struct resource *r,
- struct dlm_plock_info *in)
-
-{
- int rv;
-
- rv = add_lock(r, in->nodeid, in->owner, in->pid,
- !in->ex, po->start, in->start - 1);
- if (rv)
- goto out;
-
- rv = add_lock(r, in->nodeid, in->owner, in->pid,
- !in->ex, in->end + 1, po->end);
- if (rv)
- goto out;
-
- po->start = in->start;
- po->end = in->end;
- po->ex = in->ex;
- out:
- return rv;
-}
-
-static int lock_internal(struct lockspace *ls, struct resource *r,
- struct dlm_plock_info *in)
-{
- struct posix_lock *po, *safe;
- int rv = 0;
-
- list_for_each_entry_safe(po, safe, &r->locks, list) {
- if (po->nodeid != in->nodeid || po->owner != in->owner)
- continue;
- if (!ranges_overlap(po->start, po->end, in->start, in->end))
- continue;
-
- /* existing range (RE) overlaps new range (RN) */
-
- switch(overlap_type(in->start, in->end, po->start, po->end)) {
-
- case 0:
- if (po->ex == in->ex)
- goto out;
-
- /* ranges the same - just update the existing lock */
- po->ex = in->ex;
- goto out;
-
- case 1:
- if (po->ex == in->ex)
- goto out;
-
- rv = lock_case1(po, r, in);
- goto out;
-
- case 2:
- if (po->ex == in->ex)
- goto out;
-
- rv = lock_case2(po, r, in);
- goto out;
-
- case 3:
- list_del(&po->list);
- free(po);
- break;
-
- case 4:
- if (po->start < in->start)
- po->end = in->start - 1;
- else
- po->start = in->end + 1;
- break;
-
- default:
- rv = -1;
- goto out;
- }
- }
-
- rv = add_lock(r, in->nodeid, in->owner, in->pid,
- in->ex, in->start, in->end);
- out:
- return rv;
-
-}
-
-static int unlock_internal(struct lockspace *ls, struct resource *r,
- struct dlm_plock_info *in)
-{
- struct posix_lock *po, *safe;
- int rv = 0;
-
- list_for_each_entry_safe(po, safe, &r->locks, list) {
- if (po->nodeid != in->nodeid || po->owner != in->owner)
- continue;
- if (!ranges_overlap(po->start, po->end, in->start, in->end))
- continue;
-
- /* existing range (RE) overlaps new range (RN) */
-
- switch (overlap_type(in->start, in->end, po->start, po->end)) {
-
- case 0:
- /* ranges the same - just remove the existing lock */
-
- list_del(&po->list);
- free(po);
- goto out;
-
- case 1:
- /* RN within RE and starts or ends on RE boundary -
- * shrink and update RE */
-
- rv = shrink_range(po, in->start, in->end);
- goto out;
-
- case 2:
- /* RN within RE - shrink and update RE to be front
- * fragment, and add a new lock for back fragment */
-
- rv = add_lock(r, in->nodeid, in->owner, in->pid,
- po->ex, in->end + 1, po->end);
- po->end = in->start - 1;
- goto out;
-
- case 3:
- /* RE within RN - remove RE, then continue checking
- * because RN could cover other locks */
-
- list_del(&po->list);
- free(po);
- continue;
-
- case 4:
- /* front of RE in RN, or end of RE in RN - shrink and
- * update RE, then continue because RN could cover
- * other locks */
-
- rv = shrink_range(po, in->start, in->end);
- continue;
-
- default:
- rv = -1;
- goto out;
- }
- }
- out:
- return rv;
-}
-
-static void clear_waiters(struct lockspace *ls, struct resource *r,
- struct dlm_plock_info *in)
-{
- struct lock_waiter *w, *safe;
-
- list_for_each_entry_safe(w, safe, &r->waiters, list) {
- if (w->info.nodeid != in->nodeid || w->info.owner != in->owner)
- continue;
-
- list_del(&w->list);
-
- log_plock_error(ls, "clear waiter %llx %llx-%llx %d/%u/%llx",
- (unsigned long long)in->number,
- (unsigned long long)in->start,
- (unsigned long long)in->end,
- in->nodeid, in->pid,
- (unsigned long long)in->owner);
- free(w);
- }
-}
-
-static int add_waiter(struct lockspace *ls, struct resource *r,
- struct dlm_plock_info *in)
-
-{
- struct lock_waiter *w;
-
- w = malloc(sizeof(struct lock_waiter));
- if (!w)
- return -ENOMEM;
- memcpy(&w->info, in, sizeof(struct dlm_plock_info));
- list_add_tail(&w->list, &r->waiters);
- return 0;
-}
-
-static void write_result(struct lockspace *ls, struct dlm_plock_info *in,
- int rv)
-{
- if (need_fsid_translation)
- in->fsid = ls->associated_mg_id;
-
- in->rv = rv;
- write(plock_device_fd, in, sizeof(struct dlm_plock_info));
-}
-
-static void do_waiters(struct lockspace *ls, struct resource *r)
-{
- struct lock_waiter *w, *safe;
- struct dlm_plock_info *in;
- int rv;
-
- list_for_each_entry_safe(w, safe, &r->waiters, list) {
- in = &w->info;
-
- if (is_conflict(r, in, 0))
- continue;
-
- list_del(&w->list);
-
- /*
- log_group(ls, "take waiter %llx %llx-%llx %d/%u/%llx",
- in->number, in->start, in->end,
- in->nodeid, in->pid, in->owner);
- */
-
- rv = lock_internal(ls, r, in);
-
- if (in->nodeid == our_nodeid)
- write_result(ls, in, rv);
-
- free(w);
- }
-}
-
-static void do_lock(struct lockspace *ls, struct dlm_plock_info *in,
- struct resource *r)
-{
- int rv;
-
- if (is_conflict(r, in, 0)) {
- if (!in->wait)
- rv = -EAGAIN;
- else {
- rv = add_waiter(ls, r, in);
- if (rv)
- goto out;
- rv = -EINPROGRESS;
- }
- } else
- rv = lock_internal(ls, r, in);
-
- out:
- if (in->nodeid == our_nodeid && rv != -EINPROGRESS)
- write_result(ls, in, rv);
-
- do_waiters(ls, r);
- put_resource(r);
-}
-
-static void do_unlock(struct lockspace *ls, struct dlm_plock_info *in,
- struct resource *r)
-{
- int rv;
-
- rv = unlock_internal(ls, r, in);
-
-#ifdef DLM_PLOCK_BUILD_WORKAROUND
- if (in->pad & DLM_PLOCK_FL_CLOSE) {
-#else
- if (in->flags & DLM_PLOCK_FL_CLOSE) {
-#endif
- clear_waiters(ls, r, in);
- /* no replies for unlock-close ops */
- goto skip_result;
- }
-
- if (in->nodeid == our_nodeid)
- write_result(ls, in, rv);
-
- skip_result:
- do_waiters(ls, r);
- put_resource(r);
-}
-
-/* we don't even get to this function if the getlk isn't from us */
-
-static void do_get(struct lockspace *ls, struct dlm_plock_info *in,
- struct resource *r)
-{
- int rv;
-
- if (is_conflict(r, in, 1))
- rv = 1;
- else
- rv = 0;
-
- write_result(ls, in, rv);
- put_resource(r);
-}
-
-static void save_message(struct lockspace *ls, struct dlm_header *hd, int len,
- int from, int type)
-{
- struct save_msg *sm;
-
- sm = malloc(sizeof(struct save_msg) + len);
- if (!sm)
- return;
- memset(sm, 0, sizeof(struct save_msg) + len);
-
- memcpy(&sm->buf, hd, len);
- sm->type = type;
- sm->len = len;
- sm->nodeid = from;
-
- log_plock(ls, "save %s from %d len %d", msg_name(type), from, len);
-
- list_add_tail(&sm->list, &ls->saved_messages);
-}
-
-static void __receive_plock(struct lockspace *ls, struct dlm_plock_info *in,
- int from, struct resource *r)
-{
- switch (in->optype) {
- case DLM_PLOCK_OP_LOCK:
- ls->last_plock_time = time(NULL);
- do_lock(ls, in, r);
- break;
- case DLM_PLOCK_OP_UNLOCK:
- ls->last_plock_time = time(NULL);
- do_unlock(ls, in, r);
- break;
- case DLM_PLOCK_OP_GET:
- do_get(ls, in, r);
- break;
- default:
- log_plock_error(ls, "receive_plock error from %d optype %d",
- from, in->optype);
- if (from == our_nodeid)
- write_result(ls, in, -EINVAL);
- }
-}
-
-/* When ls members receive our options message (for our mount), one of them
- saves all plock state received to that point in a checkpoint and then sends
- us our journals message. We know to retrieve the plock state from the
- checkpoint when we receive our journals message. Any plocks messages that
- arrive between seeing our options message and our journals message needs to
- be saved and processed after we synchronize our plock state from the
- checkpoint. Any plock message received while we're mounting but before we
- set save_plocks (when we see our options message) can be ignored because it
- should be reflected in the checkpointed state. */
-
-static void _receive_plock(struct lockspace *ls, struct dlm_header *hd, int len)
-{
- struct dlm_plock_info info;
- struct resource *r = NULL;
- struct timeval now;
- uint64_t usec;
- int from = hd->nodeid;
- int rv, create;
-
- memcpy(&info, (char *)hd + sizeof(struct dlm_header), sizeof(info));
- info_bswap_in(&info);
-
- log_plock(ls, "receive plock %llx %s %s %llx-%llx %d/%u/%llx w %d",
- (unsigned long long)info.number,
- op_str(info.optype),
- ex_str(info.optype, info.ex),
- (unsigned long long)info.start, (unsigned long long)info.end,
- info.nodeid, info.pid, (unsigned long long)info.owner,
- info.wait);
-
- plock_recv_count++;
- if (!(plock_recv_count % 1000)) {
- gettimeofday(&now, NULL);
- usec = dt_usec(&plock_recv_time, &now);
- log_plock(ls, "plock_recv_count %u time %.3f s",
- plock_recv_count, usec * 1.e-6);
- plock_recv_time = now;
- }
-
- if (info.optype == DLM_PLOCK_OP_GET && from != our_nodeid)
- return;
-
- if (from != hd->nodeid || from != info.nodeid) {
- log_plock_error(ls, "receive_plock error from %d header %d info %d",
- from, hd->nodeid, info.nodeid);
- return;
- }
-
- create = !cfgd_plock_ownership;
-
- rv = find_resource(ls, info.number, create, &r);
-
- if (rv && cfgd_plock_ownership) {
- /* There must have been a race with a drop, so we need to
- ignore this plock op which will be resent. If we're the one
- who sent the plock, we need to send_own() and put it on the
- pending list to resend once the owner is established. */
-
- log_plock(ls, "receive_plock from %d no r %llx", from,
- (unsigned long long)info.number);
-
- if (from != our_nodeid)
- return;
-
- rv = find_resource(ls, info.number, 1, &r);
- if (rv)
- return;
- send_own(ls, r, our_nodeid);
- save_pending_plock(ls, r, &info);
- return;
- }
- if (rv) {
- /* r not found, rv is -ENOENT, this shouldn't happen because
- process_plocks() creates a resource for every op */
-
- log_plock_error(ls, "receive_plock error from %d no r %llx %d",
- from, (unsigned long long)info.number, rv);
- return;
- }
-
- /* The owner should almost always be 0 here, but other owners may
- be possible given odd combinations of races with drop. Odd races to
- worry about (some seem pretty improbable):
-
- - A sends drop, B sends plock, receive drop, receive plock.
- This is addressed above.
-
- - A sends drop, B sends plock, receive drop, B reads plock
- and sends own, receive plock, on B we find owner of -1.
-
- - A sends drop, B sends two plocks, receive drop, receive plocks.
- Receiving the first plock is the previous case, receiving the
- second plock will find r with owner of -1.
-
- - A sends drop, B sends two plocks, receive drop, C sends own,
- receive plock, B sends own, receive own (C), receive plock,
- receive own (B).
-
- Haven't tried to cook up a scenario that would lead to the
- last case below; receiving a plock from ourself and finding
- we're the owner of r. */
-
- if (!r->owner) {
- __receive_plock(ls, &info, from, r);
-
- } else if (r->owner == -1) {
- log_plock(ls, "receive_plock from %d r %llx owner %d", from,
- (unsigned long long)info.number, r->owner);
-
- if (from == our_nodeid)
- save_pending_plock(ls, r, &info);
-
- } else if (r->owner != our_nodeid) {
- log_plock(ls, "receive_plock from %d r %llx owner %d", from,
- (unsigned long long)info.number, r->owner);
-
- if (from == our_nodeid)
- save_pending_plock(ls, r, &info);
-
- } else if (r->owner == our_nodeid) {
- log_plock(ls, "receive_plock from %d r %llx owner %d", from,
- (unsigned long long)info.number, r->owner);
-
- if (from == our_nodeid)
- __receive_plock(ls, &info, from, r);
- }
-}
-
-void receive_plock(struct lockspace *ls, struct dlm_header *hd, int len)
-{
- if (ls->save_plocks) {
- save_message(ls, hd, len, hd->nodeid, DLM_MSG_PLOCK);
- return;
- }
-
- _receive_plock(ls, hd, len);
-}
-
-static int send_struct_info(struct lockspace *ls, struct dlm_plock_info *in,
- int msg_type)
-{
- struct dlm_header *hd;
- int rv = 0, len;
- char *buf;
-
- len = sizeof(struct dlm_header) + sizeof(struct dlm_plock_info);
- buf = malloc(len);
- if (!buf) {
- rv = -ENOMEM;
- goto out;
- }
- memset(buf, 0, len);
-
- info_bswap_out(in);
-
- hd = (struct dlm_header *)buf;
- hd->type = msg_type;
-
- memcpy(buf + sizeof(struct dlm_header), in, sizeof(*in));
-
- dlm_send_message(ls, buf, len);
-
- free(buf);
- out:
- if (rv)
- log_plock_error(ls, "send_struct_info error %d", rv);
- return rv;
-}
-
-static void send_plock(struct lockspace *ls, struct resource *r,
- struct dlm_plock_info *in)
-{
- send_struct_info(ls, in, DLM_MSG_PLOCK);
-}
-
-static void send_own(struct lockspace *ls, struct resource *r, int owner)
-{
- struct dlm_plock_info info;
-
- /* if we've already sent an own message for this resource,
- (pending list is not empty), then we shouldn't send another */
-
- if (!list_empty(&r->pending)) {
- log_plock(ls, "send_own %llx already pending",
- (unsigned long long)r->number);
- return;
- }
-
- if (!owner)
- r->flags |= R_SEND_UNOWN;
- else
- r->flags |= R_SEND_OWN;
-
- memset(&info, 0, sizeof(info));
- info.number = r->number;
- info.nodeid = owner;
-
- send_struct_info(ls, &info, DLM_MSG_PLOCK_OWN);
-}
-
-static void send_syncs(struct lockspace *ls, struct resource *r)
-{
- struct dlm_plock_info info;
- struct posix_lock *po;
- struct lock_waiter *w;
- int rv;
-
- list_for_each_entry(po, &r->locks, list) {
- memset(&info, 0, sizeof(info));
- info.number = r->number;
- info.start = po->start;
- info.end = po->end;
- info.nodeid = po->nodeid;
- info.owner = po->owner;
- info.pid = po->pid;
- info.ex = po->ex;
-
- rv = send_struct_info(ls, &info, DLM_MSG_PLOCK_SYNC_LOCK);
- if (rv)
- goto out;
-
- po->flags |= P_SYNCING;
- }
-
- list_for_each_entry(w, &r->waiters, list) {
- memcpy(&info, &w->info, sizeof(info));
-
- rv = send_struct_info(ls, &info, DLM_MSG_PLOCK_SYNC_WAITER);
- if (rv)
- goto out;
-
- w->flags |= P_SYNCING;
- }
- out:
- return;
-}
-
-static void send_drop(struct lockspace *ls, struct resource *r)
-{
- struct dlm_plock_info info;
-
- memset(&info, 0, sizeof(info));
- info.number = r->number;
- r->flags |= R_SEND_DROP;
-
- send_struct_info(ls, &info, DLM_MSG_PLOCK_DROP);
-}
-
-/* plock op can't be handled until we know the owner value of the resource,
- so the op is saved on the pending list until the r owner is established */
-
-static void save_pending_plock(struct lockspace *ls, struct resource *r,
- struct dlm_plock_info *in)
-{
- struct lock_waiter *w;
-
- w = malloc(sizeof(struct lock_waiter));
- if (!w) {
- log_plock_error(ls, "save_pending_plock no mem");
- return;
- }
- memcpy(&w->info, in, sizeof(struct dlm_plock_info));
- list_add_tail(&w->list, &r->pending);
-}
-
-/* plock ops are on pending list waiting for ownership to be established.
- owner has now become us, so add these plocks to r */
-
-static void add_pending_plocks(struct lockspace *ls, struct resource *r)
-{
- struct lock_waiter *w, *safe;
-
- list_for_each_entry_safe(w, safe, &r->pending, list) {
- __receive_plock(ls, &w->info, our_nodeid, r);
- list_del(&w->list);
- free(w);
- }
-}
-
-/* plock ops are on pending list waiting for ownership to be established.
- owner has now become 0, so send these plocks to everyone */
-
-static void send_pending_plocks(struct lockspace *ls, struct resource *r)
-{
- struct lock_waiter *w, *safe;
-
- list_for_each_entry_safe(w, safe, &r->pending, list) {
- send_plock(ls, r, &w->info);
- list_del(&w->list);
- free(w);
- }
-}
-
-static void _receive_own(struct lockspace *ls, struct dlm_header *hd, int len)
-{
- struct dlm_plock_info info;
- struct resource *r;
- int should_not_happen = 0;
- int from = hd->nodeid;
- int rv;
-
- ls->last_plock_time = time(NULL);
-
- memcpy(&info, (char *)hd + sizeof(struct dlm_header), sizeof(info));
- info_bswap_in(&info);
-
- log_plock(ls, "receive_own %llx from %u owner %u",
- (unsigned long long)info.number, hd->nodeid, info.nodeid);
-
- rv = find_resource(ls, info.number, 1, &r);
- if (rv)
- return;
-
- if (from == our_nodeid) {
- /*
- * received our own own message
- */
-
- if (info.nodeid == 0) {
- /* we are setting owner to 0 */
-
- if (r->owner == our_nodeid) {
- /* we set owner to 0 when we relinquish
- ownership */
- should_not_happen = 1;
- } else if (r->owner == 0) {
- /* this happens when we relinquish ownership */
- r->flags |= R_GOT_UNOWN;
- } else {
- should_not_happen = 1;
- }
-
- } else if (info.nodeid == our_nodeid) {
- /* we are setting owner to ourself */
-
- if (r->owner == -1) {
- /* we have gained ownership */
- r->owner = our_nodeid;
- add_pending_plocks(ls, r);
- } else if (r->owner == our_nodeid) {
- should_not_happen = 1;
- } else if (r->owner == 0) {
- send_pending_plocks(ls, r);
- } else {
- /* resource is owned by other node;
- they should set owner to 0 shortly */
- }
-
- } else {
- /* we should only ever set owner to 0 or ourself */
- should_not_happen = 1;
- }
- } else {
- /*
- * received own message from another node
- */
-
- if (info.nodeid == 0) {
- /* other node is setting owner to 0 */
-
- if (r->owner == -1) {
- /* we should have a record of the owner before
- it relinquishes */
- should_not_happen = 1;
- } else if (r->owner == our_nodeid) {
- /* only the owner should relinquish */
- should_not_happen = 1;
- } else if (r->owner == 0) {
- should_not_happen = 1;
- } else {
- r->owner = 0;
- r->flags |= R_GOT_UNOWN;
- send_pending_plocks(ls, r);
- }
-
- } else if (info.nodeid == from) {
- /* other node is setting owner to itself */
-
- if (r->owner == -1) {
- /* normal path for a node becoming owner */
- r->owner = from;
- } else if (r->owner == our_nodeid) {
- /* we relinquish our ownership: sync our local
- plocks to everyone, then set owner to 0 */
- send_syncs(ls, r);
- send_own(ls, r, 0);
- /* we need to set owner to 0 here because
- local ops may arrive before we receive
- our send_own message and can't be added
- locally */
- r->owner = 0;
- } else if (r->owner == 0) {
- /* can happen because we set owner to 0 before
- we receive our send_own sent just above */
- } else {
- /* do nothing, current owner should be
- relinquishing its ownership */
- }
-
- } else if (info.nodeid == our_nodeid) {
- /* no one else should try to set the owner to us */
- should_not_happen = 1;
- } else {
- /* a node should only ever set owner to 0 or itself */
- should_not_happen = 1;
- }
- }
-
- if (should_not_happen) {
- log_plock_error(ls, "receive_own error from %u %llx "
- "info nodeid %d r owner %d",
- from, (unsigned long long)r->number,
- info.nodeid, r->owner);
- }
-}
-
-void receive_own(struct lockspace *ls, struct dlm_header *hd, int len)
-{
- if (ls->save_plocks) {
- save_message(ls, hd, len, hd->nodeid, DLM_MSG_PLOCK_OWN);
- return;
- }
-
- _receive_own(ls, hd, len);
-}
-
-static void clear_syncing_flag(struct lockspace *ls, struct resource *r,
- struct dlm_plock_info *in)
-{
- struct posix_lock *po;
- struct lock_waiter *w;
-
- list_for_each_entry(po, &r->locks, list) {
- if ((po->flags & P_SYNCING) &&
- in->start == po->start &&
- in->end == po->end &&
- in->nodeid == po->nodeid &&
- in->owner == po->owner &&
- in->pid == po->pid &&
- in->ex == po->ex) {
- po->flags &= ~P_SYNCING;
- return;
- }
- }
-
- list_for_each_entry(w, &r->waiters, list) {
- if ((w->flags & P_SYNCING) &&
- in->start == w->info.start &&
- in->end == w->info.end &&
- in->nodeid == w->info.nodeid &&
- in->owner == w->info.owner &&
- in->pid == w->info.pid &&
- in->ex == w->info.ex) {
- w->flags &= ~P_SYNCING;
- return;
- }
- }
-
- log_plock_error(ls, "clear_syncing error %llx no match %s %llx-%llx "
- "%d/%u/%llx",
- (unsigned long long)r->number,
- in->ex ? "WR" : "RD",
- (unsigned long long)in->start,
- (unsigned long long)in->end,
- in->nodeid, in->pid,
- (unsigned long long)in->owner);
-}
-
-static void _receive_sync(struct lockspace *ls, struct dlm_header *hd, int len)
-{
- struct dlm_plock_info info;
- struct resource *r;
- int from = hd->nodeid;
- int rv;
-
- ls->last_plock_time = time(NULL);
-
- memcpy(&info, (char *)hd + sizeof(struct dlm_header), sizeof(info));
- info_bswap_in(&info);
-
- log_plock(ls, "receive sync %llx from %u %s %llx-%llx %d/%u/%llx",
- (unsigned long long)info.number, from, info.ex ? "WR" : "RD",
- (unsigned long long)info.start, (unsigned long long)info.end,
- info.nodeid, info.pid, (unsigned long long)info.owner);
-
- rv = find_resource(ls, info.number, 0, &r);
- if (rv) {
- log_plock_error(ls, "receive_sync error no r %llx from %d",
- info.number, from);
- return;
- }
-
- if (from == our_nodeid) {
- /* this plock now in sync on all nodes */
- clear_syncing_flag(ls, r, &info);
- return;
- }
-
- if (hd->type == DLM_MSG_PLOCK_SYNC_LOCK)
- add_lock(r, info.nodeid, info.owner, info.pid, info.ex,
- info.start, info.end);
- else if (hd->type == DLM_MSG_PLOCK_SYNC_WAITER)
- add_waiter(ls, r, &info);
-}
-
-void receive_sync(struct lockspace *ls, struct dlm_header *hd, int len)
-{
- if (ls->save_plocks) {
- save_message(ls, hd, len, hd->nodeid, hd->type);
- return;
- }
-
- _receive_sync(ls, hd, len);
-}
-
-static void _receive_drop(struct lockspace *ls, struct dlm_header *hd, int len)
-{
- struct dlm_plock_info info;
- struct resource *r;
- int from = hd->nodeid;
- int rv;
-
- ls->last_plock_time = time(NULL);
-
- memcpy(&info, (char *)hd + sizeof(struct dlm_header), sizeof(info));
- info_bswap_in(&info);
-
- log_plock(ls, "receive_drop %llx from %u",
- (unsigned long long)info.number, from);
-
- rv = find_resource(ls, info.number, 0, &r);
- if (rv) {
- /* we'll find no r if two nodes sent drop at once */
- log_plock(ls, "receive_drop from %d no r %llx", from,
- (unsigned long long)info.number);
- return;
- }
-
- if (r->owner != 0) {
- /* - A sent drop, B sent drop, receive drop A, C sent own,
- receive drop B (this warning on C, owner -1)
- - A sent drop, B sent drop, receive drop A, A sent own,
- receive own A, receive drop B (this warning on all,
- owner A) */
- log_plock(ls, "receive_drop from %d r %llx owner %d", from,
- (unsigned long long)r->number, r->owner);
- return;
- }
-
- if (!list_empty(&r->pending)) {
- /* shouldn't happen */
- log_plock_error(ls, "receive_drop error from %d r %llx pending op",
- from, (unsigned long long)r->number);
- return;
- }
-
- /* the decision to drop or not must be based on things that are
- guaranteed to be the same on all nodes */
-
- if (list_empty(&r->locks) && list_empty(&r->waiters)) {
- list_del(&r->list);
- free(r);
- } else {
- /* A sent drop, B sent a plock, receive plock, receive drop */
- log_plock(ls, "receive_drop from %d r %llx in use", from,
- (unsigned long long)r->number);
- }
-}
-
-void receive_drop(struct lockspace *ls, struct dlm_header *hd, int len)
-{
- if (ls->save_plocks) {
- save_message(ls, hd, len, hd->nodeid, DLM_MSG_PLOCK_DROP);
- return;
- }
-
- _receive_drop(ls, hd, len);
-}
-
-/* We only drop resources from the unowned state to simplify things.
- If we want to drop a resource we own, we unown/relinquish it first. */
-
-/* FIXME: in the transition from owner = us, to owner = 0, to drop;
- we want the second period to be shorter than the first */
-
-static int drop_resources(struct lockspace *ls)
-{
- struct resource *r;
- struct timeval now;
- int count = 0;
-
- if (!cfgd_plock_ownership)
- return 0;
-
- if (list_empty(&ls->plock_resources))
- return 0;
-
- gettimeofday(&now, NULL);
-
- if (time_diff_ms(&ls->drop_resources_last, &now) <
- cfgd_drop_resources_time)
- return 1;
-
- ls->drop_resources_last = now;
-
- /* try to drop the oldest, unused resources */
-
- list_for_each_entry_reverse(r, &ls->plock_resources, list) {
- if (count >= cfgd_drop_resources_count)
- break;
- if (r->owner && r->owner != our_nodeid)
- continue;
- if (time_diff_ms(&r->last_access, &now) <
- cfgd_drop_resources_age)
- continue;
-
- if (list_empty(&r->locks) && list_empty(&r->waiters)) {
- if (r->owner == our_nodeid) {
- send_own(ls, r, 0);
- r->owner = 0;
- } else if (r->owner == 0 && got_unown(r)) {
- send_drop(ls, r);
- }
-
- count++;
- }
- }
-
- return 1;
-}
-
-void drop_resources_all(void)
-{
- struct lockspace *ls;
- int rv = 0;
-
- poll_drop_plock = 0;
-
- list_for_each_entry(ls, &lockspaces, list) {
- rv = drop_resources(ls);
- if (rv)
- poll_drop_plock = 1;
- }
-}
-
-int limit_plocks(void)
-{
- struct timeval now;
-
- /* Don't send more messages while the cpg message queue is backed up */
-
- if (message_flow_control_on) {
- update_flow_control_status();
- if (message_flow_control_on)
- return 1;
- }
-
- if (!cfgd_plock_rate_limit || !plock_read_count)
- return 0;
-
- gettimeofday(&now, NULL);
-
- /* Every time a plock op is read from the kernel, we increment
- plock_read_count. After every cfgd_plock_rate_limit (N) reads,
- we check the time it's taken to do those N; if the time is less than
- a second, then we delay reading any more until a second is up.
- This way we read a max of N ops from the kernel every second. */
-
- if (!(plock_read_count % cfgd_plock_rate_limit)) {
- if (time_diff_ms(&plock_rate_last, &now) < 1000) {
- plock_rate_delays++;
- return 2;
- }
- plock_rate_last = now;
- plock_read_count++;
- }
- return 0;
-}
-
-void process_plocks(int ci)
-{
- struct lockspace *ls;
- struct resource *r;
- struct dlm_plock_info info;
- struct timeval now;
- uint64_t usec;
- int create, rv;
-
- if (limit_plocks()) {
- poll_ignore_plock = 1;
- client_ignore(plock_ci, plock_fd);
- return;
- }
-
- gettimeofday(&now, NULL);
-
- memset(&info, 0, sizeof(info));
-
- rv = do_read(plock_device_fd, &info, sizeof(info));
- if (rv < 0) {
- log_debug("process_plocks: read error %d fd %d\n",
- errno, plock_device_fd);
- return;
- }
-
- /* kernel doesn't set the nodeid field */
- info.nodeid = our_nodeid;
-
- if (!cfgd_enable_plock) {
- rv = -ENOSYS;
- goto fail;
- }
-
- if (need_fsid_translation)
- info.fsid = mg_to_ls_id(info.fsid);
-
- ls = find_ls_id(info.fsid);
- if (!ls) {
- log_plock(ls, "process_plocks: no ls id %x", info.fsid);
- rv = -EEXIST;
- goto fail;
- }
-
- if (ls->disable_plock) {
- rv = -ENOSYS;
- goto fail;
- }
-
- log_plock(ls, "read plock %llx %s %s %llx-%llx %d/%u/%llx w %d",
- (unsigned long long)info.number,
- op_str(info.optype),
- ex_str(info.optype, info.ex),
- (unsigned long long)info.start, (unsigned long long)info.end,
- info.nodeid, info.pid, (unsigned long long)info.owner,
- info.wait);
-
- /* report plock rate and any delays since the last report */
- plock_read_count++;
- if (!(plock_read_count % 1000)) {
- usec = dt_usec(&plock_read_time, &now) ;
- log_plock(ls, "plock_read_count %u time %.3f s delays %u",
- plock_read_count, usec * 1.e-6, plock_rate_delays);
- plock_read_time = now;
- plock_rate_delays = 0;
- }
-
- create = (info.optype == DLM_PLOCK_OP_UNLOCK) ? 0 : 1;
-
- rv = find_resource(ls, info.number, create, &r);
- if (rv)
- goto fail;
-
- if (r->owner == 0) {
- /* plock state replicated on all nodes */
- send_plock(ls, r, &info);
-
- } else if (r->owner == our_nodeid) {
- /* we are the owner of r, so our plocks are local */
- __receive_plock(ls, &info, our_nodeid, r);
-
- } else {
- /* r owner is -1: r is new, try to become the owner;
- r owner > 0: tell other owner to give up ownership;
- both done with a message trying to set owner to ourself */
- send_own(ls, r, our_nodeid);
- save_pending_plock(ls, r, &info);
- }
-
- if (cfgd_plock_ownership && !list_empty(&ls->plock_resources))
- poll_drop_plock = 1;
- return;
-
- fail:
-#ifdef DLM_PLOCK_BUILD_WORKAROUND
- if (!(info.pad & DLM_PLOCK_FL_CLOSE)) {
-#else
- if (!(info.flags & DLM_PLOCK_FL_CLOSE)) {
-#endif
- info.rv = rv;
- rv = write(plock_device_fd, &info, sizeof(info));
- }
-}
-
-void process_saved_plocks(struct lockspace *ls)
-{
- struct save_msg *sm, *sm2;
- struct dlm_header *hd;
- int count = 0;
-
- log_plock(ls, "process_saved_plocks begin");
-
- if (list_empty(&ls->saved_messages))
- goto out;
-
- list_for_each_entry_safe(sm, sm2, &ls->saved_messages, list) {
- hd = (struct dlm_header *)sm->buf;
-
- switch (sm->type) {
- case DLM_MSG_PLOCK:
- _receive_plock(ls, hd, sm->len);
- break;
- case DLM_MSG_PLOCK_OWN:
- _receive_own(ls, hd, sm->len);
- break;
- case DLM_MSG_PLOCK_DROP:
- _receive_drop(ls, hd, sm->len);
- break;
- case DLM_MSG_PLOCK_SYNC_LOCK:
- case DLM_MSG_PLOCK_SYNC_WAITER:
- _receive_sync(ls, hd, sm->len);
- break;
- default:
- continue;
- }
-
- list_del(&sm->list);
- free(sm);
- count++;
- }
- out:
- log_plock(ls, "process_saved_plocks %d end", count);
-}
-
-/* locks still marked SYNCING should not go into the ckpt; the new node
- will get those locks by receiving PLOCK_SYNC messages */
-
-static void pack_section_buf(struct lockspace *ls, struct resource *r,
- int owner)
-{
- struct pack_plock *pp;
- struct posix_lock *po;
- struct lock_waiter *w;
- int count = 0;
-
- /* plocks on owned resources are not replicated on other nodes;
- N.B. owner not always equal to r->owner */
-
- if (cfgd_plock_ownership && (owner == our_nodeid))
- return;
-
- pp = (struct pack_plock *) §ion_buf;
-
- list_for_each_entry(po, &r->locks, list) {
- if (po->flags & P_SYNCING)
- continue;
- pp->start = cpu_to_le64(po->start);
- pp->end = cpu_to_le64(po->end);
- pp->owner = cpu_to_le64(po->owner);
- pp->pid = cpu_to_le32(po->pid);
- pp->nodeid = cpu_to_le32(po->nodeid);
- pp->ex = po->ex;
- pp->waiter = 0;
- pp++;
- count++;
- }
-
- list_for_each_entry(w, &r->waiters, list) {
- if (w->flags & P_SYNCING)
- continue;
- pp->start = cpu_to_le64(w->info.start);
- pp->end = cpu_to_le64(w->info.end);
- pp->owner = cpu_to_le64(w->info.owner);
- pp->pid = cpu_to_le32(w->info.pid);
- pp->nodeid = cpu_to_le32(w->info.nodeid);
- pp->ex = w->info.ex;
- pp->waiter = 1;
- pp++;
- count++;
- }
-
- section_len = count * sizeof(struct pack_plock);
-}
-
-static int unpack_section_buf(struct lockspace *ls, char *numbuf, int buflen,
- uint64_t *r_num, int *lock_count)
-{
- struct pack_plock *pp;
- struct posix_lock *po;
- struct lock_waiter *w;
- struct resource *r;
- int count = section_len / sizeof(struct pack_plock);
- int i, owner = 0;
- unsigned long long num;
- struct timeval now;
-
- gettimeofday(&now, NULL);
-
- sscanf(numbuf, "r%llu.%d", &num, &owner);
-
-#if 0
- /* would be nice to always compile this, but it adds a lot of time */
- r = search_resource(ls, num);
- if (r) {
- log_error("unpack %llu duplicate", num);
- return -1;
- }
-#endif
-
- r = malloc(sizeof(struct resource));
- if (!r)
- return -ENOMEM;
- memset(r, 0, sizeof(struct resource));
- INIT_LIST_HEAD(&r->locks);
- INIT_LIST_HEAD(&r->waiters);
- INIT_LIST_HEAD(&r->pending);
-
- if (!cfgd_plock_ownership) {
- if (owner) {
- log_error("unpack %llu bad owner %d count %d",
- (unsigned long long)num, owner, count);
- free(r);
- return -1;
- }
- } else {
- if (!owner)
- r->flags |= R_GOT_UNOWN;
-
- /* no locks should be included for owned resources */
-
- if (owner && count) {
- log_error("unpack %llu owner %d bad count %d",
- (unsigned long long)num, owner, count);
- free(r);
- return -1;
- }
- }
-
- r->number = num;
- r->owner = owner;
- r->last_access = now;
-
- *r_num = num;
-
- pp = (struct pack_plock *) §ion_buf;
-
- for (i = 0; i < count; i++) {
- if (!pp->waiter) {
- po = malloc(sizeof(struct posix_lock));
- if (!po)
- return -ENOMEM;
- po->start = le64_to_cpu(pp->start);
- po->end = le64_to_cpu(pp->end);
- po->owner = le64_to_cpu(pp->owner);
- po->pid = le32_to_cpu(pp->pid);
- po->nodeid = le32_to_cpu(pp->nodeid);
- po->ex = pp->ex;
- list_add_tail(&po->list, &r->locks);
- } else {
- w = malloc(sizeof(struct lock_waiter));
- if (!w)
- return -ENOMEM;
- w->info.start = le64_to_cpu(pp->start);
- w->info.end = le64_to_cpu(pp->end);
- w->info.owner = le64_to_cpu(pp->owner);
- w->info.pid = le32_to_cpu(pp->pid);
- w->info.nodeid = le32_to_cpu(pp->nodeid);
- w->info.ex = pp->ex;
- list_add_tail(&w->list, &r->waiters);
- }
- pp++;
- }
-
- list_add_tail(&r->list, &ls->plock_resources);
- *lock_count = count;
- return 0;
-}
-
-/* If we are the new ckpt_node, we'll be unlinking a ckpt that we don't
- have open, which was created by the previous ckpt_node. The previous
- ckpt_node should have closed the ckpt in set_plock_ckpt_node() so it
- will go away when we unlink it here. */
-
-static int _unlink_checkpoint(struct lockspace *ls, SaNameT *name)
-{
- SaCkptCheckpointHandleT h;
- SaCkptCheckpointDescriptorT s;
- SaAisErrorT rv;
- int ret = 0;
-
- h = (SaCkptCheckpointHandleT) ls->plock_ckpt_handle;
- log_group(ls, "unlink ckpt %llx", (unsigned long long)h);
-
- unlink_retry:
- rv = saCkptCheckpointUnlink(system_ckpt_handle, name);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "unlink ckpt retry");
- sleep(1);
- goto unlink_retry;
- }
- if (rv == SA_AIS_OK)
- goto out_close;
-
- log_group(ls, "unlink ckpt error %d %s", rv, ls->name);
- ret = -1;
-
- status_retry:
- rv = saCkptCheckpointStatusGet(h, &s);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "unlink ckpt status retry");
- sleep(1);
- goto status_retry;
- }
- if (rv != SA_AIS_OK) {
- log_group(ls, "unlink ckpt status error %d %s", rv, ls->name);
- goto out_close;
- }
-
- log_group(ls, "unlink ckpt status: size %llu, max sections %u, "
- "max section size %llu, section count %u, mem %u",
- (unsigned long long)s.checkpointCreationAttributes.checkpointSize,
- s.checkpointCreationAttributes.maxSections,
- (unsigned long long)s.checkpointCreationAttributes.maxSectionSize,
- s.numberOfSections, s.memoryUsed);
-
- out_close:
- if (!h)
- goto out;
-
- rv = saCkptCheckpointClose(h);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "unlink ckpt close retry");
- sleep(1);
- goto out_close;
- }
- if (rv != SA_AIS_OK) {
- log_error("unlink ckpt %llx close err %d %s",
- (unsigned long long)h, rv, ls->name);
- /* should we return an error here and possibly cause
- store_plocks() to fail on this? */
- /* ret = -1; */
- }
- out:
- ls->plock_ckpt_handle = 0;
- return ret;
-}
-
-void close_plock_checkpoint(struct lockspace *ls)
-{
- SaCkptCheckpointHandleT h;
- SaAisErrorT rv;
-
- h = (SaCkptCheckpointHandleT) ls->plock_ckpt_handle;
- if (!h)
- return;
- retry:
- rv = saCkptCheckpointClose(h);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "close_plock_checkpoint retry");
- sleep(1);
- goto retry;
- }
- if (rv != SA_AIS_OK) {
- log_error("close_plock_checkpoint %llx err %d %s",
- (unsigned long long)h, rv, ls->name);
- }
-
- ls->plock_ckpt_handle = 0;
-}
-
-/*
- * section id is r<inodenum>.<owner>, the maximum string length is:
- * "r" prefix = 1 strlen("r")
- * max uint64 = 20 strlen("18446744073709551615")
- * "." before owner = 1 strlen(".")
- * max int = 11 strlen("-2147483647")
- * \0 at end = 1
- * ---------------------
- * 34 SECTION_NAME_LEN
- */
-
-#define SECTION_NAME_LEN 34
-
-/* Copy all plock state into a checkpoint so new node can retrieve it. The
- node creating the ckpt for the mounter needs to be the same node that's
- sending the mounter its journals message (i.e. the low nodeid). The new
- mounter knows the ckpt is ready to read only after it gets its journals
- message.
-
- If the mounter is becoming the new low nodeid in the group, the node doing
- the store closes the ckpt and the new node unlinks the ckpt after reading
- it. The ckpt should then disappear and the new node can create a new ckpt
- for the next mounter. */
-
-void store_plocks(struct lockspace *ls, uint32_t *sig)
-{
- SaCkptCheckpointCreationAttributesT attr;
- SaCkptCheckpointHandleT h;
- SaCkptSectionIdT section_id;
- SaCkptSectionCreationAttributesT section_attr;
- SaCkptCheckpointOpenFlagsT flags;
- SaNameT name;
- SaAisErrorT rv;
- char buf[SECTION_NAME_LEN];
- struct resource *r;
- struct posix_lock *po;
- struct lock_waiter *w;
- int total_size, section_size, max_section_size;
- int len, owner;
- uint32_t r_count = 0, p_count = 0;
- uint64_t r_num_first = 0, r_num_last = 0;
-
- if (!cfgd_enable_plock || ls->disable_plock)
- return;
-
- /* no change to plock state since we created the last checkpoint */
- if (ls->last_checkpoint_time > ls->last_plock_time) {
- log_group(ls, "store_plocks saved ckpt uptodate");
- r_num_first = ls->checkpoint_r_num_first;
- r_num_last = ls->checkpoint_r_num_last;
- r_count = ls->checkpoint_r_count;
- p_count = ls->checkpoint_p_count;
- goto out;
- }
- ls->last_checkpoint_time = time(NULL);
-
- len = snprintf((char *)name.value, SA_MAX_NAME_LENGTH, "dlmplock.%s",
- ls->name);
- name.length = len;
-
- _unlink_checkpoint(ls, &name);
-
- /* loop through all plocks to figure out sizes to set in
- the attr fields */
-
- r_count = 0;
- p_count = 0;
- total_size = 0;
- max_section_size = 0;
-
- list_for_each_entry(r, &ls->plock_resources, list) {
- if (r->owner == -1)
- continue;
-
- r_count++;
- section_size = 0;
- list_for_each_entry(po, &r->locks, list) {
- section_size += sizeof(struct pack_plock);
- p_count++;
- }
- list_for_each_entry(w, &r->waiters, list) {
- section_size += sizeof(struct pack_plock);
- p_count++;
- }
- total_size += section_size;
- if (section_size > max_section_size)
- max_section_size = section_size;
- }
-
- log_group(ls, "store_plocks r_count %u p_count %u "
- "total_size %d max_section_size %d",
- r_count, p_count, total_size, max_section_size);
- log_plock(ls, "store_plocks r_count %u p_count %u "
- "total_size %d max_section_size %d",
- r_count, p_count, total_size, max_section_size);
-
- attr.creationFlags = SA_CKPT_WR_ALL_REPLICAS;
- attr.checkpointSize = total_size;
- attr.retentionDuration = SA_TIME_MAX;
- attr.maxSections = r_count + 1; /* don't know why we need +1 */
- attr.maxSectionSize = max_section_size;
- attr.maxSectionIdSize = SECTION_NAME_LEN;
-
- flags = SA_CKPT_CHECKPOINT_READ |
- SA_CKPT_CHECKPOINT_WRITE |
- SA_CKPT_CHECKPOINT_CREATE;
-
- open_retry:
- rv = saCkptCheckpointOpen(system_ckpt_handle, &name,&attr,flags,0,&h);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "store_plocks ckpt open retry");
- sleep(1);
- goto open_retry;
- }
- if (rv != SA_AIS_OK) {
- log_error("store_plocks ckpt open error %d %s", rv, ls->name);
- goto fail;
- }
-
- log_group(ls, "store_plocks open ckpt handle %llx",
- (unsigned long long)h);
- ls->plock_ckpt_handle = (uint64_t) h;
-
- /* - If r owner is -1, ckpt nothing.
- - If r owner is us, ckpt owner of us and no plocks.
- - If r owner is other, ckpt that owner and any plocks we have on r
- (they've just been synced but owner=0 msg not recved yet).
- - If r owner is 0 and !got_unown, then we've just unowned r;
- ckpt owner of us and any plocks that don't have SYNCING set
- (plocks with SYNCING will be handled by our sync messages).
- - If r owner is 0 and got_unown, then ckpt owner 0 and all plocks;
- (there should be no SYNCING plocks) */
-
- list_for_each_entry(r, &ls->plock_resources, list) {
- if (!cfgd_plock_ownership)
- owner = 0;
- else if (r->owner == -1)
- continue;
- else if (r->owner == our_nodeid)
- owner = our_nodeid;
- else if (r->owner)
- owner = r->owner;
- else if (!r->owner && !got_unown(r))
- owner = our_nodeid;
- else if (!r->owner)
- owner = 0;
- else {
- log_plock_error(ls, "store_plocks error owner %d r %llx",
- r->owner, (unsigned long long)r->number);
- continue;
- }
-
- memset(&buf, 0, sizeof(buf));
- len = snprintf(buf, SECTION_NAME_LEN, "r%llu.%d",
- (unsigned long long)r->number, owner);
-
- section_id.id = (void *)buf;
- section_id.idLen = len + 1;
- section_attr.sectionId = §ion_id;
- section_attr.expirationTime = SA_TIME_END;
-
- memset(§ion_buf, 0, sizeof(section_buf));
- section_len = 0;
-
- pack_section_buf(ls, r, owner);
-
- if (!r_num_first)
- r_num_first = r->number;
- r_num_last = r->number;
-
- log_plock(ls, "wr sect ro %d rf %x len %u \"%s\"",
- r->owner, r->flags, section_len, buf);
-
- create_retry:
- rv = saCkptSectionCreate(h, §ion_attr, §ion_buf,
- section_len);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "store_plocks ckpt create retry");
- sleep(1);
- goto create_retry;
- }
- if (rv != SA_AIS_OK) {
- log_error("store_plocks ckpt section create err %d %s",
- rv, ls->name);
- goto fail;
- }
- }
- out:
- *sig = (0xFFFFFFFF & r_num_first) ^ (0xFFFFFFFF & r_num_last) ^ r_count;
-
- log_group(ls, "store_plocks first %llu last %llu r_count %u "
- "p_count %u sig %x",
- (unsigned long long)r_num_first,
- (unsigned long long)r_num_last,
- r_count, p_count, *sig);
- log_plock(ls, "store_plocks first %llu last %llu r_count %u "
- "p_count %u sig %x",
- (unsigned long long)r_num_first,
- (unsigned long long)r_num_last,
- r_count, p_count, *sig);
-
- ls->checkpoint_r_num_first = r_num_first;
- ls->checkpoint_r_num_last = r_num_last;
- ls->checkpoint_r_count = r_count;
- ls->checkpoint_p_count = p_count;
- return;
-
- fail:
- ls->disable_plock = 1;
- /* force the node receiving plocks to fail sig check and disable
- plocks as well */
- *sig = 0xF0000000;
-}
-
-/* called by a node that's just been added to the group to get existing plock
- state */
-
-void retrieve_plocks(struct lockspace *ls, uint32_t *sig)
-{
- SaCkptCheckpointHandleT h;
- SaCkptSectionIterationHandleT itr;
- SaCkptSectionDescriptorT desc;
- SaCkptIOVectorElementT iov;
- SaNameT name;
- SaAisErrorT rv;
- char buf[SECTION_NAME_LEN];
- int len, lock_count, error;
- uint32_t r_count = 0, p_count = 0;
- uint64_t r_num, r_num_first = 0, r_num_last = 0;
-
- if (!cfgd_enable_plock || ls->disable_plock)
- return;
-
- log_group(ls, "retrieve_plocks");
-
- len = snprintf((char *)name.value, SA_MAX_NAME_LENGTH, "dlmplock.%s",
- ls->name);
- name.length = len;
-
- open_retry:
- rv = saCkptCheckpointOpen(system_ckpt_handle, &name, NULL,
- SA_CKPT_CHECKPOINT_READ, 0, &h);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "retrieve_plocks ckpt open retry");
- sleep(1);
- goto open_retry;
- }
- if (rv != SA_AIS_OK) {
- log_error("retrieve_plocks ckpt open error %d %s",
- rv, ls->name);
- return;
- }
-
- init_retry:
- rv = saCkptSectionIterationInitialize(h, SA_CKPT_SECTIONS_ANY, 0, &itr);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "retrieve_plocks ckpt iterinit retry");
- sleep(1);
- goto init_retry;
- }
- if (rv != SA_AIS_OK) {
- log_error("retrieve_plocks ckpt iterinit error %d %s",
- rv, ls->name);
- goto out;
- }
-
- while (1) {
- next_retry:
- rv = saCkptSectionIterationNext(itr, &desc);
- if (rv == SA_AIS_ERR_NO_SECTIONS)
- break;
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "retrieve_plocks ckpt iternext retry");
- sleep(1);
- goto next_retry;
- }
- if (rv != SA_AIS_OK) {
- log_error("retrieve_plocks ckpt iternext error %d %s",
- rv, ls->name);
- goto out_it;
- }
-
- if (!desc.sectionId.idLen)
- continue;
-
- iov.sectionId = desc.sectionId;
- iov.dataBuffer = §ion_buf;
- iov.dataSize = desc.sectionSize;
- iov.dataOffset = 0;
-
- /* for debug print */
- memset(&buf, 0, sizeof(buf));
- snprintf(buf, SECTION_NAME_LEN, "%s", desc.sectionId.id);
-
- read_retry:
- rv = saCkptCheckpointRead(h, &iov, 1, NULL);
- if (rv == SA_AIS_ERR_TRY_AGAIN) {
- log_group(ls, "retrieve_plocks ckpt read retry");
- sleep(1);
- goto read_retry;
- }
- if (rv != SA_AIS_OK) {
- log_error("retrieve_plocks ckpt read error %d %s",
- rv, ls->name);
- goto out_it;
- }
-
- /* we'll get empty (zero length) sections for resources with
- no locks, which exist in ownership mode; the resource
- name and owner come from the section id */
-
- log_plock(ls, "rd sect len %llu \"%s\"",
- (unsigned long long)iov.readSize, buf);
-
- section_len = iov.readSize;
-
- if (section_len % sizeof(struct pack_plock)) {
- log_error("retrieve_plocks bad section len %d %s",
- section_len, ls->name);
- continue;
- }
-
- r_num = 0;
- lock_count = 0;
-
- error = unpack_section_buf(ls, (char *)desc.sectionId.id,
- desc.sectionId.idLen, &r_num,
- &lock_count);
- if (error < 0)
- continue;
-
- r_count++;
- p_count += lock_count;
-
- if (!r_num_first)
- r_num_first = r_num;
- r_num_last = r_num;
- }
-
- out_it:
- saCkptSectionIterationFinalize(itr);
- out:
- saCkptCheckpointClose(h);
-
- *sig = (0xFFFFFFFF & r_num_first) ^ (0xFFFFFFFF & r_num_last) ^ r_count;
-
- log_group(ls, "retrieve_plocks first %llu last %llu r_count %u "
- "p_count %u sig %x",
- (unsigned long long)r_num_first,
- (unsigned long long)r_num_last,
- r_count, p_count, *sig);
- log_plock(ls, "retrieve_plocks first %llu last %llu r_count %u "
- "p_count %u sig %x",
- (unsigned long long)r_num_first,
- (unsigned long long)r_num_last,
- r_count, p_count, *sig);
-}
-
-/* Called when a node has failed, or we're unmounting. For a node failure, we
- need to call this when the cpg confchg arrives so that we're guaranteed all
- nodes do this in the same sequence wrt other messages. */
-
-void purge_plocks(struct lockspace *ls, int nodeid, int unmount)
-{
- struct posix_lock *po, *po2;
- struct lock_waiter *w, *w2;
- struct resource *r, *r2;
- int purged = 0;
-
- if (!cfgd_enable_plock || ls->disable_plock)
- return;
-
- list_for_each_entry_safe(r, r2, &ls->plock_resources, list) {
- list_for_each_entry_safe(po, po2, &r->locks, list) {
- if (po->nodeid == nodeid || unmount) {
- list_del(&po->list);
- free(po);
- purged++;
- }
- }
-
- list_for_each_entry_safe(w, w2, &r->waiters, list) {
- if (w->info.nodeid == nodeid || unmount) {
- list_del(&w->list);
- free(w);
- purged++;
- }
- }
-
- /* TODO: haven't thought carefully about how this transition
- to owner 0 might interact with other owner messages in
- progress. */
-
- if (r->owner == nodeid) {
- r->owner = 0;
- r->flags |= R_GOT_UNOWN;
- r->flags |= R_PURGE_UNOWN;
- send_pending_plocks(ls, r);
- }
-
- if (!list_empty(&r->waiters))
- do_waiters(ls, r);
-
- if (!cfgd_plock_ownership &&
- list_empty(&r->locks) && list_empty(&r->waiters)) {
- list_del(&r->list);
- free(r);
- }
- }
-
- if (purged)
- ls->last_plock_time = time(NULL);
-
- log_plock(ls, "purged %d plocks for %d", purged, nodeid);
-}
-
-int fill_plock_dump_buf(struct lockspace *ls)
-{
- struct posix_lock *po;
- struct lock_waiter *w;
- struct resource *r;
- struct timeval now;
- int rv = 0;
- int len = DLMC_DUMP_SIZE, pos = 0, ret;
-
- memset(plock_dump_buf, 0, sizeof(plock_dump_buf));
- plock_dump_len = 0;
-
- gettimeofday(&now, NULL);
-
- list_for_each_entry(r, &ls->plock_resources, list) {
-
- if (list_empty(&r->locks) &&
- list_empty(&r->waiters) &&
- list_empty(&r->pending)) {
- ret = snprintf(plock_dump_buf + pos, len - pos,
- "%llu rown %d unused_ms %llu\n",
- (unsigned long long)r->number, r->owner,
- (unsigned long long)time_diff_ms(&r->last_access,
- &now));
- if (ret >= len - pos) {
- rv = -ENOSPC;
- goto out;
- }
- pos += ret;
- continue;
- }
-
- list_for_each_entry(po, &r->locks, list) {
- ret = snprintf(plock_dump_buf + pos, len - pos,
- "%llu %s %llu-%llu nodeid %d pid %u owner %llx rown %d\n",
- (unsigned long long)r->number,
- po->ex ? "WR" : "RD",
- (unsigned long long)po->start,
- (unsigned long long)po->end,
- po->nodeid, po->pid,
- (unsigned long long)po->owner, r->owner);
-
- if (ret >= len - pos) {
- rv = -ENOSPC;
- goto out;
- }
- pos += ret;
- }
-
- list_for_each_entry(w, &r->waiters, list) {
- ret = snprintf(plock_dump_buf + pos, len - pos,
- "%llu %s %llu-%llu nodeid %d pid %u owner %llx rown %d WAITING\n",
- (unsigned long long)r->number,
- w->info.ex ? "WR" : "RD",
- (unsigned long long)w->info.start,
- (unsigned long long)w->info.end,
- w->info.nodeid, w->info.pid,
- (unsigned long long)w->info.owner, r->owner);
-
- if (ret >= len - pos) {
- rv = -ENOSPC;
- goto out;
- }
- pos += ret;
- }
-
- list_for_each_entry(w, &r->pending, list) {
- ret = snprintf(plock_dump_buf + pos, len - pos,
- "%llu %s %llu-%llu nodeid %d pid %u owner %llx rown %d PENDING\n",
- (unsigned long long)r->number,
- w->info.ex ? "WR" : "RD",
- (unsigned long long)w->info.start,
- (unsigned long long)w->info.end,
- w->info.nodeid, w->info.pid,
- (unsigned long long)w->info.owner, r->owner);
-
- if (ret >= len - pos) {
- rv = -ENOSPC;
- goto out;
- }
- pos += ret;
- }
- }
- out:
- plock_dump_len = pos;
- return rv;
-}
-
diff --git a/group/include/linux_endian.h b/group/include/linux_endian.h
deleted file mode 100644
index 43089d2..0000000
--- a/group/include/linux_endian.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef __LINUX_ENDIAN_DOT_H__
-#define __LINUX_ENDIAN_DOT_H__
-
-
-#include <endian.h>
-#include <byteswap.h>
-
-
-/* I'm not sure which versions of alpha glibc/gcc are broken,
- so fix all of them. */
-#ifdef __alpha__
-#undef bswap_64
-static __inline__ unsigned long bswap_64(unsigned long x)
-{
- unsigned int h = x >> 32;
- unsigned int l = x;
-
- h = bswap_32(h);
- l = bswap_32(l);
-
- return ((unsigned long)l << 32) | h;
-}
-#endif /* __alpha__ */
-
-
-#if __BYTE_ORDER == __BIG_ENDIAN
-
-#define be16_to_cpu(x) (x)
-#define be32_to_cpu(x) (x)
-#define be64_to_cpu(x) (x)
-
-#define cpu_to_be16(x) (x)
-#define cpu_to_be32(x) (x)
-#define cpu_to_be64(x) (x)
-
-#define le16_to_cpu(x) (bswap_16((x)))
-#define le32_to_cpu(x) (bswap_32((x)))
-#define le64_to_cpu(x) (bswap_64((x)))
-
-#define cpu_to_le16(x) (bswap_16((x)))
-#define cpu_to_le32(x) (bswap_32((x)))
-#define cpu_to_le64(x) (bswap_64((x)))
-
-#endif /* __BYTE_ORDER == __BIG_ENDIAN */
-
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-#define be16_to_cpu(x) (bswap_16((x)))
-#define be32_to_cpu(x) (bswap_32((x)))
-#define be64_to_cpu(x) (bswap_64((x)))
-
-#define cpu_to_be16(x) (bswap_16((x)))
-#define cpu_to_be32(x) (bswap_32((x)))
-#define cpu_to_be64(x) (bswap_64((x)))
-
-#define le16_to_cpu(x) (x)
-#define le32_to_cpu(x) (x)
-#define le64_to_cpu(x) (x)
-
-#define cpu_to_le16(x) (x)
-#define cpu_to_le32(x) (x)
-#define cpu_to_le64(x) (x)
-
-#endif /* __BYTE_ORDER == __LITTLE_ENDIAN */
-
-
-#endif /* __LINUX_ENDIAN_DOT_H__ */
diff --git a/group/include/list.h b/group/include/list.h
deleted file mode 100644
index 8100cbc..0000000
--- a/group/include/list.h
+++ /dev/null
@@ -1,336 +0,0 @@
-/* Copied from include/linux/list.h */
-
-#ifndef _LINUX_LIST_H
-#define _LINUX_LIST_H
-
-/**
- * container_of - cast a member of a structure out to the containing structure
- *
- * @ptr: the pointer to the member.
- * @type: the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-
-
-/*
- * These are non-NULL pointers that will result in page faults
- * under normal circumstances, used to verify that nobody uses
- * non-initialized list entries.
- */
-#define LIST_POISON1 ((void *) 0x00100100)
-#define LIST_POISON2 ((void *) 0x00200200)
-
-/*
- * Simple doubly linked list implementation.
- *
- * Some of the internal functions ("__xxx") are useful when
- * manipulating whole lists rather than single entries, as
- * sometimes we already know the next/prev entries and we can
- * generate better code by using them directly rather than
- * using the generic single-entry routines.
- */
-
-struct list_head {
- struct list_head *next, *prev;
-};
-
-#define LIST_HEAD_INIT(name) { &(name), &(name) }
-
-#define LIST_HEAD(name) \
- struct list_head name = LIST_HEAD_INIT(name)
-
-#define INIT_LIST_HEAD(ptr) do { \
- (ptr)->next = (ptr); (ptr)->prev = (ptr); \
-} while (0)
-
-/*
- * Insert a new entry between two known consecutive entries.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_add(struct list_head *new,
- struct list_head *prev,
- struct list_head *next)
-{
- next->prev = new;
- new->next = next;
- new->prev = prev;
- prev->next = new;
-}
-
-/**
- * list_add - add a new entry
- * @new: new entry to be added
- * @head: list head to add it after
- *
- * Insert a new entry after the specified head.
- * This is good for implementing stacks.
- */
-static inline void list_add(struct list_head *new, struct list_head *head)
-{
- __list_add(new, head, head->next);
-}
-
-/**
- * list_add_tail - add a new entry
- * @new: new entry to be added
- * @head: list head to add it before
- *
- * Insert a new entry before the specified head.
- * This is useful for implementing queues.
- */
-static inline void list_add_tail(struct list_head *new, struct list_head *head)
-{
- __list_add(new, head->prev, head);
-}
-
-/*
- * Delete a list entry by making the prev/next entries
- * point to each other.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_del(struct list_head * prev, struct list_head * next)
-{
- next->prev = prev;
- prev->next = next;
-}
-
-/**
- * list_del - deletes entry from list.
- * @entry: the element to delete from the list.
- * Note: list_empty on entry does not return true after this, the entry is
- * in an undefined state.
- */
-static inline void list_del(struct list_head *entry)
-{
- __list_del(entry->prev, entry->next);
- entry->next = LIST_POISON1;
- entry->prev = LIST_POISON2;
-}
-
-/**
- * list_del_init - deletes entry from list and reinitialize it.
- * @entry: the element to delete from the list.
- */
-static inline void list_del_init(struct list_head *entry)
-{
- __list_del(entry->prev, entry->next);
- INIT_LIST_HEAD(entry);
-}
-
-/**
- * list_move - delete from one list and add as another's head
- * @list: the entry to move
- * @head: the head that will precede our entry
- */
-static inline void list_move(struct list_head *list, struct list_head *head)
-{
- __list_del(list->prev, list->next);
- list_add(list, head);
-}
-
-/**
- * list_move_tail - delete from one list and add as another's tail
- * @list: the entry to move
- * @head: the head that will follow our entry
- */
-static inline void list_move_tail(struct list_head *list,
- struct list_head *head)
-{
- __list_del(list->prev, list->next);
- list_add_tail(list, head);
-}
-
-/**
- * list_empty - tests whether a list is empty
- * @head: the list to test.
- */
-static inline int list_empty(const struct list_head *head)
-{
- return head->next == head;
-}
-
-/**
- * list_empty_careful - tests whether a list is
- * empty _and_ checks that no other CPU might be
- * in the process of still modifying either member
- *
- * NOTE: using list_empty_careful() without synchronization
- * can only be safe if the only activity that can happen
- * to the list entry is list_del_init(). Eg. it cannot be used
- * if another CPU could re-list_add() it.
- *
- * @head: the list to test.
- */
-static inline int list_empty_careful(const struct list_head *head)
-{
- struct list_head *next = head->next;
- return (next == head) && (next == head->prev);
-}
-
-static inline void __list_splice(struct list_head *list,
- struct list_head *head)
-{
- struct list_head *first = list->next;
- struct list_head *last = list->prev;
- struct list_head *at = head->next;
-
- first->prev = head;
- head->next = first;
-
- last->next = at;
- at->prev = last;
-}
-
-/**
- * list_splice - join two lists
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- */
-static inline void list_splice(struct list_head *list, struct list_head *head)
-{
- if (!list_empty(list))
- __list_splice(list, head);
-}
-
-/**
- * list_splice_init - join two lists and reinitialise the emptied list.
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- *
- * The list at @list is reinitialised
- */
-static inline void list_splice_init(struct list_head *list,
- struct list_head *head)
-{
- if (!list_empty(list)) {
- __list_splice(list, head);
- INIT_LIST_HEAD(list);
- }
-}
-
-/**
- * list_entry - get the struct for this entry
- * @ptr: the &struct list_head pointer.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_struct within the struct.
- */
-#define list_entry(ptr, type, member) \
- container_of(ptr, type, member)
-
-/**
- * list_first_entry - get the first element from a list
- * @ptr: the list head to take the element from.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_struct within the struct.
- *
- * Note, that list is expected to be not empty.
- */
-#define list_first_entry(ptr, type, member) \
- list_entry((ptr)->next, type, member)
-
-/**
- * list_for_each - iterate over a list
- * @pos: the &struct list_head to use as a loop counter.
- * @head: the head for your list.
- */
-#define list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * __list_for_each - iterate over a list
- * @pos: the &struct list_head to use as a loop counter.
- * @head: the head for your list.
- *
- * This variant differs from list_for_each() in that it's the
- * simplest possible list iteration code, no prefetching is done.
- * Use this for code that knows the list to be very short (empty
- * or 1 entry) most of the time.
- */
-#define __list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * list_for_each_prev - iterate over a list backwards
- * @pos: the &struct list_head to use as a loop counter.
- * @head: the head for your list.
- */
-#define list_for_each_prev(pos, head) \
- for (pos = (head)->prev; pos != (head); pos = pos->prev)
-
-/**
- * list_for_each_safe - iterate over a list safe against removal of list entry
- * @pos: the &struct list_head to use as a loop counter.
- * @n: another &struct list_head to use as temporary storage
- * @head: the head for your list.
- */
-#define list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
-
-/**
- * list_for_each_entry - iterate over list of given type
- * @pos: the type * to use as a loop counter.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry(pos, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_reverse - iterate backwards over list of given type.
- * @pos: the type * to use as a loop counter.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry_reverse(pos, head, member) \
- for (pos = list_entry((head)->prev, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.prev, typeof(*pos), member))
-
-/**
- * list_prepare_entry - prepare a pos entry for use as a start point in
- * list_for_each_entry_continue
- * @pos: the type * to use as a start point
- * @head: the head of the list
- * @member: the name of the list_struct within the struct.
- */
-#define list_prepare_entry(pos, head, member) \
- ((pos) ? : list_entry(head, typeof(*pos), member))
-
-/**
- * list_for_each_entry_continue - iterate over list of given type
- * continuing after existing point
- * @pos: the type * to use as a loop counter.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry_continue(pos, head, member) \
- for (pos = list_entry(pos->member.next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @pos: the type * to use as a loop counter.
- * @n: another type * to use as temporary storage
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry_safe(pos, n, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member), \
- n = list_entry(pos->member.next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-
-#endif
diff --git a/group/lib/Makefile b/group/lib/Makefile
deleted file mode 100644
index ca1e2c6..0000000
--- a/group/lib/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-TARGET=libgroup
-
-MAKESTATICLIB = 1
-
-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$(S) -I$(S)/../daemon
-CFLAGS += -I${incdir}
diff --git a/group/lib/libgroup.c b/group/lib/libgroup.c
deleted file mode 100644
index 894aeb1..0000000
--- a/group/lib/libgroup.c
+++ /dev/null
@@ -1,524 +0,0 @@
-#include <sys/types.h>
-#include <sys/un.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "groupd.h"
-#include "libgroup.h"
-
-#define LIBGROUP_MAGIC 0x67727570
-#define MAXARGS 100 /* FIXME */
-
-#define VALIDATE_HANDLE(h) \
-do { \
- if (!(h) || (h)->magic != LIBGROUP_MAGIC) { \
- errno = EINVAL; \
- return -1; \
- } \
-} while (0)
-
-enum {
- DO_STOP = 1,
- DO_START = 2,
- DO_FINISH = 3,
- DO_TERMINATE = 4,
- DO_SET_ID = 5,
- DO_DELIVER = 6,
-};
-
-
-/* if there's more data beyond the number of args we want, the return value
- points to it */
-
-static char *get_args(char *buf, int *argc, char **argv, char sep, int want)
-{
- char *p = buf, *rp = NULL;
- int i;
-
- argv[0] = p;
-
- for (i = 1; i < MAXARGS; i++) {
- p = strchr(buf, sep);
- if (!p)
- break;
- *p = '\0';
-
- if (want == i) {
- rp = p + 1;
- break;
- }
-
- argv[i] = p + 1;
- buf = p + 1;
- }
- *argc = i;
-
- /* we ended by hitting \0, return the point following that */
- if (!rp)
- rp = strchr(buf, '\0') + 1;
-
- return rp;
-}
-
-static void get_nodeids(char *buf, int memb_count, int *nodeids)
-{
- char *p;
- int i, count = 0;
-
- for (i = 0; ; i++) {
- if (isdigit(buf[i]))
- break;
- }
-
- buf = &buf[i];
-
- for (i = 0; i < memb_count; i++) {
-
- nodeids[count++] = atoi(buf);
-
- p = strchr(buf, ' ');
- if (!p)
- break;
-
- buf = p + 1;
- }
-}
-
-static int get_action(char *buf)
-{
- char act[16];
- int i;
-
- memset(act, 0, 16);
-
- for (i = 0; i < 16; i++) {
- if (isalnum(buf[i]))
- act[i] = buf[i];
- else
- break;
- }
-
- if (!strncmp(act, "stop", 16))
- return DO_STOP;
-
- if (!strncmp(act, "start", 16))
- return DO_START;
-
- if (!strncmp(act, "finish", 16))
- return DO_FINISH;
-
- if (!strncmp(act, "terminate", 16))
- return DO_TERMINATE;
-
- if (!strncmp(act, "setid", 16))
- return DO_SET_ID;
-
- if (!strncmp(act, "deliver", 16))
- return DO_DELIVER;
-
- return -1;
-}
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, (char *)buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0)
- return rv;
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-static int do_read(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- while (off < count) {
- rv = read(fd, (char *)buf + off, count - off);
- if (rv == 0)
- return -1;
- if (rv == -1 && errno == EINTR)
- continue;
- if (rv == -1)
- return -1;
- off += rv;
- }
- return 0;
-}
-
-struct group_handle
-{
- int magic;
- int fd;
- int level;
- void *private;
- group_callbacks_t cbs;
- char prog_name[32];
-};
-
-static int _joinleave(group_handle_t handle, const char *name, const char *cmd)
-{
- char buf[GROUPD_MSGLEN];
- struct group_handle *h = (struct group_handle *) handle;
- VALIDATE_HANDLE(h);
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "%s %s", cmd, name);
-
- return do_write(h->fd, buf, GROUPD_MSGLEN);
-}
-
-int group_join(group_handle_t handle, char *name)
-{
- return _joinleave(handle, name, "join");
-}
-
-int group_leave(group_handle_t handle, char *name)
-{
- return _joinleave(handle, name, "leave");
-}
-
-int group_stop_done(group_handle_t handle, char *name)
-{
- char buf[GROUPD_MSGLEN];
- struct group_handle *h = (struct group_handle *) handle;
- VALIDATE_HANDLE(h);
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "stop_done %s", name);
-
- return do_write(h->fd, buf, GROUPD_MSGLEN);
-}
-
-int group_start_done(group_handle_t handle, char *name, int event_nr)
-{
- char buf[GROUPD_MSGLEN];
- struct group_handle *h = (struct group_handle *) handle;
- VALIDATE_HANDLE(h);
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "start_done %s %d", name, event_nr);
-
- return do_write(h->fd, buf, GROUPD_MSGLEN);
-}
-
-int group_send(group_handle_t handle, char *name, int len, char *data)
-{
- char buf[GROUPD_MSGLEN];
- int rv;
- struct group_handle *h = (struct group_handle *) handle;
- VALIDATE_HANDLE(h);
-
- if (len > 2048 || len <= 0)
- return -EINVAL;
-
- memset(buf, 0, sizeof(buf));
- rv = snprintf(buf, sizeof(buf), "send %s %d", name, len);
- memcpy(buf + rv + 1, data, len);
-
- return do_write(h->fd, buf, GROUPD_MSGLEN);
-}
-
-static int connect_groupd(void)
-{
- struct sockaddr_un sun;
- socklen_t addrlen;
- int rv, fd;
-
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (fd < 0)
- goto out;
-
- memset(&sun, 0, sizeof(sun));
- sun.sun_family = AF_UNIX;
- strcpy(&sun.sun_path[1], GROUPD_SOCK_PATH);
- addrlen = sizeof(sa_family_t) + strlen(sun.sun_path+1) + 1;
-
- rv = connect(fd, (struct sockaddr *) &sun, addrlen);
- if (rv < 0) {
- close(fd);
- fd = rv;
- }
- out:
- return fd;
-}
-
-group_handle_t group_init(void *private, const char *prog_name, int level,
- group_callbacks_t *cbs, int timeout)
-{
- struct group_handle *h;
- char buf[GROUPD_MSGLEN];
- int rv, saved_errno, i;
-
- h = malloc(sizeof(struct group_handle));
- if (!h)
- return NULL;
-
- h->magic = LIBGROUP_MAGIC;
- h->private = private;
- h->cbs = *cbs;
- h->level = level;
- strncpy(h->prog_name, prog_name, 32);
-
- for (i = 0; !timeout || i < timeout * 2; i++) {
- h->fd = connect_groupd();
- if (h->fd > 0 || !timeout)
- break;
- usleep(500000);
- }
-
- if (h->fd <= 0)
- goto fail;
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "setup %s %d", prog_name, level);
-
- rv = do_write(h->fd, &buf, GROUPD_MSGLEN);
- if (rv < 0)
- goto fail;
-
- return (group_handle_t) h;
-
- fail:
- saved_errno = errno;
- close(h->fd);
- free(h);
- h = NULL;
- errno = saved_errno;
- return NULL;
-}
-
-int group_exit(group_handle_t handle)
-{
- struct group_handle *h = (struct group_handle *) handle;
- VALIDATE_HANDLE(h);
- h->magic = 0;
- close(h->fd);
- free(h);
- return 0;
-}
-
-int group_get_fd(group_handle_t handle)
-{
- struct group_handle *h = (struct group_handle *) handle;
- VALIDATE_HANDLE(h);
- return h->fd;
-}
-
-/* Format of string messages we receive from groupd:
-
- "stop <name>"
-
- name = the name of the group (same for rest)
-
- "start <name> <event_nr> <type> <memb_count> <memb0> <memb1>..."
-
- event_nr = used to later match finish/terminate
- type = 1/GROUP_NODE_FAILED, 2/GROUP_NODE_JOIN, 3/GROUP_NODE_LEAVE
- memb_count = the number of group members
- memb0... = the nodeids of the group members
-
- "finish <name> <event_nr>"
-
- event_nr = matches the start event that's finishing
-
- "terminate <name> <event_nr>"
-
- event_nr = matches the start event that's being canceled
-
- "setid <name> <id>"
-
- id = the global id of the group
-
- "deliver <name> <nodeid> <len>"<data>
-
- nodeid = who sent the message
- len = length of the message
- data = the message
-*/
-
-int group_dispatch(group_handle_t handle)
-{
- char buf[GROUPD_MSGLEN], *argv[MAXARGS];
- char *p;
- int act, argc, rv, count, *nodeids;
- struct group_handle *h = (struct group_handle *) handle;
- VALIDATE_HANDLE(h);
-
- memset(buf, 0, sizeof(buf));
-
- rv = do_read(h->fd, &buf, GROUPD_MSGLEN);
- if (rv < 0)
- goto out;
-
- act = get_action(buf);
-
- switch (act) {
-
- case DO_STOP:
- get_args(buf, &argc, argv, ' ', 2);
-
- h->cbs.stop(h, h->private, argv[1]);
- break;
-
- case DO_START:
- p = get_args(buf, &argc, argv, ' ', 5);
-
- count = atoi(argv[4]);
- nodeids = malloc(count * sizeof(int));
- if (!nodeids) {
- rv = -ENOMEM;
- goto out;
- }
- get_nodeids(p, count, nodeids);
-
- h->cbs.start(h, h->private, argv[1], atoi(argv[2]),
- atoi(argv[3]), count, nodeids);
-
- free(nodeids);
- break;
-
- case DO_FINISH:
- get_args(buf, &argc, argv, ' ', 3);
-
- h->cbs.finish(h, h->private, argv[1], atoi(argv[2]));
- break;
-
- case DO_TERMINATE:
- get_args(buf, &argc, argv, ' ', 3);
-
- /* FIXME: why aren't we passing event_nr, argv[2], through? */
-
- h->cbs.terminate(h, h->private, argv[1]);
- break;
-
- case DO_SET_ID:
- get_args(buf, &argc, argv, ' ', 3);
-
- h->cbs.set_id(h, h->private, argv[1],
- (unsigned int) strtoul(argv[2], NULL, 10));
- break;
-
- case DO_DELIVER:
- p = get_args(buf, &argc, argv, ' ', 4);
-
- h->cbs.deliver(h, h->private, argv[1], atoi(argv[2]),
- atoi(argv[3]), p);
- break;
- }
-
- rv = 0;
- out:
- return rv;
-}
-
-int group_get_groups(int max, int *count, group_data_t *data)
-{
- char buf[GROUPD_MSGLEN];
- group_data_t dbuf, empty;
- int fd, rv;
-
- *count = 0;
-
- fd = connect_groupd();
- if (fd < 0)
- return fd;
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "get_groups %d", max);
-
- rv = do_write(fd, &buf, GROUPD_MSGLEN);
- if (rv < 0)
- goto out;
-
- memset(&empty, 0, sizeof(empty));
-
- while (1) {
- memset(&dbuf, 0, sizeof(dbuf));
-
- rv = do_read(fd, &dbuf, sizeof(group_data_t));
- if (rv < 0)
- break;
-
- if (!memcmp(&dbuf, &empty, sizeof(group_data_t))) {
- rv = 0;
- break;
- } else {
- memcpy(&data[*count], &dbuf, sizeof(group_data_t));
- (*count)++;
- }
- }
- out:
- close(fd);
- return rv;
-}
-
-int group_get_group(int level, const char *name, group_data_t *data)
-{
- char buf[GROUPD_MSGLEN];
- char data_buf[sizeof(group_data_t)];
- int fd, rv;
-
- fd = connect_groupd();
- if (fd < 0)
- return fd;
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "get_group %d %s", level, name);
-
- rv = do_write(fd, &buf, GROUPD_MSGLEN);
- if (rv < 0)
- goto out;
-
- rv = do_read(fd, &data_buf, sizeof(data_buf));
- if (rv < 0)
- goto out;
-
- memcpy(data, data_buf, sizeof(group_data_t));
- rv = 0;
- out:
- close(fd);
- return rv;
-}
-
-int group_get_version(int *version)
-{
- char buf[GROUPD_MSGLEN];
- int fd, rv;
-
- fd = connect_groupd();
- if (fd < 0)
- return fd;
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "get_version");
-
- rv = do_write(fd, &buf, GROUPD_MSGLEN);
- if (rv < 0)
- goto out;
-
- rv = do_read(fd, version, sizeof(int));
- if (rv < 0)
- goto out;
- rv = 0;
- out:
- close(fd);
- return rv;
-}
-
diff --git a/group/lib/libgroup.h b/group/lib/libgroup.h
deleted file mode 100644
index fd100a8..0000000
--- a/group/lib/libgroup.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef _LIBGROUP_H_
-#define _LIBGROUP_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MAX_GROUP_MEMBERS 256
-#define MAX_GROUP_NAME_LEN 32
-
-/* these need to match what's in groupd.h */
-#define GROUP_NODE_FAILED 1
-#define GROUP_NODE_JOIN 2
-#define GROUP_NODE_LEAVE 3
-
-typedef void *group_handle_t;
-
-typedef void (*group_stop_t)(group_handle_t h, void *priv, char *name);
-typedef void (*group_start_t)(group_handle_t h, void *priv, char *name,
- int event_nr, int type, int member_count,
- int *members);
-typedef void (*group_finish_t)(group_handle_t h, void *priv, char *name,
- int event_nr);
-typedef void (*group_terminate_t)(group_handle_t h, void *priv, char *name);
-typedef void (*group_set_id_t)(group_handle_t h, void *priv, char *name,
- unsigned int id);
-typedef void (*group_deliver_t)(group_handle_t h, void *priv, char *name,
- int nodeid, int len, char *buf);
-
-typedef struct {
- group_stop_t stop;
- group_start_t start;
- group_finish_t finish;
- group_terminate_t terminate;
- group_set_id_t set_id;
- group_deliver_t deliver;
-} group_callbacks_t;
-
-group_handle_t group_init(void *priv, const char *prog_name, int level, group_callbacks_t *cbs, int timeout);
-int group_exit(group_handle_t handle);
-
-int group_join(group_handle_t handle, char *name);
-int group_leave(group_handle_t handle, char *name);
-int group_stop_done(group_handle_t handle, char *name);
-int group_start_done(group_handle_t handle, char *name, int event_nr);
-int group_get_fd(group_handle_t handle);
-int group_dispatch(group_handle_t handle);
-int group_send(group_handle_t handle, char *name, int len, char *buf);
-
-
-/*
- * Querying for group information
- */
-
-typedef struct group_data {
- char client_name[32+1];
- char name[MAX_GROUP_NAME_LEN+1];
- int level;
- unsigned int id;
- int member;
- int member_count;
- int members[MAX_GROUP_MEMBERS];
- int event_state;
- int event_nodeid;
- int event_local_status;
- uint64_t event_id;
-} group_data_t;
-
-/* These routines create their own temporary connection to groupd so they
- don't interfere with dispatchable callback messages. */
-
-int group_get_groups(int max, int *count, group_data_t *data);
-int group_get_group(int level, const char *name, group_data_t *data);
-
-int group_get_version(int *version);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/group/man/Makefile b/group/man/Makefile
deleted file mode 100644
index 68b0d90..0000000
--- a/group/man/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-MANTARGET= \
- dlm_controld.8 \
- group_tool.8 \
- groupd.8
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-all:
-
-clean:
diff --git a/group/man/dlm_controld.8 b/group/man/dlm_controld.8
deleted file mode 100644
index 6764681..0000000
--- a/group/man/dlm_controld.8
+++ /dev/null
@@ -1,313 +0,0 @@
-.TH DLM_CONTROLD 8 2009-01-18 cluster cluster
-
-.SH NAME
-dlm_controld \- daemon that configures dlm according to cluster events
-
-.SH SYNOPSIS
-.B dlm_controld
-[OPTIONS]
-
-.SH DESCRIPTION
-The dlm lives in the kernel, and the cluster infrastructure (corosync
-membership and group management) lives in user space. The dlm in the
-kernel needs to adjust/recover for certain cluster events. It's the job
-of dlm_controld to receive these events and reconfigure the kernel dlm as
-needed. dlm_controld controls and configures the dlm through sysfs and
-configfs files that are considered dlm-internal interfaces.
-
-The cman init script usually starts the dlm_controld daemon.
-
-.SH OPTIONS
-Command line options override a corresponding setting in cluster.conf.
-
-.TP
-.B \-D
-Enable debugging to stderr and don't fork.
-.br
-See also
-.B dlm_tool dump
-in
-.BR dlm_tool (8).
-
-.TP
-.B \-L
-Enable debugging to log file.
-.br
-See also
-.B logging
-in
-.BR cluster.conf (5).
-
-.TP
-.B \-K
-Enable kernel dlm debugging messages.
-.br
-See also
-.B log_debug
-below.
-
-.TP
-.BI \-r " num"
-dlm kernel lowcomms protocol, 0 tcp, 1 sctp, 2 detect.
-2 selects tcp if corosync rrp_mode is "none", otherwise sctp.
-.br
-Default 2.
-
-.TP
-.BI \-g " num"
-groupd compatibility mode, 0 off, 1 on.
-.br
-Default 0.
-
-.TP
-.BI \-f " num"
-Enable (1) or disable (0) fencing recovery dependency.
-.br
-Default 1.
-
-.TP
-.BI \-q " num"
-Enable (1) or disable (0) quorum recovery dependency.
-.br
-Default 0.
-
-.TP
-.BI \-d " num"
-Enable (1) or disable (0) deadlock detection code.
-.br
-Default 0.
-
-.TP
-.BI \-p " num"
-Enable (1) or disable (0) plock code for cluster fs.
-.br
-Default 1.
-
-.TP
-.BI \-l " num"
-Limit the rate of plock operations, 0 for no limit.
-.br
-Default 0.
-
-.TP
-.BI \-o " num"
-Enable (1) or disable (0) plock ownership.
-.br
-Default 1.
-
-.TP
-.BI \-t " ms"
-Plock ownership drop resources time (milliseconds).
-.br
-Default 10000.
-
-.TP
-.BI \-c " num"
-Plock ownership drop resources count.
-.br
-Default 10.
-
-.TP
-.BI \-a " ms"
-Plock ownership drop resources age (milliseconds).
-.br
-Default 10000.
-
-.TP
-.B \-P
-Enable plock debugging messages (can produce excessive output).
-
-.TP
-.B \-h
-Print a help message describing available options, then exit.
-
-.TP
-.B \-V
-Print program version information, then exit.
-
-
-.SH FILES
-.BR cluster.conf (5)
-is usually located at /etc/cluster/cluster.conf. It is not read directly.
-Other cluster components load the contents into memory, and the values are
-accessed through the libccs library.
-
-Configuration options for dlm (kernel) and dlm_controld are added to the
-<dlm /> section of cluster.conf, within the top level <cluster> section.
-
-.SS Kernel options
-
-.TP
-.B protocol
-The network
-.B protocol
-can be set to tcp, sctp or detect which selects tcp or sctp based on
-the corosync rrp_mode configuration (redundant ring protocol).
-The rrp_mode "none" results in tcp. Default detect.
-
-<dlm protocol="detect"/>
-
-.TP
-.B timewarn
-After waiting
-.B timewarn
-centiseconds, the dlm will emit a warning via netlink. This only applies
-to lockspaces created with the DLM_LSFL_TIMEWARN flag, and is used for
-deadlock detection. Default 500 (5 seconds).
-
-<dlm timewarn="500"/>
-
-.TP
-.B log_debug
-DLM kernel debug messages can be enabled by setting
-.B log_debug
-to 1. Default 0.
-
-<dlm log_debug="0"/>
-
-.TP
-.B clusternode/weight
-The lock directory
-.B weight
-can be specified one the clusternode lines. Weights would usually be
-used in the lock server configurations shown below instead.
-
-<clusternode name="node01" nodeid="1" weight="1"/>
-
-.SS Daemon options
-
-.TP
-.B enable_fencing
-See command line description.
-
-<dlm enable_fencing="1"/>
-
-.TP
-.B enable_quorum
-See command line description.
-
-<dlm enable_quorum="0"/>
-
-.TP
-.B enable_deadlk
-See command line description.
-
-<dlm enable_deadlk="0"/>
-
-.TP
-.B enable_plock
-See command line description.
-
-<dlm enable_plock="1"/>
-
-.TP
-.B plock_rate_limit
-See command line description.
-
-<dlm plock_rate_limit="0"/>
-
-.TP
-.B plock_ownership
-See command line description.
-
-<dlm plock_ownership="1"/>
-
-.TP
-.B drop_resources_time
-See command line description.
-
-<dlm drop_resources_time="10000"/>
-
-.TP
-.B drop_resources_count
-See command line description.
-
-<dlm drop_resources_count="10"/>
-
-.TP
-.B drop_resources_age
-See command line description.
-
-<dlm drop_resources_age="10000"/>
-
-.TP
-.B plock_debug
-Enable (1) or disable (0) plock debugging messages (can produce excessive
-output). Default 0.
-
-<dlm plock_debug="0"/>
-
-
-.SS Disabling resource directory
-
-Lockspaces usually use a resource directory to keep track of which node is
-the master of each resource. The dlm can operate without the resource
-directory, though, by statically assigning the master of a resource using
-a hash of the resource name. To enable, set the per-lockspace
-.B nodir
-option to 1.
-
-.nf
-<dlm>
- <lockspace name="foo" nodir="1"/>
-</dlm>
-.fi
-
-.SS Lock-server configuration
-
-The nodir setting can be combined with node weights to create a
-configuration where select node(s) are the master of all resources/locks.
-These
-.B master
-nodes can be viewed as "lock servers" for the other nodes.
-
-.nf
-<dlm>
- <lockspace name="foo" nodir="1">
- <master name="node01"/>
- </lockspace>
-</dlm>
-
-or,
-
-<dlm>
- <lockspace name="foo" nodir="1">
- <master name="node01"/>
- <master name="node02"/>
- </lockspace>
-</dlm>
-.fi
-
-Lock management will be partitioned among the available masters. There
-can be any number of masters defined. The designated master nodes will
-master all resources/locks (according to the resource name hash). When no
-masters are members of the lockspace, then the nodes revert to the common
-fully-distributed configuration. Recovery is faster, with little
-disruption, when a non-master node joins/leaves.
-
-There is no special mode in the dlm for this lock server configuration,
-it's just a natural consequence of combining the "nodir" option with node
-weights. When a lockspace has master nodes defined, the master has a
-default weight of 1 and all non-master nodes have weight of 0. An explicit
-non-zero
-.B weight
-can also be assigned to master nodes, e.g.
-
-.nf
-<dlm>
- <lockspace name="foo" nodir="1">
- <master name="node01" weight="2"/>
- <master name="node02" weight="1"/>
- </lockspace>
-</dlm>
-.fi
-
-In which case node01 will master 2/3 of the total resources and node2 will
-master the other 1/3.
-
-.SH SEE ALSO
-.BR dlm_tool (8),
-.BR fenced (8),
-.BR cman (5),
-.BR cluster.conf (5)
-
diff --git a/group/man/group_tool.8 b/group/man/group_tool.8
deleted file mode 100644
index 53cd3da..0000000
--- a/group/man/group_tool.8
+++ /dev/null
@@ -1,80 +0,0 @@
-.TH GROUP_TOOL 8 2009-01-19 cluster cluster
-
-.SH NAME
-group_tool \- run common fence_tool, dlm_tool, gfs_control commands
-
-.SH SYNOPSIS
-.B group_tool
-[COMMAND] [OPTIONS]
-
-.SH DESCRIPTION
-This utility is deprecated and the new replacements are shown. See
-.BR fence_tool (8),
-.BR dlm_tool (8),
-.BR gfs_control (8)
-man pages for more information about the new commands.
-
-.TP
-.B ls
-runs
-.BR "fence_tool ls " ;
-.BR "dlm_tool ls " ;
-.B gfs_control ls
-.TP
-.B dump fence
-equivalent to new
-.B fence_tool dump
-.TP
-.B dump dlm
-equivalent to new
-.B dlm_tool dump
-.TP
-.B dump gfs
-equivalent to new
-.B gfs_control dump
-.TP
-.BI "dump plocks" " name"
-equivalent to new
-.BI "dlm_tool plocks" " name"
-
-.SS Cluster Uprading
-
-When performing a rolling upgrade from cluster2 to cluster3, the
-.BR groupd (8)
-daemon will be running and group_tool can be used with groupd like it was in
-cluster2.
-
-.TP
-.B ls \-g1
-queries and displays the internal groupd state.
-.TP
-.B dump
-queries and dumps the groupd debug buffer.
-.TP
-.B compat
-queries and displays the internal groupd compatibility mode.
-
-.SH OPTIONS
-.TP
-.BI \-g " num"
-Force old groupd queries with 1.
-.TP
-.B \-n
-Show all node information in ls.
-.TP
-.B \-v
-Show verbose information from groupd with ls \-g1.
-.TP
-.B \-h
-Print a help message describing available options, then exit.
-.TP
-.B \-V
-Print program version information, then exit.
-
-.SH SEE ALSO
-.BR cman (5),
-.BR groupd (8),
-.BR fence_tool (8),
-.BR dlm_tool (8),
-.BR gfs_control(8)
-
diff --git a/group/man/groupd.8 b/group/man/groupd.8
deleted file mode 100644
index 5c83cd6..0000000
--- a/group/man/groupd.8
+++ /dev/null
@@ -1,64 +0,0 @@
-.TH GROUPD 8 2009-01-19 cluster cluster
-
-.SH NAME
-groupd \- compatibility daemon for fenced, dlm_controld and gfs_controld
-
-.SH SYNOPSIS
-.B groupd
-[OPTIONS]
-
-.SH DESCRIPTION
-
-The groupd daemon and libgroup library are used by the fenced,
-dlm_controld and gfs_controld daemons when they are operating in
-cluster2-compatible mode to perform a rolling cluster upgrade from
-cluster2 to cluster3.
-
-See
-.BR cman (5)
-for more information on the
-.B upgrading
-configuration option needed to perform a rolling upgrade.
-
-When the upgrading option is enabled, cman adds the following to the
-online configuration:
-
- <group groupd_compat="1"/>
-
-This setting causes the cman init script to start the groupd daemon,
-and causes the groupd, fenced, dlm_controld and gfs_controld daemons to
-operate in the old cluster2 mode so they will be compatible with cluster2
-nodes in the cluster that have not yet been upgraded.
-
-The upgrading setting, including the groupd_compat setting,
-.B cannot be changed in a running cluster.
-The entire cluster must be taken offline to change these because the new
-cluster3 default modes are not compatible with the old cluster2 modes.
-The upgrading/compat settings cause the new cluster3 daemons to run the
-old cluster2 code and protocols.
-
-.SH OPTIONS
-Command line options override a corresponding setting in cluster.conf.
-
-.TP
-.B \-D
-Enable debugging to stderr and don't fork.
-.TP
-.B \-L
-Enable debugging to log file.
-.TP
-.BI \-g " num"
-groupd compatibility mode, 0 off, 1 on. Default 0.
-.TP
-.B \-h
-Print a help message describing available options, then exit.
-.TP
-.B \-V
-Print program version information, then exit.
-
-.SH SEE ALSO
-.BR cman (5),
-.BR fenced (8),
-.BR dlm_controld (8),
-.BR gfs_controld (8)
-
diff --git a/group/test/Makefile b/group/test/Makefile
deleted file mode 100644
index 3a91013..0000000
--- a/group/test/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-TARGETS= client clientd
-
-all: $(TARGETS)
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${libdir}
-
-%: %.o
- $(CC) -o $@ $^ $(LDFLAGS)
-
-clean: generalclean
diff --git a/group/test/client.c b/group/test/client.c
deleted file mode 100644
index a9a3930..0000000
--- a/group/test/client.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/types.h>
-#include <sys/errno.h>
-
-
-#define COMMAND_SOCK_PATH "command_socket"
-
-
-int main(int argc, char *argv[])
-{
- int s, i, rv;
- struct sockaddr_un addr;
- socklen_t addrlen;
- char buf[256];
-
- s = socket(AF_LOCAL, SOCK_DGRAM, 0);
- if (s < 0) {
- printf("socket error %d errno %d\n", s, errno);
- exit(-1);
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- strcpy(&addr.sun_path[1], COMMAND_SOCK_PATH);
- addrlen = sizeof(sa_family_t) + strlen(addr.sun_path+1) + 1;
-
- memset(buf, 0, 256);
-
- for (i = 1; i < argc; i++) {
- if (i != 1)
- strcat(buf, " ");
- strcat(buf, argv[i]);
- }
-
-
- rv = sendto(s, buf, strlen(buf), 0, (struct sockaddr *)&addr, addrlen);
-
- printf("send %d \"%s\"\n", rv, buf);
- return 0;
-}
-
diff --git a/group/test/clientd.c b/group/test/clientd.c
deleted file mode 100644
index 9f344f4..0000000
--- a/group/test/clientd.c
+++ /dev/null
@@ -1,179 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <asm/types.h>
-#include <sys/socket.h>
-#include <sys/poll.h>
-#include <sys/un.h>
-#include <linux/netlink.h>
-
-#define GROUPD_SOCK_PATH "groupd_socket"
-#define COMMAND_SOCK_PATH "command_socket"
-
-#define MAXLINE 256
-#define MAXCON 4
-
-#define log_error(fmt, args...) fprintf(stderr, fmt "\n", ##args)
-
-int groupd_fd;
-int command_fd;
-struct sockaddr_un sun;
-struct sockaddr_un addr;
-socklen_t addrlen;
-
-
-void process_groupd(void)
-{
- char buf[MAXLINE];
- int rv;
-
- memset(buf, 0, sizeof(buf));
-
- rv = read(groupd_fd, &buf, sizeof(buf));
- if (rv < 0) {
- log_error("read error %d errno %d", rv, errno);
- return;
- }
-
- printf("I: groupd read: %s\n", buf);
-}
-
-void process_command(void)
-{
- char buf[MAXLINE];
- int rv;
-
- memset(buf, 0, sizeof(buf));
-
- rv = recvfrom(command_fd, buf, MAXLINE, 0, (struct sockaddr *) &addr,
- &addrlen);
-
- printf("I: command recv: %s\n", buf);
-
- rv = write(groupd_fd, buf, strlen(buf));
- if (rv < 0)
- log_error("groupd write error");
-
- printf("O: command write: %s\n", buf);
-}
-
-void process_input(int fd)
-{
- if (fd == groupd_fd)
- process_groupd();
- else if (fd == command_fd)
- process_command();
-}
-
-void process_hup(int fd)
-{
- if (fd == groupd_fd)
- close(groupd_fd);
- else if (fd == command_fd)
- close(command_fd);
-}
-
-int setup_groupd(void)
-{
- char buf[] = "setup test 1";
- int rv;
-
- rv = write(groupd_fd, &buf, strlen(buf));
- if (rv < 0) {
- log_error("write error %d errno %d %s", rv, errno, buf);
- return -1;
- }
- return 0;
-}
-
-int loop(void)
-{
- struct pollfd *pollfd;
- int s, rv, i, maxi;
-
-
- pollfd = malloc(MAXCON * sizeof(struct pollfd));
- if (!pollfd)
- return -1;
-
-
- /* connect to the groupd server */
-
- s = socket(AF_LOCAL, SOCK_STREAM, 0);
- if (s < 0) {
- log_error("socket");
- exit(1);
- }
-
- memset(&sun, 0, sizeof(sun));
- sun.sun_family = AF_LOCAL;
- strcpy(&sun.sun_path[1], GROUPD_SOCK_PATH);
- addrlen = sizeof(sa_family_t) + strlen(sun.sun_path+1) + 1;
-
- rv = connect(s, (struct sockaddr *) &sun, addrlen);
- if (rv < 0) {
- log_error("groupd connect error %d errno %d", rv, errno);
- exit(1);
- }
-
- groupd_fd = s;
- pollfd[0].fd = s;
- pollfd[0].events = POLLIN;
-
-
- /* get commands via another local socket */
-
- s = socket(AF_LOCAL, SOCK_DGRAM, 0);
- if (s < 0) {
- log_error("socket");
- exit(1);
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- strcpy(&addr.sun_path[1], COMMAND_SOCK_PATH);
- addrlen = sizeof(sa_family_t) + strlen(addr.sun_path+1) + 1;
-
- rv = bind(s, (struct sockaddr *) &addr, addrlen);
- if (rv < 0) {
- log_error("bind error");
- exit(1);
- }
-
- command_fd = s;
- pollfd[1].fd = s;
- pollfd[1].events = POLLIN;
-
- maxi = 1;
-
- rv = setup_groupd();
- if (rv < 0) {
- log_error("setup_groupd");
- exit(1);
- }
-
- for (;;) {
- rv = poll(pollfd, maxi + 1, -1);
- if (rv < 0)
- log_error("poll");
-
- for (i = 0; i <= maxi; i++) {
- if (pollfd[i].revents & (POLLHUP | POLLERR | POLLNVAL)) {
- process_hup(pollfd[i].fd);
- } else if (pollfd[i].revents & POLLIN) {
- process_input(pollfd[i].fd);
- }
- }
- }
-
- free(pollfd);
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- return loop();
-}
-
diff --git a/group/tool/Makefile b/group/tool/Makefile
deleted file mode 100644
index 3004821..0000000
--- a/group/tool/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-TARGET= group_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
-
-CFLAGS += -I$(S) -I$(S)/../daemon/ -I$(S)/../lib/
-CFLAGS += -I${incdir}
-CFLAGS += -I${KERNEL_SRC}/include/
-
-LDFLAGS += -L../lib -lgroup
-LDFLAGS += -L${libdir}
-
-LDDEPS += ../lib/libgroup.a
-
-${TARGET}: ${OBJS} ${LDDEPS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-depends:
- $(MAKE) -C ../lib all
-
-clean: generalclean
diff --git a/group/tool/main.c b/group/tool/main.c
deleted file mode 100644
index 5b21531..0000000
--- a/group/tool/main.c
+++ /dev/null
@@ -1,735 +0,0 @@
-#include <sys/types.h>
-#include <sys/un.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <netinet/in.h>
-#include <linux/dlmconstants.h>
-
-#include "libgroup.h"
-#include "groupd.h"
-#include "copyright.cf"
-
-#define GROUP_LIBGROUP 2
-#define GROUP_LIBCPG 3
-
-#define MAX_NODES 128
-#define MAX_LS 128
-#define MAX_MG 128
-#define MAX_GROUPS 128
-
-#define OP_LIST 1
-#define OP_DUMP 2
-#define OP_COMPAT 3
-
-#define DEFAULT_GROUPD_COMPAT 0
-
-static char *prog_name;
-static int operation;
-static int opt_ind;
-static int verbose;
-static int ls_all_nodes;
-static int opt_groupd_compat;
-static int cfg_groupd_compat = DEFAULT_GROUPD_COMPAT;
-
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, (char *)buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0)
- return rv;
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-static int do_read(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- while (off < count) {
- rv = read(fd, (char *)buf + off, count - off);
- if (rv == 0)
- return -1;
- if (rv == -1 && errno == EINTR)
- continue;
- if (rv == -1)
- return -1;
- off += rv;
- }
- return 0;
-}
-
-static void print_usage(void)
-{
- printf("Usage:\n");
- printf("\n");
- printf("%s [options] [compat|ls|dump]\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("\n");
-
- printf("compat Show compatibility mode that groupd is running\n");
- printf("\n");
-
- printf("ls Show group state for fence, dlm, gfs\n");
- printf(" -g <num> select daemons to query\n");
- printf(" 0: query fenced, dlm_controld, gfs_controld\n");
- printf(" 1: query groupd (for old compat mode)\n");
- printf(" 2: use 0 if daemons running in new mode,\n");
- printf(" or 1 if groupd running in old mode.\n");
- printf(" Default %d\n", DEFAULT_GROUPD_COMPAT);
- printf(" -n Show all node information (with -g0)\n");
- printf(" -v Show extra event information (with -g1)\n");
- printf("\n");
-
- printf("dump Show debug log from groupd\n");
- printf("dump fence Show debug log from fenced (fence_tool dump)\n");
- printf("dump dlm Show debug log from dlm_controld (dlm_tool dump)\n");
- printf("dump gfs Show debug log from gfs_controld (gfs_control dump)\n");
- printf(" (dlm_tool plocks <name>)\n");
- printf("\n");
-}
-
-#define OPTION_STRING "g:hVvn"
-
-static void decode_arguments(int argc, char **argv)
-{
- int cont = 1;
- int optchar;
-
- while (cont) {
- optchar = getopt(argc, argv, OPTION_STRING);
-
- switch (optchar) {
-
- case 'g':
- opt_groupd_compat = 1;
- cfg_groupd_compat = atoi(optarg);
- break;
-
- case 'n':
- ls_all_nodes = 1;
- break;
-
- case 'v':
- verbose = 1;
- break;
-
- case 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case 'V':
- printf("%s %s (built %s %s)\n",
- prog_name, RELEASE_VERSION, __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- break;
-
- case ':':
- case '?':
- fprintf(stderr, "Please use '-h' for usage.\n");
- exit(EXIT_FAILURE);
- break;
-
- case EOF:
- cont = 0;
- break;
-
- default:
- fprintf(stderr, "unknown option: %c\n", optchar);
- exit(EXIT_FAILURE);
- break;
- };
- }
-
- while (optind < argc) {
- if (strcmp(argv[optind], "dump") == 0) {
- operation = OP_DUMP;
- opt_ind = optind + 1;
- break;
- } else if (strcmp(argv[optind], "ls") == 0 ||
- strcmp(argv[optind], "list") == 0) {
- operation = OP_LIST;
- opt_ind = optind + 1;
- break;
- } else if (strcmp(argv[optind], "compat") == 0) {
- operation = OP_COMPAT;
- opt_ind = optind + 1;
- break;
- }
- optind++;
- }
-
- if (!operation)
- operation = OP_LIST;
-}
-
-/* copied from grouip/daemon/gd_internal.h, must keep in sync */
-
-#define EST_JOIN_BEGIN 1
-#define EST_JOIN_STOP_WAIT 2
-#define EST_JOIN_ALL_STOPPED 3
-#define EST_JOIN_START_WAIT 4
-#define EST_JOIN_ALL_STARTED 5
-#define EST_LEAVE_BEGIN 6
-#define EST_LEAVE_STOP_WAIT 7
-#define EST_LEAVE_ALL_STOPPED 8
-#define EST_LEAVE_START_WAIT 9
-#define EST_LEAVE_ALL_STARTED 10
-#define EST_FAIL_BEGIN 11
-#define EST_FAIL_STOP_WAIT 12
-#define EST_FAIL_ALL_STOPPED 13
-#define EST_FAIL_START_WAIT 14
-#define EST_FAIL_ALL_STARTED 15
-
-static const char *ev_state_str(int state)
-{
- switch (state) {
- case EST_JOIN_BEGIN:
- return "JOIN_BEGIN";
- case EST_JOIN_STOP_WAIT:
- return "JOIN_STOP_WAIT";
- case EST_JOIN_ALL_STOPPED:
- return "JOIN_ALL_STOPPED";
- case EST_JOIN_START_WAIT:
- return "JOIN_START_WAIT";
- case EST_JOIN_ALL_STARTED:
- return "JOIN_ALL_STARTED";
- case EST_LEAVE_BEGIN:
- return "LEAVE_BEGIN";
- case EST_LEAVE_STOP_WAIT:
- return "LEAVE_STOP_WAIT";
- case EST_LEAVE_ALL_STOPPED:
- return "LEAVE_ALL_STOPPED";
- case EST_LEAVE_START_WAIT:
- return "LEAVE_START_WAIT";
- case EST_LEAVE_ALL_STARTED:
- return "LEAVE_ALL_STARTED";
- case EST_FAIL_BEGIN:
- return "FAIL_BEGIN";
- case EST_FAIL_STOP_WAIT:
- return "FAIL_STOP_WAIT";
- case EST_FAIL_ALL_STOPPED:
- return "FAIL_ALL_STOPPED";
- case EST_FAIL_START_WAIT:
- return "FAIL_START_WAIT";
- case EST_FAIL_ALL_STARTED:
- return "FAIL_ALL_STARTED";
- default:
- return "unknown";
- }
-}
-
-static const char *state_str(group_data_t *data)
-{
- static char buf[128];
-
- memset(buf, 0, sizeof(buf));
-
- if (!data->event_state && !data->event_nodeid)
- sprintf(buf, "none");
- else if (verbose)
- snprintf(buf, 127, "%s %d %llx %d",
- ev_state_str(data->event_state),
- data->event_nodeid,
- (unsigned long long)data->event_id,
- data->event_local_status);
- else
- snprintf(buf, 127, "%s", ev_state_str(data->event_state));
-
- return buf;
-}
-
-static int data_compare(const void *va, const void *vb)
-{
- const group_data_t *a = va;
- const group_data_t *b = vb;
- return a->level - b->level;
-}
-
-static int member_compare(const void *va, const void *vb)
-{
- const int *a = va;
- const int *b = vb;
- return *a - *b;
-}
-
-static int groupd_list(int argc, char **argv)
-{
- group_data_t data[MAX_GROUPS];
- int i, j, rv, count = 0, level, ret = 0;
- char *name;
- const char *state_header;
- int type_width = 16;
- int level_width = 5;
- int name_width = 32;
- int id_width = 8;
- int state_width = 12;
- int len, max_name = 4;
-
- memset(&data, 0, sizeof(data));
-
- if (opt_ind && opt_ind < argc) {
- level = atoi(argv[opt_ind++]);
- name = argv[opt_ind];
-
- rv = group_get_group(level, name, data);
- count = 1;
-
- /* don't output if there's no group at all */
- if (data[0].id == 0 && !strlen(data[0].name) &&
- !strlen(data[0].client_name)) {
- fprintf(stderr, "groupd has no information about "
- "the specified group\n");
- return 1;
- }
- /* If we wanted a specific group but we are not
- joined, print it out - but return failure to
- the caller */
- if (data[0].member != 1)
- ret = 1;
- } else
- rv = group_get_groups(MAX_GROUPS, &count, data);
-
- if (rv < 0)
- return rv;
-
- if (!count)
- return 0;
-
- for (i = 0; i < count; i++) {
- len = strlen(data[i].name);
- if (len > max_name)
- max_name = len;
- }
- name_width = max_name + 1;
-
- if (verbose)
- state_header = "state node id local_done";
- else
- state_header = "state";
-
- qsort(&data, count, sizeof(group_data_t), data_compare);
-
- for (i = 0; i < count; i++) {
- if (!i)
- printf("%-*s %-*s %-*s %-*s %-*s\n",
- type_width, "type",
- level_width, "level",
- name_width, "name",
- id_width, "id",
- state_width, state_header);
-
- printf("%-*s %-*d %-*s %0*x %-*s\n",
- type_width, data[i].client_name,
- level_width, data[i].level,
- name_width, data[i].name,
- id_width, data[i].id,
- state_width, state_str(&data[i]));
-
- qsort(&data[i].members, data[i].member_count,
- sizeof(int), member_compare);
-
- printf("[");
- for (j = 0; j < data[i].member_count; j++) {
- if (j != 0)
- printf(" ");
- printf("%d", data[i].members[j]);
- }
- printf("]\n");
- }
- return ret;
-}
-
-#if 0
-static int print_header_done;
-
-static int fenced_node_compare(const void *va, const void *vb)
-{
- const struct fenced_node *a = va;
- const struct fenced_node *b = vb;
-
- return a->nodeid - b->nodeid;
-}
-
-static void print_header(void)
-{
- if (print_header_done)
- return;
- print_header_done = 1;
-
- printf("type level name id state\n");
-}
-
-static void fenced_list(void)
-{
- struct fenced_domain d;
- struct fenced_node nodes[MAX_NODES];
- struct fenced_node *np;
- int node_count;
- int rv, j;
-
- rv = fenced_domain_info(&d);
- if (rv < 0)
- return;
-
- print_header();
-
- printf("fence 0 %-*s %08x %d\n",
- 16, "default", 0, d.state);
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
-
- rv = fenced_domain_nodes(FENCED_NODES_MEMBERS, MAX_NODES,
- &node_count, nodes);
- if (rv < 0 || !node_count)
- goto do_nodeids;
-
- qsort(&nodes, node_count, sizeof(struct fenced_node),
- fenced_node_compare);
-
- do_nodeids:
- printf("[");
- np = nodes;
- for (j = 0; j < node_count; j++) {
- if (j)
- printf(" ");
- printf("%d", np->nodeid);
- np++;
- }
- printf("]\n");
-}
-
-static int dlmc_node_compare(const void *va, const void *vb)
-{
- const struct dlmc_node *a = va;
- const struct dlmc_node *b = vb;
-
- return a->nodeid - b->nodeid;
-}
-
-static void dlm_controld_list(void)
-{
- struct dlmc_lockspace lss[MAX_LS];
- struct dlmc_node nodes[MAX_NODES];
- struct dlmc_node *np;
- struct dlmc_lockspace *ls;
- char *name = NULL;
- int node_count;
- int ls_count;
- int rv;
- int i, j;
-
- memset(lss, 0, sizeof(lss));
-
- if (name) {
- rv = dlmc_lockspace_info(name, lss);
- if (rv < 0)
- return;
- ls_count = 1;
- } else {
- rv = dlmc_lockspaces(MAX_LS, &ls_count, lss);
- if (rv < 0)
- return;
- }
-
- for (i = 0; i < ls_count; i++) {
- ls = &lss[i];
-
- if (!i)
- print_header();
-
- printf("dlm 1 %-*s %08x %x\n",
- 16, ls->name, ls->global_id, ls->flags);
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
-
- rv = dlmc_lockspace_nodes(ls->name, DLMC_NODES_MEMBERS,
- MAX_NODES, &node_count, nodes);
- if (rv < 0 || !node_count)
- goto do_nodeids;
-
- qsort(nodes, node_count, sizeof(struct dlmc_node),
- dlmc_node_compare);
-
- do_nodeids:
- printf("[");
- np = nodes;
- for (j = 0; j < node_count; j++) {
- if (j)
- printf(" ");
- printf("%d", np->nodeid);
- np++;
- }
- printf("]\n");
- }
-}
-
-static int gfsc_node_compare(const void *va, const void *vb)
-{
- const struct gfsc_node *a = va;
- const struct gfsc_node *b = vb;
-
- return a->nodeid - b->nodeid;
-}
-
-static void gfs_controld_list(void)
-{
- struct gfsc_mountgroup mgs[MAX_MG];
- struct gfsc_node nodes[MAX_NODES];
- struct gfsc_node *np;
- struct gfsc_mountgroup *mg;
- char *name = NULL;
- int node_count;
- int mg_count;
- int rv;
- int i, j;
-
- memset(mgs, 0, sizeof(mgs));
-
- if (name) {
- rv = gfsc_mountgroup_info(name, mgs);
- if (rv < 0)
- return;
- mg_count = 1;
- } else {
- rv = gfsc_mountgroups(MAX_MG, &mg_count, mgs);
- if (rv < 0)
- return;
- }
-
- for (i = 0; i < mg_count; i++) {
- mg = &mgs[i];
-
- if (!i)
- print_header();
-
- printf("gfs 2 %-*s %08x %x\n",
- 16, mg->name, mg->global_id, mg->flags);
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
-
- rv = gfsc_mountgroup_nodes(mg->name, GFSC_NODES_MEMBERS,
- MAX_NODES, &node_count, nodes);
- if (rv < 0 || !node_count)
- goto do_nodeids;
-
- qsort(nodes, node_count, sizeof(struct gfsc_node),
- gfsc_node_compare);
-
- do_nodeids:
- printf("[");
- np = nodes;
- for (j = 0; j < node_count; j++) {
- if (j)
- printf(" ");
- printf("%d", np->nodeid);
- np++;
- }
- printf("]\n");
- }
-}
-#endif
-
-static int connect_daemon(const char *path)
-{
- struct sockaddr_un sun;
- socklen_t addrlen;
- int rv, fd;
-
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (fd < 0)
- goto out;
-
- memset(&sun, 0, sizeof(sun));
- sun.sun_family = AF_UNIX;
- strcpy(&sun.sun_path[1], path);
- addrlen = sizeof(sa_family_t) + strlen(sun.sun_path+1) + 1;
-
- rv = connect(fd, (struct sockaddr *) &sun, addrlen);
- if (rv < 0) {
- close(fd);
- fd = rv;
- }
- out:
- return fd;
-}
-
-static void groupd_dump_debug(int argc, char **argv, char *inbuf)
-{
- char outbuf[GROUPD_MSGLEN];
- int rv, fd;
-
- fd = connect_daemon(GROUPD_SOCK_PATH);
- if (fd < 0)
- return;
-
- memset(outbuf, 0, sizeof(outbuf));
- sprintf(outbuf, "dump");
-
- rv = do_write(fd, outbuf, sizeof(outbuf));
- if (rv < 0) {
- printf("dump write error %d errno %d\n", rv, errno);
- return;
- }
-
- do_read(fd, inbuf, GROUPD_DUMP_SIZE);
-
- close(fd);
-}
-
-int main(int argc, char **argv)
-{
- int rv, version = 0;
-
- prog_name = argv[0];
- decode_arguments(argc, argv);
-
- switch (operation) {
- case OP_COMPAT:
- rv = group_get_version(&version);
- if (rv < 0)
- version = -1;
-
- switch (version) {
- case -1:
- break;
- case -EAGAIN:
- printf("groupd compatibility mode 2 (pending)\n");
- break;
- case GROUP_LIBGROUP:
- printf("groupd compatibility mode 1\n");
- break;
- case GROUP_LIBCPG:
- printf("groupd compatibility mode 0\n");
- break;
- default:
- printf("groupd compatibility mode %d\n", version);
- break;
- }
-
- if (rv < 0)
- exit(EXIT_FAILURE);
- break;
-
- case OP_LIST:
-
- rv = group_get_version(&version);
- if (rv < 0)
- version = -1;
-
- switch (version) {
- case -1:
- version = GROUP_LIBCPG;
- break;
- case -EAGAIN:
- printf("groupd compatibility mode 2 (pending)\n");
- break;
- case GROUP_LIBGROUP:
- printf("groupd compatibility mode 1\n");
- break;
- case GROUP_LIBCPG:
- printf("groupd compatibility mode 0\n");
- break;
- default:
- printf("groupd compatibility mode %d\n", version);
- break;
- }
-
- if ((cfg_groupd_compat == 0) ||
- (cfg_groupd_compat == 2 && version == GROUP_LIBCPG)) {
- /* show the new cluster3 data (from daemons) in
- the new daemon-specific format */
-
- if (verbose || ls_all_nodes) {
- system("fence_tool ls -n");
- system("dlm_tool ls -n");
- system("gfs_control ls -n");
- } else {
- system("fence_tool ls");
- system("dlm_tool ls");
- system("gfs_control ls");
- }
-
- if (version == GROUP_LIBGROUP)
- printf("Run 'group_tool ls -g1' for groupd information.\n");
- break;
- }
-
- if ((cfg_groupd_compat == 1) ||
- (cfg_groupd_compat == 2 && version == GROUP_LIBGROUP)) {
- /* show the same old cluster2 data (from groupd)
- in the same old format as cluster2 */
-
- groupd_list(argc, argv);
-
- if (version == GROUP_LIBCPG)
- printf("Run 'group_tool ls -g0' for daemon information.\n");
- break;
- }
-
-#if 0
- /* do we want to add an option that will use these functions
- to "fake" new cluster3 data in the old cluster2 format? */
- fenced_list();
- dlm_controld_list();
- gfs_controld_list();
-#endif
-
- case OP_DUMP:
- if (opt_ind && opt_ind < argc) {
- if (!strncmp(argv[opt_ind], "gfs", 3)) {
- system("gfs_control dump");
- }
-
- if (!strncmp(argv[opt_ind], "dlm", 3)) {
- system("dlm_tool dump");
- }
-
- if (!strncmp(argv[opt_ind], "fence", 5)) {
- system("fence_tool dump");
- }
-
- if (!strncmp(argv[opt_ind], "plocks", 6)) {
- fprintf(stderr, "use dlm_tool command\n");
- }
- } else {
- char rbuf[GROUPD_DUMP_SIZE];
-
- memset(rbuf, 0, sizeof(rbuf));
-
- groupd_dump_debug(argc, argv, rbuf);
-
- do_write(STDOUT_FILENO, rbuf, strlen(rbuf));
- }
-
- break;
- }
-
- return 0;
-}
-
diff --git a/make/binding-passthrough.mk b/make/binding-passthrough.mk
deleted file mode 100644
index 5f3a1bb..0000000
--- a/make/binding-passthrough.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-all: ${SUBDIRS}
-
-%:
- set -e && \
- for i in ${SUBDIRS}; do \
- ${MAKE} -C $$i -f Makefile.bindings $@; \
- done
diff --git a/make/clean.mk b/make/clean.mk
deleted file mode 100644
index 9f81fdd..0000000
--- a/make/clean.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-generalclean:
- rm -rf *~* *.o *.a *.so *.so.* a.out *.po *.s *.Tpo *.pyc
- rm -rf core core.* .depend cscope.* *.orig *.rej
- rm -rf linux .*.o.cmd .*.ko.cmd *.mod.c .tmp_versions
- rm -rf Module.symvers Module.markers .*.o.d modules.order
- rm -rf ${TARGET} ${TARGETS} ${TARGET}_test *.pc
- rm -rf ${TARGET1} ${TARGET2} ${TARGET3} ${TARGET4} ${TARGET5} ${TARGET6}
diff --git a/make/cobj.mk b/make/cobj.mk
deleted file mode 100644
index 514e487..0000000
--- a/make/cobj.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-ifdef outoftreebuild
-
-%.o: $(S)/%.c
- cd $(S) > /dev/null 2>&1 && \
- src=$(shell basename $<) && \
- $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(REENT_CFLAGS) -c -o $(O)/$@ $$src && \
- cd - >/dev/null 2>&1;
-
-# used by dlm/libdlm
-%_lt.o: $(S)/%.c
- cd $(S) > /dev/null 2>&1 && \
- src=$(shell basename $<) && \
- $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $(O)/$@ $$src && \
- cd - >/dev/null 2>&1;
-
-# used by rgmanager/src/daemons
-%-noccs.o: $(S)/%.c
- cd $(S) > /dev/null 2>&1 && \
- src=$(shell basename $<) && \
- $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(NOCCS_CFLAGS) -c -o $(O)/$@ $$src && \
- cd - >/dev/null 2>&1;
-
-else
-%.o: $(S)/%.c
- src=$(shell basename $<) && \
- $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(REENT_CFLAGS) -c -o $@ $$src
-
-# used by dlm/libdlm
-%_lt.o: $(S)/%.c
- src=$(shell basename $<) && \
- $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $$src
-
-# used by rgmanager/src/daemons
-%-noccs.o: $(S)/%.c
- src=$(shell basename $<) && \
- $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(NOCCS_CFLAGS) -c -o $@ $$src
-
-endif
diff --git a/make/copyright.cf b/make/copyright.cf
deleted file mode 100644
index 3801aa9..0000000
--- a/make/copyright.cf
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __COPYRIGHT_DOT_CF__
-#define __COPYRIGHT_DOT_CF__
-
-#define REDHAT_COPYRIGHT "Copyright (C) Red Hat, Inc. 2004-2010 All rights reserved."
-
-#endif /* __COPYRIGHT_DOT_CF__ */
diff --git a/make/defines.mk.input b/make/defines.mk.input
deleted file mode 100644
index 919697f..0000000
--- a/make/defines.mk.input
+++ /dev/null
@@ -1,80 +0,0 @@
-# Install Locations
-prefix ?= ${DESTDIR}@PREFIX@
-sbindir ?= ${DESTDIR}@SBINDIR@
-relativesbin ?= @RELATIVESBIN@
-initddir ?= ${DESTDIR}@INITDDIR@
-libdir ?= ${DESTDIR}@LIBDIR@
-libexecdir ?= ${DESTDIR}@LIBEXECDIR@
-sharedir ?= ${DESTDIR}@SHAREDIR@
-docdir ?= ${DESTDIR}@DOCDIR@
-logdir ?= ${DESTDIR}@LOGDIR@
-logrotatedir ?= ${DESTDIR}@LOGROTATEDIR@
-mandir ?= ${DESTDIR}@MANDIR@
-incdir ?= ${DESTDIR}@INCDIR@
-notifyddir ?= ${DESTDIR}@CONFDIR@/cman-notify.d
-pkgconfigdir ?= ${DESTDIR}@LIBDIR@/pkgconfig
-
-# Build information
-
-# C Compiler defaults
-CC = @CC@
-AR = ar
-RANLIB = ranlib
-
-CFLAGS += @CFLAGS@ -I@SRCDIR@/make
-CFLAGS += -DDEFAULT_CONFIG_DIR=\"@CONFDIR@\" -DDEFAULT_CONFIG_FILE=\"@CONFFILE@\"
-CFLAGS += -DLOGDIR=\"@LOGDIR@\" -DSYSLOGFACILITY=@SYSLOGFACILITY@ -DSYSLOGLEVEL=@SYSLOGLEVEL@
-LDFLAGS += @LDFLAGS@
-
-SRCDIR = @SRCDIR@
-OBJDIR = @OBJDIR@
-
-KERNEL_SRC = @KERNEL_SRC@
-ccsincdir ?= @CCSINCDIR@
-ccslibdir ?= @CCSLIBDIR@
-cmanincdir ?= @CMANINCDIR@
-cmanlibdir ?= @CMANLIBDIR@
-dlmincdir ?= @DLMINCDIR@
-dlmlibdir ?= @DLMLIBDIR@
-dlmcontrolincdir ?= @DLMCONTROLINCDIR@
-dlmcontrollibdir ?= @DLMCONTROLLIBDIR@
-fenceincdir ?= @FENCEINCDIR@
-fencelibdir ?= @FENCELIBDIR@
-fencedincdir ?= @FENCEDINCDIR@
-fencedlibdir ?= @FENCEDLIBDIR@
-logtincdir ?= @LOGTINCDIR@
-logtlibdir ?= @LOGTLIBDIR@
-ncursesincdir ?= @NCURSESINCDIR@
-ncurseslibdir ?= @NCURSESLIBDIR@
-slangincdir ?= @SLANGINCDIR@
-slanglibdir ?= @SLANGLIBDIR@
-corosyncincdir ?= @COROSYNCINCDIR@
-corosynclibdir ?= @COROSYNCLIBDIR@
-openaisincdir ?= @OPENAISINCDIR@
-openaislibdir ?= @OPENAISLIBDIR@
-corosyncbin ?= @COROSYNCBIN@
-ldapincdir ?= @LDAPINCDIR@
-ldaplibdir ?= @LDAPLIBDIR@
-zlibincdir ?= @ZLIBINCDIR@
-zliblibdir ?= @ZLIBLIBDIR@
-contrib_code ?= @ENABLE_CONTRIB@
-disable_dbus ?= @DISABLE_DBUS@
-without_common ?= @DISABLE_COMMON@
-without_config ?= @DISABLE_CONFIG@
-without_cman ?= @DISABLE_CMAN@
-without_dlm ?= @DISABLE_DLM@
-without_group ?= @DISABLE_GROUP@
-without_fence ?= @DISABLE_FENCE@
-without_rgmanager ?= @DISABLE_RGMANAGER@
-without_bindings ?= @DISABLE_BINDINGS@
-
-THISDIR = $(shell echo $(CURDIR) | sed -e 's|$(OBJDIR)/||g')
-S=$(SRCDIR)/$(THISDIR)
-O=$(OBJDIR)/$(THISDIR)
-
-outoftreebuild ?= @OUTOFTREEBUILD@
-
-CONFDIR=@CONFDIR@
-CONFFILE=@CONFFILE@
-
-UNINSTALL = perl @SRCDIR@/scripts/uninstall.pl
diff --git a/make/install.mk b/make/install.mk
deleted file mode 100644
index 49ca678..0000000
--- a/make/install.mk
+++ /dev/null
@@ -1,92 +0,0 @@
-install:
-ifdef LIBDIRT
- install -d ${libdir}
- install -m644 ${LIBDIRT} ${libdir}
-endif
-ifdef LIBSYMT
- cp -a ${LIBSYMT} ${libdir}
-endif
-ifdef INCDIRT
- install -d ${incdir}
- set -e; \
- for i in ${INCDIRT}; do \
- install -m644 $(S)/$$i ${incdir}; \
- done
-endif
-ifdef FORCESBINT
- mkdir -p ${DESTDIR}/sbin
- install ${FORCESBINT} ${DESTDIR}/sbin
-endif
-ifdef SBINDIRT
- install -d ${sbindir}
- install -m755 ${SBINDIRT} ${sbindir}
-endif
-ifdef SBINSYMT
- install -d ${sbindir}
- cp -a ${SBINSYMT} ${sbindir}
-endif
-ifdef LCRSOT
- install -d ${libexecdir}/lcrso
- install -m644 ${LCRSOT} ${libexecdir}/lcrso
-endif
-ifdef INITDT
- install -d ${initddir}
- set -e; \
- for i in ${INITDT}; do \
- if [ -f $$i ]; then \
- install -m755 $$i ${initddir}; \
- else \
- install -m755 $(S)/$$i ${initddir}; \
- fi; \
- done
-endif
-ifdef UDEVT
- install -d ${DESTDIR}/lib/udev/rules.d
- set -e; \
- for i in ${UDEVT}; do \
- install -m644 $(S)/$$i ${DESTDIR}/lib/udev/rules.d; \
- done
-endif
-ifdef DOCS
- install -d ${docdir}
- set -e; \
- for i in ${DOCS}; do \
- install -m644 $(S)/$$i ${docdir}; \
- done
-endif
-ifdef LOGRORATED
- install -d ${logrotatedir}
- install -m644 ${LOGRORATED} ${logrotatedir}
-endif
-ifdef NOTIFYD
- install -d ${notifyddir}
- install -m755 ${NOTIFYD} ${notifyddir}
-endif
-ifdef PKGCONF
- install -d ${pkgconfigdir}
- install -m644 ${PKGCONF} ${pkgconfigdir}
-endif
-ifdef SHAREDIRTEX
- install -d ${sharedir}
- install -m755 ${SHAREDIRTEX} ${sharedir}
-endif
-ifdef SHAREDIRT
- install -d ${sharedir}
- install -m644 ${SHAREDIRT} ${sharedir}
-endif
-ifdef SHAREDIRSYMT
- install -d ${sharedir}
- cp -a ${SHAREDIRSYMT} ${sharedir}
-endif
-ifdef RELAXNGDIRT
- install -d ${sharedir}/relaxng
- install -m644 ${RELAXNGDIRT} ${sharedir}/relaxng
-endif
-ifdef MANTARGET
- set -e; \
- for i in ${MANTARGET}; do \
- p=`echo $$i | sed -e 's#.*\.##g'`; \
- install -d ${mandir}/man$$p; \
- install -m644 $$i ${mandir}/man$$p; \
- done
-endif
diff --git a/make/libs.mk b/make/libs.mk
deleted file mode 100644
index a4e9a12..0000000
--- a/make/libs.mk
+++ /dev/null
@@ -1,59 +0,0 @@
-# handle objects
-ifndef OBJS
- OBJS = $(TARGET).o
-endif
-
-# we always build the static version
-ifndef STATICLIB
- STATICLIB = $(TARGET).a
-endif
-
-# handle the shared version
-ifndef MAKESTATICLIB
- ifndef LIBDIRT
- LIBDIRT=$(TARGET).a \
- $(TARGET).so.$(SOMAJOR).$(SOMINOR)
- endif
- ifndef LIBSYMT
- LIBSYMT=$(TARGET).so \
- $(TARGET).so.$(SOMAJOR)
- endif
- ifndef INCDIRT
- INCDIRT=$(TARGET).h
- endif
- ifndef SHAREDLIB
- SHAREDLIB=$(TARGET).so.${SOMAJOR}.${SOMINOR}
- endif
- ifndef PKGCONF
- PKGCONF=$(TARGET).pc
- endif
-
-all: $(STATICLIB) $(SHAREDLIB) $(PKGCONF)
-
-$(SHAREDLIB): $(OBJS)
- $(CC) -shared -o $@ -Wl,-soname=$(TARGET).so.$(SOMAJOR) $^ $(LDFLAGS)
- ln -sf $(TARGET).so.$(SOMAJOR).$(SOMINOR) $(TARGET).so
- ln -sf $(TARGET).so.$(SOMAJOR).$(SOMINOR) $(TARGET).so.$(SOMAJOR)
-
-$(PKGCONF): $(S)/$(PKGCONF).in
- cat $(S)/$(PKGCONF).in | \
- sed \
- -e 's#@PREFIX@#${prefix}#g' \
- -e 's#@LIBDIR@#${libdir}#g' \
- -e 's#@INCDIR@#${incdir}#g' \
- -e 's#@VERSION@#${RELEASE_VERSION}#g' \
- > $@
-
-else
-
-all: $(STATICLIB)
-
-endif
-
-$(STATICLIB): $(OBJS)
- ${AR} cru $@ $^
- ${RANLIB} $@
-
-clean: generalclean
-
--include $(OBJS:.o=.Tpo)
diff --git a/make/official_release_version b/make/official_release_version
deleted file mode 100644
index 211c0c2..0000000
--- a/make/official_release_version
+++ /dev/null
@@ -1 +0,0 @@
-SONAME "3.0"
diff --git a/make/passthrough.mk b/make/passthrough.mk
deleted file mode 100644
index 979a86c..0000000
--- a/make/passthrough.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-all: ${SUBDIRS}
-
-%:
- set -e && \
- for i in ${SUBDIRS}; do \
- ${MAKE} -C $$i $@; \
- done
diff --git a/make/perl-binding-common.mk b/make/perl-binding-common.mk
deleted file mode 100644
index ad1ffcb..0000000
--- a/make/perl-binding-common.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-TARGET += Makefile \
- META.yml
-
-all: $(TARGET)
- ${MAKE} LD_RUN_PATH="";
-
-%.pm: $(S)/%.pm.in
- cat $< | \
- sed \
- -e 's/@VERSION@/${RELEASE_VERSION}/g' \
- > $@
-
-%.yml: $(S)/%.yml.in
- cat $< | \
- sed \
- -e 's/@VERSION@/${RELEASE_VERSION}/g' \
- > $@
-
-Makefile: META.yml $(PMTARGET)
- perl Makefile.PL INC='$(CFLAGS)' LIBS='$(LDFLAGS)' INSTALLDIRS=vendor
-
-install:
- ${MAKE} -f Makefile install
-
-uninstall:
- echo uninstall target not supported yet
-
-clean:
- -${MAKE} -f Makefile clean
- rm -f $(TARGET) Makefile.old *.d
diff --git a/make/release.mk b/make/release.mk
deleted file mode 100644
index 986ae71..0000000
--- a/make/release.mk
+++ /dev/null
@@ -1,160 +0,0 @@
-# NOTE: this make file snippet is only used by the release managers
-# to build official release tarballs, handle tagging and publish.
-#
-# this script is NOT "make -j" safe
-#
-# do _NOT_ use for anything else!!!!!!!!!
-
-# setup tons of vars
-
-# signing key
-gpgsignkey=0x6CE95CA7
-
-# project layout
-project=cluster
-projectver=$(project)-$(version)
-projecttar=$(projectver).tar
-projectgz=$(projecttar).gz
-projectbz=$(projecttar).bz2
-projectxz=$(projecttar).xz
-
-rgmproject=rgmanager
-rgmprojectver=$(rgmproject)-$(version)
-rgmprojecttar=$(rgmprojectver).tar
-rgmprojectgz=$(rgmprojecttar).gz
-rgmprojectbz=$(rgmprojecttar).bz2
-rgmprojectxz=$(rgmprojecttar).xz
-
-# temp dirs
-
-ifdef release
-reldir=release
-gitver=$(projectver)
-forceclean=clean
-else
-reldir=release-candidate
-gitver=HEAD
-forceclean=
-endif
-
-releasearea=$(shell pwd)/../$(projectver)-$(reldir)
-
-all: $(forceclean) checks setup tag tarballs changelog sha256 sign
-
-checks:
-ifeq (,$(version))
- @echo ERROR: need to define version=
- @exit 1
-endif
-ifeq (,$(oldversion))
- @echo ERROR: need to define oldversion=
- @exit 1
-endif
- @if [ ! -d .git ]; then \
- echo This script needs to be executed from top level cluster git tree; \
- exit 1; \
- fi
-
-setup: checks $(releasearea)
-
-$(releasearea):
- mkdir $@
-
-tag: setup $(releasearea)/tag-$(version)
-
-$(releasearea)/tag-$(version):
-ifeq (,$(release))
- @echo Building test release $(version), no tagging
-else
- git tag -a -m "$(projectver) release" $(projectver) HEAD
-endif
- @touch $@
-
-tarballs: tag
-tarballs: $(releasearea)/$(projecttar)
-tarballs: $(releasearea)/$(projectgz)
-tarballs: $(releasearea)/$(projectbz)
-tarballs: $(releasearea)/$(projectxz)
-tarballs: $(releasearea)/$(rgmprojecttar)
-tarballs: $(releasearea)/$(rgmprojectgz)
-tarballs: $(releasearea)/$(rgmprojectbz)
-tarballs: $(releasearea)/$(rgmprojectxz)
-
-$(releasearea)/$(projecttar):
- @echo Creating $(project) tarball
- rm -rf $(releasearea)/$(projectver)
- git archive \
- --format=tar \
- --prefix=$(projectver)/ \
- $(gitver) | \
- (cd $(releasearea)/ && tar xf -)
- cd $(releasearea) && \
- echo "VERSION \"$(version)\"" \
- >> $(projectver)/make/official_release_version && \
- tar cpf $(projecttar) $(projectver) && \
- rm -rf $(projectver)
-
-$(releasearea)/$(rgmprojecttar): $(releasearea)/$(projecttar)
- @echo Creating $(rgmproject) tarball
- cd $(releasearea) && \
- rm -rf $(projectver) $(rgmprojectver) && \
- tar xpf $(projecttar) && \
- mv $(projectver) $(rgmprojectver) && \
- cd $(rgmprojectver) && \
- rm -rf bindings cman common config contrib dlm fence group \
- doc/cluster_conf.html && \
- sed -i \
- -e 's#cluster_conf.html##g' \
- -e 's#README.licence.*#README.licence#g' doc/Makefile && \
- cd .. && \
- tar cpf $(rgmprojecttar) $(rgmprojectver) && \
- rm -rf $(rgmprojectver)
-
-$(releasearea)/%.gz: $(releasearea)/%
- @echo Creating $@
- cat $< | gzip -9 > $@
-
-$(releasearea)/%.bz2: $(releasearea)/%
- @echo Creating $@
- cat $< | bzip2 -c > $@
-
-$(releasearea)/%.xz: $(releasearea)/%
- @echo Creating $@
- cat $< | xz -z -9 > $@
-
-changelog: checks setup $(releasearea)/Changelog-$(version)
-
-$(releasearea)/Changelog-$(version): $(releasearea)/$(projecttar)
- git log $(project)-$(oldversion)..$(gitver) | \
- git shortlog > $@
- git diff --stat $(project)-$(oldversion)..$(gitver) >> $@
-
-sha256: changelog tarballs $(releasearea)/$(projectver).sha256
-
-$(releasearea)/$(projectver).sha256: $(releasearea)/Changelog-$(version)
- cd $(releasearea) && \
- sha256sum Changelog-$(version) *.gz *.bz2 *.xz | sort -k2 > $@
-
-sign: sha256 $(releasearea)/$(projectver).sha256.asc
-
-$(releasearea)/$(projectver).sha256.asc: $(releasearea)/$(projectver).sha256
- cd $(releasearea) && \
- gpg --default-key $(gpgsignkey) \
- --detach-sign \
- --armor \
- $<
-
-publish: sign
-ifeq (,$(release))
- @echo Nothing to publish
-else
- git push --tags origin
- cd $(releasearea) && \
- scp *.gz *.bz2 *.xz Changelog-* *sha256* \
- fedorahosted.org:$(project)
- @echo Hey you!.. yeah you looking somewhere else!
- @echo remember to update the wiki and send the email to cluster-devel and linux-cluster
-endif
-
-clean: checks
- rm -rf $(releasearea)
diff --git a/make/uninstall.mk b/make/uninstall.mk
deleted file mode 100644
index 3ca687f..0000000
--- a/make/uninstall.mk
+++ /dev/null
@@ -1,59 +0,0 @@
-uninstall:
-ifdef LIBDIRT
- ${UNINSTALL} ${LIBDIRT} ${libdir}
-endif
-ifdef LIBSYMT
- ${UNINSTALL} ${LIBSYMT} ${libdir}
-endif
-ifdef INCDIRT
- ${UNINSTALL} ${INCDIRT} ${incdir}
-endif
-ifdef FORCESBINT
- ${UNINSTALL} ${FORCESBINT} ${DESTDIR}/sbin
-endif
-ifdef SBINDIRT
- ${UNINSTALL} ${SBINDIRT} ${sbindir}
-endif
-ifdef SBINSYMT
- ${UNINSTALL} ${SBINSYMT} ${sbindir}
-endif
-ifdef LCRSOT
- ${UNINSTALL} ${LCRSOT} ${libexecdir}/lcrso
-endif
-ifdef INITDT
- ${UNINSTALL} ${INITDT} ${initddir}
-endif
-ifdef UDEVT
- ${UNINSTALL} ${UDEVT} ${DESTDIR}/lib/udev/rules.d
-endif
-ifdef DOCS
- ${UNINSTALL} ${DOCS} ${docdir}
-endif
-ifdef LOGRORATED
- ${UNINSTALL} ${LOGRORATED} ${logrotatedir}
-endif
-ifdef NOTIFYD
- ${UNINSTALL} ${NOTIFYD} ${notifyddir}
-endif
-ifdef PKGCONF
- ${UNINSTALL} ${PKGCONF} ${pkgconfigdir}
-endif
-ifdef SHAREDIRTEX
- ${UNINSTALL} ${SHAREDIRTEX} ${sharedir}
-endif
-ifdef SHAREDIRT
- ${UNINSTALL} ${SHAREDIRT} ${sharedir}
-endif
-ifdef SHAREDIRSYMT
- ${UNINSTALL} ${SHAREDIRSYMT} ${sharedir}
-endif
-ifdef RELAXNGDIRT
- ${UNINSTALL} ${RELAXNGDIRT} ${sharedir}/relaxng
-endif
-ifdef MANTARGET
- set -e; \
- for i in ${MANTARGET}; do \
- p=`echo $$i | sed -e 's#.*\.##g'`; \
- ${UNINSTALL} $$i ${mandir}/man$$p; \
- done
-endif
diff --git a/rgmanager/ChangeLog b/rgmanager/ChangeLog
deleted file mode 100644
index 917500f..0000000
--- a/rgmanager/ChangeLog
+++ /dev/null
@@ -1,634 +0,0 @@
-2008-04-16 Fabio M. Di Nitto <fabbione at fabbione.net>
- * src/utils/clustat.c: Fix variable init
-
-2008-03-04 Lon Hohberger <lhh at redhat.com>
- * src/resources/ASEHAagent.sh, Makefile: Add Sybase failover agent
- * src/resources/oracledb.sh, Makefile: Add Oracle 10g failover agent
-
-2008-02-26 Lon Hohberger <lhh at redhat.com>
- * src/resources/ip.sh: Fix netmask handling in ip.sh
- * src/utils/clustat.c: Don't show estranged nodes if they're down
-2008-02-01 Lon Hohberger <lhh at redhat.com>
- * src/daemons/rg_state.c, slang_event.c, groups.c, restart_counter.c,
- include/restart_counter.h, resgroup.h,
- src/resources/default_event_script.sl: Allow restart counters to
- correctly work with central_processing. (#400211 / #431130)
-
-2008-01-25 Lon Hohberger <lhh at redhat.com>
- * src/daemons/rg_thread.c: Fix case that broke 'clusvcadm -e <service>
- -n <node>' case #430220
- * src/daemons/rg_state.c: Don't enable migrate-to-self (#430272)
-
-2008-01-02 Fabio M. Di Nitto <fabbione at ubuntu.com>
- * src/resources/ocf-shellfuncs: Add interpreter.
-
-2007-12-30 Fabio M. Di Nitto <fabbione at ubuntu.com>
- * src/daemons/rg_state.c, include/resgroup.h, src/clulib/alloc.c:
- Fix building when -DDEBUG is defined.
-
-2007-12-24 Fabio M. Di Nitto <fabbione at ubuntu.com>
- * src/clulib/vft.c: Change ifdef to fix build on parisc.
-
-2007-12-19 Lon Hohberger <lhh at redhat.com>
- * include/res-ocf.h: Fix typo
- * src/daemons/restree.c: Export reference counts to resource agents.
- * src/resources/clusterfs.sh: Use reference counts to ensure we
- don't unmount a GFS file system if it's in use by multiple services
- on the same node. #254111
- * src/resources/service.sh, default_event_script.sl: Add support for
- "soft" dependencies if central_processing is enabled
-
-2007-12-14 Lon Hohberger <lhh at redhat.com>
- (Misc central_events fixes)
- * Add return code for inability to run because of exclusive
- tag
- * Only initialize state once
- * Fix master-node failover.
- * Correctly return node after enable if request was forwarded
-
-2007-12-12 Lon Hohberger <lhh at redhat.com>
- * Misc changes; add missing ds.h
- * src/resources/default*.sl: Make clusvcadm -r go to a different
- node. Don't notice() that we're starting a service if it's
- disabled.
- * src/daemons/groups.c: Make clustat not interfere with startup
- when central processing is enabled
- * src/daemons/slang_event.c: Make clusvcadm correctly report
- service owner after relocate/restart/enable requests.
-
-2007-11-30 Lon Hohberger <lhh at redhat.com>
- * Commit RIND / S-Lang script engine [untested]
-
-[RHEL5 merged ChangeLog Entries]
-2007-11-30 Lon Hohberger <lhh at redhat.com>
- * src/resources/clusterfs.sh: Retry mount up to 3 times to avoid
- race condition during another process mounting a GFS volume
- * src/resources/vm.sh, service.sh: Add defaults for values.
- Make vm.sh work with more service attrs (max restarts)
- * src/utils/clustat.c: Make output of clustat terminal-width
- dependent
-
-2007-11-26 Lon Hohberger <lhh at redhat.com>
- * include/reslist.h: Add restart counters to resource node structure
- (intended for top-level resources, i.e. services, vms...)
- * include/restart_counter.h: Add header file for restart counter
- * src/daemons/Makefile: Fix build to include restart counters
- * src/daemons/restart_counter.c: Implement restart counters #247139
- * src/daemons/fo_domain.c, groups.c, restart_counter.c, resrules.c,
- restree.c, test.c: Glue for restart counters.
- * src/daemons/reslist.c: Glue for restart counters. Make expand_time
- parser more robust to allow things like '1h30m' as a time value.
- * src/daemons/main.c: Mark quorum disk offline in the correct
- place to avoid extraneous log messages
- * src/daemons/rg_state.c: Allow marking service as stopped if
- stuck in recover state. Make service which failed to start
- go to stopped state. Glue for restart counters.
- * src/resources/service.sh, vm.sh: Add parameters for restart
- counters #247139
-
-2007-11-14 Lon Hohberger <lhh at redhat.com>
- * src/utils/clulog.c: Make clulog honor rgmanager log levels
- (#289501)
- * src/clulib/vft.c: Fix #303981 - crash on rgmanager restart in some
- cases
- * man/clusvcadm.8: Remove references to clushutdown from man page;
- resolves #324151
- * src/resources/netfs.sh: Apply patch from Marco Ceci to fix #358161
- * src/resources/vm.sh: Make default migration policy live instead
- of pause for Xen virtual machines. Also make it configurable instead
- of static. Resolves #345871
-
-2007-11-13 Lon Hohberger <lhh at redhat.com>
- * src/resources/clusterfs.sh: Add support for self_fence operation
- to clusterfs resource agent
- * src/resources/service.sh: Add default values to service.sh
-
-2007-10-26 Lon Hohberger <lhh at redhat.com>
- * src/daemons/main.c, src/utils/clustat.c, clusvcadm.c:
- Fix #354391
-
-2007-09-25 Lon Hohberger <lhh at redhat.com>
- * src/daemons/restree.c: Apply patch to fix side case re: 229650
- Patch from Simone Gotti. Resolves: #229650
-[End RHEL5 merged changes]
-
-2007-08-30 Lon Hohberger <lhh at redhat.com>
- * src/daemons/restree.c, rg_state.c: Fix tree-restart bug
- This is another part of #229650
-
-2007-08-22 Fabio M. Di Nitto <fabbione at ubuntu.com>
- * include/list.h: Fix build with gcc-4.2.
-
-2007-08-15 Lon Hohberger <lhh at redhat.com>
- * src/utils/clustat.c: Remove uninitialized var & fix logic /
- spotted by Ryan McCabe
-
-2007-08-09 Fabio M. Di Nitto <fabbione at ubuntu.com>
- * rgmanager/src/clulib/alloc.c: Undefine DEBUG when building on
- PARISC. __builtin_address needs the same love as IA64.
-
-2007-08-02 Lon Hohberger <lhh at redhat.com>
- * general: More fixes around #248727
- * include/reslist.h, src/daemons/restree.c: Make last-value be
- returned or resources which have been checked recently
- * src/daemons/groups.c: Make VMs use migrate semantics instead of
- relocate semantics when employing failover domain rules
- * src/daemons/nodeevent.c: Fix VMs ending up on wrong nodes when
- simultaneous boot occurs
- * src/daemons/rg_forward.c: Fix erroneous timeout
- * src/daemons/rg_state.c: Handle RG_STATE_MIGRATE in svc_advise_*
- Handle certain migration failures.
- * src/resources/vm.sh: Handle certain migration failures
-
-2007-07-31 Lon Hohberger <lhh at redhat.com>
- * general: Make VMs not change state when added/removed from the
- cluster config or bounce services/VMs when minor config changes
- are made. (#248727)
- * include/res-ocf.h: Add reconfigure operation
- * include/reslist.h: Add flags allowing reconfigurable options in
- resource agent metadata, and per-agent flags which allow resources
- to be added w/o initialization / removed w/o kill.
- * src/clulib/rg_strings.c: Add string definition for reconfigure op
- * src/daemons/groups.c: Allow no-init-on-add and no-kill-on-delete
- flags to work
- * src/daemons/reslist.c: Allow resource comparison to take into
- account reconfig flags and return a new value if the resource is
- reconfigurable
- * src/daemons/resrules.c: Code to support new flags
- * src/daemons/restree.c: Code to support reconfiguration operation
- * src/daemons/test.c: Code to support testing new reconfig ops and
- behaviors
- * src/resources/*: Add new flags to service and VM resource agents.
-
-2007-07-23 Lon Hohberger <lhh at redhat.com>
- * general: make threads exit with pthread_exit() so we can wrap/track them.
- Add internal statedump (SIGUSR1) support.
- * src/clulib/msg_cluster.c: Fix rare deadlock condition. Add dump support.
- * src/clulib/tmgr.c: Add thread wrappers so we can report threads in
- internal state dumps.
- * src/clulib/vft.c: Fix rare crash if vf_resolve_views gets called with
- NULL. Add dump support.
- * src/daemons/main.c: Fix minor memory leak in membership_update(). Fix
- crash-on-exit race. Don't exit if someone requests foreground mode.
- * src/daemons/rg_forward.c: Clean up forwarding logic and handle missed
- case (forward-to-self -> ERROR!)
- * src/daemons/rg_state.c: Move closing / free of contexts out of
- send_ret/send_response to the caller (where they belong). Don't let
- people relocate disabled services.
- * src/daemons/rg_thread.c: Don't loop forever if the thread exits before
- we notice that it's started.
- * src/daemons/clusvcadm.c: Fix error codes if you try to relocate when
- rgmanager isn't running
-
-2007-07-12 Marek Grac <mgrac at redhat.com>
- * src/resources/Makefile: Fix #245178 - install RA for named
-
-2007-07-10 Lon Hohberger <lhh at redhat.com>
- * src/daemons/rg_thread.c, groups.c: Make status queue max 1 instead
- of unbounded (resolves: 247488)
-
-2007-06-29 Lon Hohberger <lhh at redhat.com>
- * src/daemons/groups.c, rg_state.c: Make all test cases for #237144
- work correctly
-
-2007-06-27 Lon Hohberger <lhh at redhat.com>
- * Merge from RHEL5 branch.
- * src/daemons/vm.sh: Un-break migrate (#231692). Make status
- checks happen every 30 seconds instead of 30 minutes.
- * include/resgroup.h: Move inline recovery flags to a header file,
- add RG_STATUS_INQUIRY for locating virtual machines which may have
- migrated.
- * include/reslist.h: Change res_exec() back to using agent_op_str()
- inline so we can squelch errors while performing RG_STATUS_INQUIRY
- * src/clulib/rg_strings.c: Add new strings for new error code /
- request types
- * src/daemons/groups.c: Change group_migrate() to use the correct
- calling semantics
- * src/daemons/main.c, nodeevent.c: Clean up cases which could cause
- #244143
- * src/daemons/resrules.c: Clear up noise
- * src/daemons/restree.c: Squelch errors during RG_STATUS_INQUIRY
- Patch up inline service recovery (#229650)
- * src/daemons/rg_state.c: Don't let migrations or relocations to a
- node running exclusive services occur in the first place and return
- a useful error. (goes with #237144). Locate virtual machines (or
- generally, services with the 'migrate' ability) elsewhere in the
- cluster prior to trying to start one. Detect if someone migrates
- such a service without using the cluster tools (#232300)
- * src/daemons/test.c: Make rg_test do the right thing for migrate
- operations
-
-2007-06-21 Fabio M. Di Nitto <fabbione at ubuntu.com>
- * rgmanager/src/clulib/alloc.c: Undefine DEBUG when building on IA64.
- The __builtin_address functionality should be taken from libunwind
- but porting requires some work. For now use this workaround and
- also make sure to wrap STACKSIZE withing DEBUG.
-
-2007-06-14 Lon Hohberger <lhh at redhat.com>
- * include/resgroup.h: Fix size incompatibility on 32/64 bit mixed
- clusters. Put in stubs for intelligent handling of state sizes
- during a cluster upgrade.
-
-2007-06-14 Marek Grac <mgrac at redhat.com>
- * src/daemons/main.c, rg_state.c, rg_thread.c,
- src/utils/clusvcadm.c
- * #211469 - RFE: Flag (-F) for clusvcadm to respect failover domain
- * 'clusvcadm -e service00' works same as in RHEL4 (differs from RHEL5.0)
- * -F for freeze was changed to -Z
-
-2007-06-13 Lon Hohberger <lhh at redhat.com>
- * src/daemons/restree.c: Fix #229650 uninitialized bug
-
-2007-05-31 Lon Hohberger <lhh at redhat.com>
- * src/daemons/resrules.c: Fix #234249 - ignore obvious backup files
- in /usr/share/cluster when processing resource rules
- * src/daemons/restree.c, src/daemons/groups.c, include/reslist.h:
- Implement independent subtrees, per bug #229650
-
-2007-05-22 Lon Hohberger <lhh at redhat.com>
- * src/resources/SAPInstance, SAPDatabase: Add primary attrs
-
-2007-05-09 Lon Hohberger <lhh at redhat.com>
- * src/resources/Makefile: Install SAP agents
-
-2007-05-08 Lon Hohberger <lhh at redhat.com>
- * src/resources/SAPInstance, SAPDatabase: Add SAP resource agents
- from Alexander Krauth
-
-2007-04-27 Lon Hohberger <lhh at redhat.com>
- * include/resgroup.h, src/clulib/rg_strings.c src/daemons/groups.c,
- rg_state.c, rg_thread.c, src/utils/clustat.c, clusvcadm.c: Apply
- patch to implement service freeze/unfreeze from Simone Gotti
- * src/daemons/sbuf.c: Add simple buffer handlers for future use
- by svc_status_inquiry
-
-2007-04-27 Fabio M. Di Nitto <fabbione at ubuntu.com>
- * src/clulib/vft.c: Change ifdef to fix build on parisc.
-
-2007-04-26 Lon Hohberger <lhh at redhat.com>
- * src/daemons/reslist.c: Try all direct ancestors while
- performing run-time inheritance resolution #231521
-
-2007-04-26 Fabio M. Di Nitto <fabbione at ubuntu.com>
- * src/daemons/Makefile: use resrules-noccs in dtest build
- target.
-
-2007-04-19 Lon Hohberger <lhh at redhat.com>
- * src/daemons/groups.c, rg_state.c: Apply patch from Andrey
- Mirkin to fix bug #237144; prevents exclusive services from
- being accidentally (or intentionally) being started on the
- same node
- * src/resources/clusterfs.sh: Apply patch from Simone
- Gotti to fix logging errors in clusterfs.sh
- * src/daemons/main.c: Fix qdiskd being treated as an online
- cluster node
-
-2007-04-12 Lon Hohberger <lhh at redhat.com>
- * src/daemons/main.c: Fix watchdog race condition causing
- reboot; patch from Andrey Mirkin; bugzilla #236204
-
-2007-03-27 Lon Hohberger <lhh at redhat.com>
- * Merge patch from Crosswalk development team:
- * Scott Cannata
- * Henry Harris
- * Leonard Maiorani
-
-=====
-
-2006-10-25 Lon Hohberger <lhh at redhat.com>
- * src/resources/clusterfs.sh: Fix unmounting problem (#212074)
-
-2006-10-23 Lon Hohberger <lhh at redhat.com>
- * src/resources/xenvm.sh: Gone; replaced with vm.sh.
- * The C code parts: Fix deadlocks incurred while testing
- rgmanager on larger node counts. #211701
-
-2006-10-06 Lon Hohberger <lhh at redhat.com>
- * src/daemons/main.c: Fix #202492: provide rgmanager's view of
- who is running rgmanager to clustat.
- * src/daemons/groups.c: Fix tiny memory leak during configuration
- changes
- * include/resgroup.h: #202492: Flip unused RG_STATUS_INQUIRY to
- RG_STATUS_NODE.
- * src/utils/clustat.c: #202492: Send RG_STATUS_NODE to clurgmgrd
- in order to obtain rgmanager "group" status information
-
-2006-09-27 Lon Hohberger <lhh at redhat.com>
- * src/daemons/rg_state.c: Fix #208011 - failed->disabled state
- transition. Fix node ID type.
- * include/members.h: Add a third state to note that a node does
- not need to be fenced as a result of rgmanager crashing. Add protos
- for memb_set_state and member_online functions.
- * include/reslist.h: Fix type error; node IDs are 32-bit ints, not
- 64-bit ints.
- * src/clulib/members.c: Add member_set_state/online functions for
- quick checks and sets of the protected member list. Zero out
- the node structure prior to calling cman_get_nodeid so that we
- don't get ENOENT (fixed clustat bug where clustat didn't report
- the "local" flag). Fix node ID type.
- * src/daemons/fo_domain.c: Fix node ID type, fix shadow declaration
- of member_online
- * src/daemons/groups.c: Unfix logic error that wasn't broken in the
- first place.
- * src/daemons/main.c: Fix node ID types. Add fourth ("clean")
- param to node_event* to decide whether a node death is clean or not.
- Nodes get marked clean if we get an RG_EXITING message, otherwise,
- they are unclean, and we wait for fencing.
- * src/daemons/nodeevent.c: Add fourth param to node_event* to help
- decide if we need to wait for a node to be fenced or not. Fix
- node ID type.
- * src/utils/clustat.c: Fix logic error preventing nodes from properly
- being flagged. Apply patch from Fabio M. Di Nitto to fix bug where
- clustat -s foo wasn't getting expanded to service:foo
- * src/daemons/rg_forward.c, rg_thread.c: Make forwarding of enable
- to specified target node work (#202498)
-
-2006-09-01 Lon Hohberger <lhh at redhat.com>
- * include/resgroup.h: Add proto for rg_strerror
- * include/vf.h: Add proto for vf_invalidate (flushes vf cache)
- * src/clulib/rg_strings.c: Add rg_strerror function, define
- human-readable strings for rgmanager error values
- * src/clulib/vft.c: Add vf_invalidate (separate from vf_shutdown)
- * src/daemons/groups.c: Fix obvious logic error
- * src/daemons/main.c: Fix rg_doall() message during loss of quorum.
- Invalidate local VF cache and kill resource configurations on
- loss of quorum (#202497). Send RG_EQUORUM back to clustat/clusvcadm
- so that they report why they can't get information. Don't queue
- status checks if we've lost quorum. Add command line parameter to
- disable internal crash watchdog
- * src/utils/clustat.c, clusvcadm.c: Handle SIGPIPE, and produce
- useful errors if possible.
-
-2006-08-31 Marek Gr��c <mgrac at redhat.com>
- * src/daemons/restree.c: Fix #203720. Do not run backup copies (ends
- with ~) of resource agents.
- * src/resources/apache.*, mysql.*: Add Apache & MySQL resource agents
- * src/resources/utils/*: Add utility scripts for resource agents
-
-2006-08-21 Lon Hohberger <lhh at redhat.com>
- * src/daemons/main.c: Fix #202500 - simultaneous starts confuse
- rgmanager. This happened due to the fact that rgmanager was not
- correctly determining port listening status of other nodes on the
- first pass, and subsequent attempts to determine status of other
- nodes were not tried.
-
-2006-08-18 Lon Hohberger <lhh at redhat.com>
- * include/resgroup.h: Change ordering and add magic field to
- rgmanager state field (warning: breaks compatibility from 08/08 CVS!)
- * src/clulib/ckpt_state.c, src/daemons/rg_state.c: Fix bug
- preventing correct operation of ckpt operation after initial boot.
- Get rid of debug info.
- * src/daemons/groups,c, main.c: Fix #202499 - shutdown while handling
- transitions sometimes allows services to restart (due to not locking
- RGs locally)
- * src/resources/clusterfs.sh, fs.sh, nfsclient.sh: Add proper
- warning messages if status check fails
- * src/resources/ra-api-1-modified.dtd: Allow 'migrate' option
- * include/clulog.h, src/daemons/clulog.c: Fix default log levels so
- that they're LOG_NOTICE, and only one default is used (#200776)
-
-2006-08-08 Lon Hohberger <lhh at redhat.com>
- * src/clulib/members.c: Fix gained/lost list creation so that the
- count is actually nonzero (#201713)
- * src/daemons/main.c: Fix typo in debug information. Kill CMAN handle
- before doing a member list update. Don't call memb_online; just
- check the cn_member field (optimization). Don't process node event
- until the node actually closes port (#201713).
- * src/utils/clusvcadm.c: Fix relocation issues (#201711).
-
-2006-08-07 Lon Hohberger <lhh at redhat.com>
- * src/clulib/ckpt_state.c: Preliminary implementation of replacement
- for VF using AIS CKPT B.02.01 (w/ built-in test program)
- * include/cman-private.h: Clean up APIs (cman APIs return
- cman_handle_t, which is void*, should be using void ** all over)
- * include/message.h: Bump context count to 128, add destination
- node ID in header of packets.
- * src/clulib/alloc.c: If we alloc the same size, return the same
- block
- * src/clulib/cman.c: API cleanups
- * src/clulib/message.c: Add error checking to msg_print
- * src/clulib/msg_cluster.c: Check destination in header before
- processing message remove dup #define for MAX_CONTEXTS, add
- proto_error() macro for displaying protocol errors. Use 'max'
- instead of 'fd' for select(). Use correct var when assigning
- contexts. Fix CMAN handles. Return correct size from msg_send()
- requests.
- * src/clulib/msgtest.c: Fix CMAN handles
- * src/clulib/vft.c: Don't handle VF_CURRENT inside comms thread
- * src/daemons/main.c: Check to see if nodes are listening on our
- port before we consider them running. Handle VF_CURRENT requests
- from other nodes. Fail if we can't determine local node ID
- * src/daemons/rg_forward.c: Give 10 minutes for responses to
- forwarded requests.
- * src/daemons/rg_state.c: Shorten RG state names. Fix 'Uncertain'
- output line.
- * src/utils/clustat.c: Fix ccs_member_list() function.
-
-2006-05-23 Lon Hohberger <lhh at redhat.com>
- * src/daemons/members.c: Zap pad fields on copy-out
- * src/daemons/main.c: Give notice if skipping an event because of
- locked services. Call the self-watchdog init function
- * src/daemons/watchdog.c: Add Stanko Kupcevic's self-watchdog from
- CVS head (fixes #193247)
- * src/daemons/groups.c: Add debug messages. Actually count
- resgroups during node transition handling
- * src/daemons/rg_state.c: allow failover of stopping services if
- the owner died (#193255)
- * src/utils/clustat.c: fix typo, misc. usability problems (#192999)
-
-2006-05-16 Lon Hohberger <lhh at redhat.com>
- * src/resources/nfsclient.sh: Fix 189218 - nfsclient not matching
- wildcards correctly when checking status. Allow disabling of
- recovery for services where the nfs clients are ordered (this will
- cause a full service restart, but works)
- * src/resources/clusterfs.sh, fs.sh, svclib_nfslock, service.sh:
- Implement rudimentary atomic bomb-style NFS lock reclaim handling
- Needs compatible and correctly configured version of nfs-utils
- installed and running on the system. For clusterfs.sh, ensure
- that we flush buffers during service tear-down - regardless of
- whether or not we unmount the file system.
- * src/utils/clunfslock.sh: HA-callout program (/usr/sbin/clunfslock)
- for use with the rpc.statd -H parameter. Copies the client to all
- cluster-managed mounted file systems so that it will get lock
- reclaim notification on failover.
-
-2006-05-09 Lon Hohberger <lhh at redhat.com>
- * include/list.h: Prevent dereferencing curr if it's null for some
- reason
- * include/resgroup.h: Clean up alignment, add rgmanager lock/unlock
- message types
- * src/daemons/Makefile: Add nodeevent.o to the build for rgmanager
- * src/clulib/msgsimple.c: Misc code path cleanups
- * src/clulib/vft.c: Add local reads for fast clustat operation.
- * src/daemons/groups.c: Count all resource groups for all nodes
- in one pass, rather than one node per pass. Split queueing of
- status checks off so we never block the main thread. Mark services
- which have autostart=0 in the config as "disabled" to help remove
- confusion between "disabled", "stopped", and the no-longer-needed
- "stopped but behave like disabled" states. bz #182454 /
- #190234 / #190408
- * src/daemons/fo_domain.c: Add patch from Josef Whiter to
- implement no-failback option for a given FO domain - bz #189841
- * src/daemons/main.c: Queue node events for another thread to
- handle, so we never block the main thread. Also, implement
- cluster-wide service lock/unlock feature from clumanager 1.2.x
- - bz #175010
- * src/daemons/nodeevent.c: Split out node event queueing / handling
- in to a separate thread so the main thread does not block
- * src/daemons/rg_state.c: Return error codes if resource groups
- are locked.
- * src/daemons/rg_thread.c: Fix assertion failure causing segfault
- in extremely rare cases. Quash the rg queue during shutdown.
- - bz #181539
- * src/daemons/rg_state.c: Add fast local service state query to
- reduce unnecessary lock contention
- * src/daemons/groups.c: Handle request for expedited information
- from clustat.
- * src/daemons/main.c: Pass arg1 to send_rg_states() to enable fast
- clustat operation.
- * src/resources/fs.sh: Implement user/group quota support if
- enabled in the file system options
- * src/utils/clustat.c: Misc. error handling. Add single service /
- member output and add -Q to the help information. #185952.
- Added -f flag.
- * src/utils/clusvcadm.c: Implement client-side of #175010
- * src/utils/clustat.c: show transition time in clustat -x
- - bz #191398
- * src/resources/fs.sh: enable user/group quotas if enabled in the
- options attribute - bz #191182
- * init.d/rgmanager: fix typo - bz #191205
-
-
--------------
-
-2005-03-21 Lon Hohberger <lhh at redhat.com>
- * init.d/rgmanager, Makefile: Fix up init script and add Makefile
- so that the init script is properly installed #142754
- * src/daemons/*: Fixes for #150344, #151187: Relocate to same node
- returns failure, hang during shutdown if user relocate is in-flight.
- Fix service state getting stuck in "recoverable" on fail-to-start
- scenarios where other nodes failed (or no other node was available)
- Rename "resourcegroup" to "service" to be consistent with UI
- * src/resources/fs.sh, clusterfs.sh: Fix #151077: Force unmount broken
- * src/resources/netfs.sh: Fix #151091: netfs status broken
- * src/resources/resourcegroup.sh, service.sh: Remove resourcegroup,
- rename to service.sh
-
-2005-03-14 Lon Hohberger <lhh at redhat.com>
- * src/resources/clusterfs.sh, fs.sh: Make clusterfs actually work.
- Clean up fs.sh + clusterfs.sh "status" when mount reports none/
- devpets/usbdev/etc.
- * src/daemons/test.c: Add a 'rules' test function for printing
- resource rules to stdout.
- * src/daemons/reslist.c: Fix 151095
-
-2005-03-07 Lon Hohberger <lhh at redhat.com>
- * include/resgroup.h: Add STOP_USER so we can handle user
- STOP (instead of just DISABLE) requests. #150333
- * src/resources/fs.sh: umount should umount mount points, not
- devices. Handle symlinks to file system block devices. #150481
- * src/clulib/rg_strings.c: Add user stop string.
- * src/clulib/gettid.c: errno fix from trunk
- * src/clulib/vft.c: Connect timeout extension for VF
- * src/daemons/main.c: Separate connect + login. GuLM doesn't know
- about SGs.
- * src/daemons/rg_state.c: Change stop handling. Add generic recover
- function.
- * src/daemons/rg_thread.c: Add support for RESTART, USER_STOP.
- #150330, #150333
- * src/utils/clusvcadm.c: Use USER_STOP to signal a user-called stop.
- #150333
-
-2005-03-02 Lon Hohberger <lhh at redhat.com>
- * include/clulog.h: Change default log level to INFO
- * include/resgroup.h: Add proto for "best_target_node"
- * src/clulib/clulog.c: Change log facility to LOG_DAEMON to match
- other cluster daemons (e.g. lock_gulmd)
- * src/daemons/groups.c: Add best_target_node, count_resource_groups.
- Implement missing autostart-disable feature and requested exclusive
- resource group feature. Store configuration view number so we can
- tell when the configuration changes.
- * src/daemons/main.c: Print node state transition messages before
- calling node_event(). Use do_status_checks() so we don't try to
- check services we're not running. Bump periodic status event
- queueing to 10 seconds instead of 5. Poll ccsd for config updates
- since we have no other way to find them. Fix bug preventing
- status checks when clustat -i 1 is running.
- * src/daemons/rg_state.c: Fix handle_relocate_req so that it uses
- best_target_node() correctly. Leave services which failed on all
- current nodes as 'stopped', so the next node transition will cause
- us to try to restart it automagically. Consider recovery policy
- when taking recovery action.
- * src/daemons/rg_thread.c: Use recovery routine instead of start.
- * src/daemons/restree.c: Fix tree delta updates.
- * src/resources/resourcegroup.sh: Add 'exclusive' parameter. Change
- 'autostart' to a boolean instead of string. Add recovery policy
- parameter.
- * src/utils/clusvcadm.c: Make "relocate to node X" work.
-
-2005-02-28 Lon Hohberger <lhh at redhat.com>
- * errors.txt: Remove random whitespace at the bottom.
- * include/resgroup.h: Add do_status_checks proto
- * include/rg_queue.h: Remove __ definitions so as not to conflict
- with glibc internals.
- * include/vf.h: Increase VF_COORD_TIMEOUT to something reasonable.
- * src/daemons/groups.c: Add do_status_checks(). We were previously
- queueing status checks for RGs that we didn't own. Not useful.
- * src/daemons/main.c: Fix for #149410.
- * src/daemons/rg_state.c: Fix various failover service problems.
- * src/resources/script.sh: Remove "recover" from generic script
- wrapper.
-
-=======================================================================
-
-2004-09-23 Lon Hohberger <lhh at redhat.com>
- * include/reslist.h: Add needstart/needstop/common flags for
- reconfiguration. Added RS_CONDSTART/CONDSTOP to perform "stop
- if needed/start if needed" operations after a resource [group]
- reconfiguration. Cleaned up structures. Added NO_CCS define for
- testing.
- * src/daemons/fo_domain.c: Added NO_CCS defines for testing.
- * src/daemons/main.c: Added reconfigure() stub function. Added
- testing support.
- * src/daemons/reslist.c: Added comparsion + primary-attr functions
- for resources. Add printout of needstart/stop in resource dump.
- * src/daemons/restree.c: Added resource list comparsion +
- resource tree comparison functions. Added condstart/stop to ops
- list. Added CONDSTART/CONDSTOP handling in res_op.
- * src/daemons/rg_locks.c: Added NO_CCS support for testing.
-
-2004-09-13 Lon Hohberger <lhh at redhat.com>
- * include/resgroup.h: Add a default check interval.
- * include/reslist.h: Add a recover operation, and put operations
- and checks together in each instantiated resource structure.
- * src/daemons/groups.c: Don't use the old rg_status() func --
- its internals have changed.
- * src/daemons/reslist.c: Duplicate the action structure of a
- parent resource type into an instantiated resource.
- * src/daemons/resrules.c: Find the actions with the correct
- path.
- * src/daemons/restree.c: Add depth parameter to res_exec. Add
- do_status - find the highest check/status level to perform given
- the elapsed time since another status operation was performed.
- Add a reference count each time a resource is started on a node.
- * src/daemons/rg_thread.c: Implement periodic status checks.
- Currently (in contrast to clumanager 1.2), these status checks
- are automatic and not configurable.
- * src/resources/*: Misc updates re: check intervals, new
- parameters, etc.
-
-2004-09-07 Lon Hohberger <lhh at redhat.com>
- * src/resources/group.sh: Add 'autostart' parameter to group
- entity
- * src/daemons/*: Add support for OCF 'action' specifications.
-
-2004-08-30 Lon Hohberger <lhh at redhat.com>
- * src/resources/*: Add status/monitor actions to metadata
- * include/list.h: Update to fix compiler warnings. This is not
- complete; it's better to add a 'field' to structures requiring
- list specs.
- * src/clulib/vft.c: Remove unnecessary pthread locks.
- * src/daemons/*: Misc. code cleanups.
-
-2004-08-12 Lon Hohberger <lhh at redhat.com>
- * global: prepare for RPM build
diff --git a/rgmanager/Makefile b/rgmanager/Makefile
deleted file mode 100644
index 8f730e3..0000000
--- a/rgmanager/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS=src man init.d
diff --git a/rgmanager/README b/rgmanager/README
deleted file mode 100644
index c8d73fe..0000000
--- a/rgmanager/README
+++ /dev/null
@@ -1,359 +0,0 @@
-This is a clustered resource group manager layered on top of Magma, a
-single API which can talk to multiple cluster infrastructures via their
-native APIs. This resource manager requires both magma and one or more
-plugins to be available (the dumb plugin will work just fine, but will
-only get you one node...).
-
-
-Note: I tend to use "service" and "resource group" to mean the same
-thing. While they are slightly different, "services" were simply
-collections of different things (IPs, file systems, etc.), as are
-resource groups.
-
-Introduction
-
-The resource manager is a daemon which provides failover of user-defined
-resource collected into groups. It is a direct descendent of the
-Service Manager from Red Hat Cluster Manager 1.2, which is a descendent
-of Cluster Manager 1.0, which is a descendent of Kimberlite 1.1.0.
-The primary reason for a rename was to avoid confusion with the Service
-Manager present in David Tiegland's Symmetric Cluster Architecture paper
-and software, with which this application must collaborate.
-
-The simplicity, ease of maintenance, and stability in the field has led
-us to attempt to preserve as much of the method of operations of Cluster
-Manager's Service Manager, but certain aspects needed to be removed in
-order to provide a more flexible framework for users.
-
-At this point, the resource manager is designed primarily for cold
-failover (= application has to restart entirely). This allows a lot of
-flexibility in the sense that most off-the-shelf applications can
-benefit from increased availability with minimal effort. However, it
-may be extended to support warm and even hot failover if necessary,
-though these models require often require application modification -
-which is outside the scope of this readme.
-
-
-Goals and Requirements
-
-(1) Supercede Red Hat Cluster Manager's capabilities with respect to
-service modification. Red Hat Cluster Manager's resource model was
-based on an old model from Kimberlite 1.1.0. In this model, services
-were entirely monolithic, and had to be disabled in order to be changed.
-This meant that if one had an NFS service with a list of clients and a
-new client was added, all other clients had to lose access in order to
-add the new client. In short, provide for on-line service modification
-and have intelligence about what to restart/reload after a new
-configuration is received. Note that this intelligence is not yet
-completed, but the framework exists for it to be completed.
-
-(2) Be able to use CMAN/DLM/SM and GuLM cluster infrastructures. This
-is done via magma.
-
-(3) Use CCS for all configuration data.
-
-(4) Be able to queue requests for services. This is forward-looking
-towards things such as event scheduling (e.g. disable this resource
-group at this time in the future).
-
-(5) Provide an extensible set of rules which define resource structure.
-This is accomplished by providing rule sets which essentially define how
-resources may be defined in CCS. These rule sets attempt to be OCF
-RA API compliant. This has the side effect of partially solving (1)
-for us.
-
-(6) Use a distributed model for resource group/service state. This is
-currently done with a port of the View-Formation code from Cluster
-Manager 1.2. Ideally, it would be nice to use LVBs in the DLM or GuLM
-to distribute this state; but it probably requires >64 bytes (DLM's
-limit). Another model is client-server like NFS, where clients tell
-the new master what resource groups they have. However, this has
-implications if the server fails and was running a RG.
-
-(7) Combination of 3 and 6 gives us: no dependency on shared storage.
-
-(8) Be practical. Try to follow the model from clumanager 1.x as much
-as possible without sacrificing flexibility. It should be easy to
-convert an existing clumanager 1.2 user to use this RM. While it will
-be impossible to perform a rolling upgrade from clumanager 1.2 to this
-RM, it should be easy to convert an existing installation's
-configuration information.
-
-(9) Try to be OCF compliant across how the resource scripts are written.
-While this is a goal, it is not a guarantee at this point.
-
-(10) Work with the same fencing model as clumanager and GFS (i.e.
-"top-down" - the infrastructure handles it). Resource-based fencing,
-for example, is specifically not a goal at this point.
-
-(11) Be scalable without being overly complex ;) Note that we're not
-very scalable at the moment (VF is too slow for this kind of thing)
-
-(12) Introduce other failover/balancing policies (instead of just
-failover domains).
-
-
-Directory Structure
-
-include/
-
-Include files
-
-src/daemons/
-
-The RM daemon and clurmtabd (from RHEL3), which keeps /var/lib/nfs/rmtab
-in sync with clustered exports, or tries to.
-
-src/utils/
-
-Home of various utilities including clustat and clusvcadm.
-
-src/clulib/
-
-Library functions which aren't necessarily tied to a specific daemon.
-This was more important in clumanager 1.2; and is mostly cruft at this
-point.
-
-src/resources/
-
-Shell scripts and resource XML rules for various resources. Includes
-a DTD to validate a given resource XML rule.
-
-
-Implementation - Handling of Client Requests
-
-The resource manager currently uses a threaded model which has a
-producer thread and a set of consumer threads with their own work
-queues.
-
- Client <--(result)---------+
- | |
- (req) |
- | [Handle request]
- | ^
- v |
-Listener --(req)--> Resource group thread
-
-In a typical example, the client sends a request to the listener thread.
-The listener accepts hands it off to a resource group queue and
-immediately resumes listening for requests. Queueing the request on a
-resource thread queue has a side effect of spawning a new resource group
-thread if one is needed. The resource group thread pulls the request
-off of its work queue and handles the request. After the request
-completes, the resource thread sends the result of the operation back to
-the client. If no other requests are pending and the last operation
-resulted in the resource group being in a non-running state (stopped,
-disabled, etc.), then the resource group thread cleans itself up and
-exits.
-
-The resource manager handles failed resource groups in a simplistic
-manner which is the same as how Red Hat Cluster Manager handled
-failover. If a resource group fails a status check, the resource
-manager stops the affected RG. If the 'STOP' operation succeeds, then
-the RM tries to restart the RG. If this succeeds, the RM is done.
-
-However, if it fails to restart/recover the resource group, it again
-stops the RG and attempts to determine the best-available online node
-based on the failover domain or (not implemented yet) least-loaded
-cluster member. If none are available, or all members fail to start the
-RG, the RG is disabled.
-
-
-Cluster Events
-
-Cluster events are provided by a cluster-abstraction library called
-Magma. Magma currently runs with CMAN/DLM, gulm, or no cluster
-infrastructure at all (e.g. one node, always-quorate-pseudo-cluster).
-
-Magma provides group membership lists, state of the cluster quorum (if
-one exists), cluster locking, and (in some cases), barriers - so the RM
-needs to implement none of the above.
-
-Cluster events are handed to the listener thread via a file descriptor,
-and can affect resource group states. For instance, when a member is no
-longer quorate, all resource groups are stopped immediately (and, quite
-normally, the member is fenced prior to this actually completing!).
-
-Whenever a node transition occurs (or in the SM case, a node joins the
-requisite service group), all RG states are evaluated to see if they
-should be moved about or started (or failed-over), depending on the
-failover domain (or other policies which are not yet implemented).
-
-
-The Resource Tree
-
-In clumanager 1.x (and Kimberlite, for that matter), the attributes of
-various resources attributes were read one by one, as required, inside
-of a large shell script. This had several benefits (hard dependency
-enforcment, maintenance, support, etc.), but had several drawbacks as
-well; the most important being flexibility.
-
-In contrast to clumanager 1.x, the resource groups are now modeled in
-the daemon's RAM as tree structures with all their requisite
-attributes loaded from CCS based on external XML rules.
-
-After a resource is started, it follows down the tree and starts all
-dependent children. Before a resource is stopped, all of its dependent
-children are first stopped. Because of this structure, it is possible
-to add or restart, for instance, an "NFS client" resource without
-affecting its parent "export" resource. By determining the delta
-between resource lists and/or resource trees, it's possible to use this
-information to automatically restart a node in the tree and all its
-dependent children in the event of a configuration change.
-
-The tree can be summarized as follows:
-
- group
- ip address...
- file system...
- NFS export...
- NFS client...
- samba share(s)...
- script...
-
-
-Resource Agents
-
-Resource agents are scripts or executables which handle operations for a
-given resource (such as start, stop, restart, etc.). See the OCF RA API
-v1.0 for more details on how the resource agents work:
-
- http://www.opencf.org/cgi-bin/viewcvs.cgi/specs/ra/
-
-The resource agents and handling should be OCF compliant (at least in
-how they are called), primarily because it is fairly nonsensical to
-require third party application developers to write multiple differing
-application scripts in order to have their application work in different
-cluster environments on an otherwise similar system [1].
-
-
-The XML Resource Rules
-
-The XML Resource Rules are encapsulated in the resource agent scripts,
-which attempt to follow the OCF RA API 1.0. The RA API, however, does
-not work with the goals of this project as it exists today, so there are
-a few extensions to the ra-api-1.dtd.
-
- * Addition of a 'required' tag parameter elements. This allows the UI
- and/or the resource group manager to determine if a resource is
- configured properly without having to ask the resource agent itself.
- * Addition of a 'primary' tag parameter elements. This allows the
- resource tree to reference resource instances using the 'ref='
- tag in the code.
- * Addition of an 'inherit' tag to allow resources to inherit a parent
- resources' parameters.
-
-Additionally, there is some data which is used in the 'special' element
-of the RA API DTD.
-
-Description of rgmanager-specific block.
-
-<!ELEMENT attributes>
-<!ATTLIST
- root (0|1) #IMPLIED
- maxinstances CDATA #IMPLIED>
-
- * root: This is the root resource type. This should only exist in the
- 'group' resource, generally.
- * maxinstances: This is the maximum number of instances in the resource
- tree this resource may exist.
-
-Description of a resource type or attribute.
-
-<!ELEMENT child EMPTY>
-<!ATTLIST child
- type CDATA #REQUIRED
- start CDATA #IMPLIED
- stop CDATA #IMPLIED>
-
-Describes a valid child rule type.
-
- * type: Resource type which is to be declared as a valid child for
- this resource type.
- * start: Start level of this child type. All resource children at
- level '1' are started before all resource children at level '2'.
- Valid values are 1-99.
- * stop: Stop level of this child type. All resource children at level
- '1' are stopped before all resource children at level '2'.
- Valid values are 1-99.
-
-
-Failover Domains
-
-A failover domain is an ordered subset of cluster members to which a
-resource group may be bound. The following is a list of semantics
-governing the options as to how the different configuration options
-affect the behavior of a resource group which is bound to a particular
-failover domain:
-
- * restricted domain: Resource groups bound to the domain may only run
- on cluster members which are also members of the failover domain. If
- no members of the failover domain are available, the resource group
- is placed in the stopped state.
-
- * unrestricted domain: Resource groups bound to this domain may run on
- all cluster members members, but will run on a member of the domain
- whenever one is available. This means that if a resource group is
- running outside of the domain and a member of the domain transitions
- online, the resource group will migrate to that cluster member.
-
- * ordered domain: Nodes in an ordered domain are assigned a priority
- level from 1-100, priority 1 being the highest and 100 being the
- lowest. A member of the highest priority group will run a resourece
- group bound to a given domain whenever one is online. This means
- that if member A has a higher priority than member B, the resource
- group will migrate to A if it was running on B if A transitions from
- offline to online.
-
- * unordered domain: Members of the domain have no order of preference;
- any member may run the resource group. Resource groups will always
- migrate to members of their failover domain whenever possible,
- however, in an unordered domain.
-
-Ordering and restriction are flags and may be combined in any way (ie,
-ordered+restricted, unordered+unrestricted, etc.). These combinations
-affect both where resource groups start after initial quorum formation
-and which cluster members will take over resource groups in the event
-that the resource group or the member running it has failed (without
-being recoverable on that member).
-
-
-Failover Domains (Examples)
-
-Given a cluster comprised of this set of members: {A, B, C, D, E, F, G}
-
-Ordered, restricted failover domain {A(1), B(2), C(3)}. A resource group
-'S' will always run on member 'A' whenever member 'A' is online and
-there is a quorum. If all members of {A, B, C} are offline, the
-resource group will be stopped. If the resource group is running on 'C'
-and 'A' transitions online, the resource group will migrate to 'A'.
-
-Unordered, restricted failover domain {A, B, C}. A service 'S' will only
-run if there is a quorum and at least one member of {A, B, C} is online.
-If another member of the domain transitions online, the service does not
-relocate.
-
-Ordered, unrestricted failover domain {A(1), B(2), C(3)}. A resource
-group 'S' will run whenever there is a quorum. If a member of the
-failover domain is online, the resource group will run on the highest
-ranking member. That is, if 'A' is online, the resource group will run
-on 'A'.
-
-Unordered, unrestricted failover domain {A, B, C}. This is also called a
-"Set of Preferred Members". When one or more members of the failover
-domain are online, the service will run on a nonspecific online member
-of the failover domain. If another member of the failover domain
-transitions online, the service does not relocate.
-
-
-
-Notes:
-
-[1] Lars Marowsky-Bree pointed this out; which makes perfect sense. The
-OCF RA API attempts to follow LSB with respect to how init-scripts
-handle starting/stopping/status of daemons and such, so it was directly
-in line with where we were going with this RM.
-
-[2] This is derived from the OCF RA metadata DTD:
-
- http://www.opencf.org/cgi-bin/viewcvs.cgi/specs/ra/ra-api-1.dtd
diff --git a/rgmanager/errors.txt b/rgmanager/errors.txt
deleted file mode 100644
index 0cda423..0000000
--- a/rgmanager/errors.txt
+++ /dev/null
@@ -1,552 +0,0 @@
-Service (Resource Group) Manager Errors
-
-Herein lie explanations as to the various errors and warnings that you may
-see while running the resource group manager. This is meant to be
-all-inclusive; if any error messages or warning messages are experienced
-which are not explained below, please file a bugzilla:
-
-http://bugzilla.redhat.com/bugzilla
-
-#1: Quorum Dissolved
-
-The cluster infrastructure has reported to the resource group manager that
-the local node and/or entire cluster is inquorate. At this point, all
-services and resources managed by the resource group manager are stopped
-and the resource group manager restarts, waiting for a quorum to form.
-
-If this node was disconnected, it should be evicted and fenced by the rest
-of the cluster. Nodes which become inquorate may reboot themselves.
-
-#2: Service <name> returned failure code. Last owner: <name>
-
-The resource group named <name> has failed to stop. This generally means
-that it may not be automatically recovered and that the system administrator
-must intervene in order to cleanly restart the service. Services which
-fail must first be disabled then re-enabled. However, be sure that all
-resources have been properly cleaned up first. Generally, a hard reset
-of the node on which the service failed will restore it to working order
-and is the safest measure to take prior to restarting the failed service.
-
-This, however, is not required.
-
-#3: Service <name> returned failure code. Last owner:
-<integer>
-
-Same as #2, but the node name was not determinable given the node ID.
-
-#4: Administrator intervention required.
-
-Only occurs after #2 or #3. Complaint stating that the administrator
-must take action after a service failed. See #2.
-
-#5: Couldn't connect to ccsd!
-
-The resource group manager was unable to connect to ccsd. This generally
-means that ccsd was not running at the time the resource group manager
-tried to connect. Starting ccsd generally solves this. If this does
-not solve it, try checking firewall rules to ensure that the connection
-to ccsd's port is not blocked. Additionally, it could be that there is
-a conflict between ccsd and the version of the system library (libccs) that
-rgmanager was built against.
-
-#6: Error loading services
-
-The resource group manager was unable to load configuration information
-from ccsd. This could mean a communication problem or an invalid
-configuration.
-
-This error is fatal; the resource group manager aborts.
-
-#7: Error building resource tree
-
-The resource group manager was unable to load configuration information
-from ccsd. This could mean a communication problem or an invalid
-configuration.
-
-This error is fatal; the resource group manager aborts.
-
-#8: Couldn't initialize services
-
-The resource group manager was unable to load configuration information
-from ccsd. This could mean a communication problem or an invalid
-configuration.
-
-#9: Couldn't connect to cluster
-
-The resource group manager was unable to find a plugin which was able to
-talk to the cluster infrastructure. Generally, this occurs when no cluster
-infrastruture is running. Try starting the preferred cluster infrastructure
-for your configuration (e.g. CMAN+DLM, GuLM) and restarting rgmanager.
-
-#10: Couldn't set up listen socket
-
-The resource group manager was unable to bind to its listening socket.
-This generally happens when there is already a resource group manager running,
-but it is possible for other applications to use the port that rgmanager
-wants to use for this purpose.
-
-#11: Couldn't set up VF listen socket
-
-The resource group manager was unable to bind to its listening socket which
-is used fo internal state distribution. This generally happens when there
-is already a resource group manager running, but it is possible for other
-applications to use the port that rgmanager wants to use for this purpose.
-
-#12: RG <name> failed to stop; intervention required
-
-The resource group manager has failed to cleanly stop a service.
-See #2 for actions to take.
-
-#13: Service <name> failed to stop cleanly
-
-The resource group manager has failed to cleanly stop a service after
-failing to start the same resource group during an enable or start operation.
-See #2 for actions to take.
-
-#14: Failed to send <integer> bytes to <integer>
-
-During a broadcast operation to all nodes, the view-formation library has
-failed to send a message to one of the nodes. This is generally recovered
-automatically.
-
-#15: rmtab_modified: stat: <error>
-
-The stat(2) function received an error while scanning for changes to
-/var/lib/nfs/rmtab. Though generally handled automatically, repeats of
-this kind of error could indicate a problem with /var/lib/nfs/rmtab.
-
-If repeated errors occur:
- * Ensure /var/lib/nfs exists and is a directory.
- * Ensure /var/lib/nfs/rmtab exists and is a regular file (not a directory)
-
-#16: Failed to reread rmtab: <error>
-
-Clurmtabd had trouble reading or parsing /var/lib/nfs/rmtab. This could
-mean that there is garbage in /var/lib/nfs/rmtab or that the internal
-format has changed or some problem with the filesystem. If the latter is
-suspected, please file a Bugzilla. Ensure you include your
-/var/lib/nfs/rmtab and version of rgmanager.
-
-#17: Failed to prune rmtab: <error>
-
-Clurmtabd failed to prune a new copy of /var/lib/nfs/rmtab against its
-specified mount point.
-
-#18: Failed to diff rbtab: <error>
-
-Clurmtabd failed to determine the differences, if any, between a previous
-copy of /var/lib/nfs/rmtab and the current data stored there.
-
-#19: (Obsolete)
-
-#20: Failed to set log level
-
-Clurmtabd failed to change its log level to the specified level. This
-is non-fatal. The side effect is that more or less verbose logging will
-be seen depending on whether the log level was increased or decreased.
-
-#21: Couldn't read/create <filename>
-
-Clurmtabd stores service-specific rmtab information in
-<mount_point>/.clumanager/rmtab so that when the service fails over,
-the new instance of clurmtabd on the other node can pick up and know which
-hosts already have mounted any NFS exports. This error could indicate that
-clients will receive ESTALE (Stale NFS file handle) after failover.
-
-#22: Failed to read <filename>: <error>
-
-Clurmtabd failed to read or parse <filename>. This could indicate garbage
-in that file, or another error. This could have side effects of ESTALEs
-being received by clients. The error should be indicative of the cause.
-
-#23: Failed to read /var/lib/nfs/rmtab: <error>
-
-Clurmtabd failed to read or parse <filename>. This could indicate garbage
-in that file, or another error. This could have side effects of ESTALEs
-being received by clients. The error should be indicative of the cause.
-
-#24: Failed to prune rmtab: <error>
-
-Clurmtabd failed to prune unrelated entries in /var/lib/nfs/rmtab. The
-error should be indicative of the cause.
-
-#25: Failed to write /var/lib/nfs/rmtab: <error>
-
-Clurmtabd failed to atomically write a new copy of /var/lib/nfs/rmtab after
-merging changes between private cluster data (<mount_point>/.clumanager/rmtab)
-and the system-wide copy (/var/lib/nfs/rmtab). The error should be indicative
-of the cause.
-
-#26: Failed to write <filename>: <error>
-
-Clurmtabd failed to atomically write a new copy of its private cluster data
-file after changes between it and the system-wide copy in
-(/var/lib/nfs/rmtab). The error should be indicative of the cause.
-
-#27: Couldn't initialize - exiting
-
-Clurmtabd failed to initialize for one reason or another. A previous
-error should indicate the reason why.
-
-#28: daemonize: <error>
-
-Clurmtabd failed to become a daemon. The possible reasons this could happen
-are documented in fork(2) and setsid(2).
-
-#29: rmtab_write_atomic: <error>
-
-Clurmtabd failed to atomically write a new copy of /var/lib/nfs/rmtab after
-merging changes between private cluster data (<mount_point>/.clumanager/rmtab)
-and the system-wide copy (/var/lib/nfs/rmtab). The error should be indicative
-of the cause.
-
-#30: Node <name> defined multiple times in domain <domain>
-
-This indicates a configuration error where a node <name> was defined more
-than once in a given failover domain <domain>. If this occurs, only the first
-entry for the node <name> will be used. Remove the duplicate copy and restart
-rgmanager on all nodes.
-
-#31: Domain <domain> defined multiple times
-
-This indicates a configuration error where a domain <domain> was defined
-more than once. Failover domains may not have duplicate names. If this
-occurs, the first one found will be used.
-
-#32: Code path error: Invalid return from node_in_domain()
-
-If this occurs, please file a Bugzilla.
-
-#33: Unable to obtain cluster lock: <error>
-
-This occurs while evaluating services after a node transition. If
-this occurs, the current service under evaluation will not be able
-to be checked for possible starting.
-
-Possible reasons obtaining a cluster lock would fail:
- * Loss of node/cluster quorum
- * Broken connection to GuLM/DLM
- * Error in magma-plugins package.
-
-#34: Cannot get status for service <name>
-
-This occurs while evaluating services after a node transition. The
-service <name> has an indeterminable state. This could indicate a
-bug with the data distribution subsystem, or an invalid service.
-
-#35: Unable to inform partner to start failback
-
-This occurs after a node transition where a node asks other nodes for
-services (resource groups) which it should own. This generally indicates
-a communication problem between the cluster nodes. If this occurs,
-services may not migrate to the node which just came online.
-
-#36: Cannot initialize services
-
-The resource group manager could not initialize services after a node
-transition. This is fatal, and rgmanager exits uncleanly afterward.
-
-#37: Error receiving message header
-
-This occurs after an incoming request causes the resource group manager to
-accept a new connection. After a new connection is received, there is a
-short amount of time during which to receive the message header. If this
-does not occur, the connection is dropped and the message (if any) is
-rejected.
-
-#38: Invalid magic: Wanted 0x<hex>, got 0x<hex>
-
-This occurs after an incoming request causes the resource group manager to
-accept a new connection. This could indicate a mismatched version between
-resource group managers or an unauthorized program attempting to communicate
-with the resource group manager. The connection is dropped and the message
-is rejected.
-
-#39: Error receiving entire request
-
-This occurs after an incoming request causes the service manager to
-accept a new connection. The amount of data received did not match the amount
-of data specified in the message header. This could indicate a mismatched
-version between service managers or an unauthorized program attempting
-to communicate with the service manager. The connection is dropped
-and the message is rejected.
-
-#40: Error replying to action request.
-
-A resource action request was received (enable/disable/etc.) while the
-resource groups were locked and we failed to reply properly to the waiting
-client connection.
-
-#41: Couldn't obtain lock for RG <name>: <error>
-
-While trying to report a failed service (resource group) to the other
-cluster members, we failed to obtain a cluster lock. This could indicate
-that the cluster quorum has dissolved, communication errors with the lock
-server, or other problems. The effect of this is, however, minimal; simply
-put, the #2 and #3 messages won't appear in the logs, so the last owner
-of the service will be unknown.
-
-See #33 for reasons as to why obtaining a lock might fail.
-
-#42: Cannot stop service <name>: Invalid State <integer>
-
-The service <name> could not be stopped. It was in an invalid state.
-This could indicate a bug in rgmanager.
-
-#43: Service <name> has failed on all applicable members; can not
-start.
-
-I don't know how to make this more verbose. The service must be disabled and
-enabled prior to being allowed to start. See #2 and #3 for more information.
-
-#44: Cannot start service <name>: Invalid State <integer>
-
-The service <name> could not be stopped. It was in an invalid state.
-This could indicate a bug in rgmanager.
-
-#45: Unable to obtain cluster lock: <error>
-
-This occurs while trying to determine the state of a resource group prior
-to starting it. If this occurs, the start operation will fail. The error
-should be indicative of the reason.
-
-See #33 for reasons as to why obtaining a lock might fail.
-
-#46: Failed getting status for RG <name>
-
-This occurs while trying to determine the state of a resource group prior
-to starting it. If this occurs, the start operation will fail.
-
-Generally, this indicates attempt to retrieve the current view of that
-resource group's state after quorum has dissolved.
-
-#47: Failed changing service status
-
-This occurs while trying to write out a new ownership state of a resource
-group prior to starting it. If this occurs, the start operation will fail.
-
-Generally, this indicates attempt to write a new view of that resource
-group's state after quorum has dissolved.
-
-#48: Unable to obtain cluster lock: <error>
-
-This occurs while trying to determine the state of a resource group prior
-to performing a status operation on it. If this occurs, the status
-operation will fail.
-
-See #33 for reasons as to why obtaining a lock might fail.
-
-#49: Failed getting status for RG <name>
-
-This occurs while trying to determine the state of a resource group prior
-to performing a status operation on it. If this occurs, the status
-operation will fail.
-
-Generally, this indicates attempt to retrieve the current view of that
-resource group's state after quorum has dissolved.
-
-#50: Unable to obtain cluster lock: <error>
-
-This occurs while trying to determine the state of a resource group prior
-to performing a stop or disable operation on it. If this occurs, the stop
-operation will fail.
-
-If a stop operation fails on a service, the service is marked as 'failed',
-if possible.
-
-See #33 for reasons as to why obtaining a lock might fail.
-See #2 for steps to take after a resource group has failed.
-
-#51: Failed getting status for service <name>
-
-This occurs while trying to determine the state of a resource group prior
-to performing a stop or disable operation on it. If this occurs, the stop
-operation will fail.
-
-Generally, this indicates attempt to retrieve the current view of that
-resource group's state after quorum has dissolved.
-
-If a stop operation fails on a service, the service is marked as 'failed',
-if possible (if the cluster is not quorate, then this is not possible).
-
-See #2 for steps to take after a resource group has failed.
-
-#52: Failed changing RG status
-
-This occurs while trying to write out a new ownership state of a resource
-group prior to stopping it. If this occurs, the stop operation will fail.
-
-Generally, this indicates attempt to write a new view of that resource
-group's state after quorum has dissolved.
-
-See #2 for steps to take after a resource group has failed.
-
-#53: Unable to obtain cluster lock: <error>
-
-This occurs while trying to determine the state of a resource group after
-performing a stop or disable operation on it. If this occurs, the stop
-operation will fail.
-
-If a stop operation fails on a service, the service is marked as 'failed',
-if possible.
-
-See #33 for reasons as to why obtaining a lock might fail.
-See #2 for steps to take after a resource group has failed.
-
-#54: Failed getting status for RG <name>
-
-This occurs while trying to determine the state of a resource group after
-to performing a stop or disable operation on it. If this occurs, the stop
-operation will fail.
-
-Generally, this indicates attempt to retrieve the current view of that
-resource group's state after quorum has dissolved.
-
-If a stop operation fails on a service, the service is marked as 'failed',
-if possible (if the cluster is not quorate, then this is not possible).
-
-#55: Failed changing RG status
-
-This occurs while trying to write out a new ownership state of a resource
-group after stopping it. If this occurs, the stop operation will fail.
-
-Generally, this indicates attempt to write a new view of that resource
-group's state after quorum has dissolved.
-
-See #2 for steps to take after a resource group has failed.
-
-#55: Unable to obtain cluster lock: <error>
-
-This occurs while trying to determine the state of a resource group after
-a stop operation has failed, while the cluster is trying to disable
-the service. If this occurs, the operation will fail.
-
-See #33 for reasons as to why obtaining a lock might fail.
-See #2 for steps to take after a resource group has failed.
-
-#56: Failed getting status for RG <name>
-
-This occurs while trying to determine the state of a resource group after
-failing to perform a stop or disable operation on it. If this occurs,
-the operation to lock the service will fail.
-
-Generally, this indicates attempt to retrieve the current view of that
-resource group's state after quorum has dissolved.
-
-#57: Failed changing RG status
-
-This occurs while trying to write out a new ownership state of a resource
-group after marking it as failed. If this occurs, the stop operation
-will fail.
-
-Generally, this indicates attempt to write a new view of that resource
-group's state after quorum has dissolved.
-
-See #2 for steps to take after a resource group has failed.
-
-#58: Failed opening connection to member #<integer>
-
-We attempted to relocate a resource group (service) to another node, but
-failed to actually connect to that node's resource group manager. This
-could indicate that rgmanager is not running on that node. In any case,
-the next node in the cluster member list is tried.
-
-#59: Error sending relocate request to member #<integer>
-
-We attempted to relocate a resource group (service) to another node, but
-failed to send the relocation message. This could indicate a problem with
-network connectivity, extremely high local/remote load, or other problems.
-The next node in the cluster member list is tried.
-
-#60: Mangled reply from member #<integer> during RG relocate
-
-We sent a resource group to another node, but it failed to send us a
-useful reply. At this point, the state of the resource group is unknown, but
-we give it the benefit of the doubt and assume it started okay.
-
-#61: Invalid reply from member <integer> during relocate operation!
-
-Similar to #60, but this occurs only after the inital preferred node failed
-to start the service and/or failed to communicate a proper reply.
-
-#62: /var/lib/nfs/rmtab does not exist - creating
-
-/var/lib/nfs/rmtab did not exist. Clurmtabd creates it.
-
-#63: Couldn't write PID!
-
-Clurmtabd failed to write its pid to <mount_point>/.clumanager/pid. This
-will cause fs.sh to kill it with -9 during a stop operation, preventing
-it from synchronizing with /var/lib/nfs/rmtab prior to exiting. This
-increases the risk of ESTALE (Stale NFS file handle) on clients after
-a relocation.
-
-#64: Could not validate <mount_point>
-#65: NFS failover of <mount_point> will malfunction
-
-Clurmtabd failed to initialize the mount point's private cluster rmtab
-file. This will prevent updating of that mount point's rmtab file, which
-means that clients will receive ESTALE after a relocation or failover.
-
-#66: Domain '<domain>' specified for resource group <name> nonexistent!
-
-The failover domain <domain> does not exist in the current view of the
-cluster configuration. This is a configuration error.
-
-#67: Shutting down uncleanly
-
-The node has left the cluster cleanly, but rgmanager was still running.
-All services are halted as quickly as possible to prevent data corruption.
-
-(It may be a good idea to have rgmanager reboot if this is received)
-
-#68: Failed to start <name>; return value: <integer>
-
-The resource group <name> failed to start and returned the value <integer>.
-This could indicate missing resources on the node or an improperly configured
-resource group. Check your resource group's configuration against your
-hardware and software configuration and ensure that it is correct.
-
-#69: Unclean [stop|disable] of <name>
-
-The resource group is being stopped because of a local node exiting or
-loss of quorum. The distributed state is left unchanged.
-
-#70: Attempting to restart resource group <name> locally.
-
-The resource group failed to start on all other applicable nodes during
-processing of a relocate operation. (A relocate operation occurs either
-by an administrator manually relocating a service or the service being
-relocated after a fail-to-restart event.)
-
-#71: Relocating failed service <name>
-
-The resource group <name> failed a status check and subsequently failed to
-restart. At this point, we try to send it to another applicable node in
-the cluster.
-
-#72: clunfsops: NFS syscall <name> failed: <error>.
-#73: clunfsops: Kernel may not have NFS failover enhancements.
-
-Required NFS failover enhancements were not present on the host kernel.
-It is impossible to restart or relocate NFS services without these, but
-they should properly work in the case of true failover situations (i.e.
-the node on whicch the NFS service was running has failed and been
-fenced by the cluster).
-
-#74: Unable to obtain cluster lock: <error>
-
-This occurs while trying to determine the state of a resource group after
-an attempt to start it has completed (at the script level). If this occurs,
-the start operation will fail.
-
-See #33 for reasons as to why obtaining a lock might fail.
-
-#75: Failed getting status for RG <name>
-
-This occurs while trying to determine the state of a resource group after
-an attempt to start it has completed. If this occurs, the start operation
-will report a failure.
-
-Generally, this indicates attempt to retrieve the current view of that
-resource group's state after quorum has dissolved.
diff --git a/rgmanager/event-script.txt b/rgmanager/event-script.txt
deleted file mode 100644
index 3cc1f31..0000000
--- a/rgmanager/event-script.txt
+++ /dev/null
@@ -1,305 +0,0 @@
-TODO:
-* Return correct error codes to clusvcadm (currently it always returns
- "Unknown")
-* Write glue for 'migrate' operations and migrate-enabled services
-
-Basic configuration specification:
-
- <rm>
- <events>
- <event class="node"/> <!-- all node events -->
- <event class="node"
- node="bar"/> <!-- events concerning 'bar' -->
- <event class="node"
- node="foo"
- node_state="up"/> <!-- 'up' events for 'foo' -->
- <event class="node"
- node_id="3"
- node_state="down"/> <!-- 'down' events for node ID 3 -->
-
- (note, all service ops and such deal with node ID, not
- with node names)
-
- <event class="service"/> <!-- all service events-->
- <event class="service"
- service_name="A"/> <!-- events concerning 'A' -->
- <event class="service"
- service_name="B"
- service_state="started"/> <!-- when 'B' is started... -->
- <event class="service"
- service_name="B"
- service_state="started"/>
- service_owner="3"/> <!-- when 'B' is started on node 3... -->
-
- <event class="service"
- priority="1"
- service_state="started"/>
- service_owner="3"/> <!-- when 'B' is started on node 3, do this
- before the other event handlers ... -->
-
-
- </events>
- ...
- </rm>
-
-General globals available from all scripts:
-
- node_self - local node ID
- event_type - event class, either:
- EVENT_NONE - unspecified / unknown
- EVENT_NODE - node transition
- EVENT_SERVICE - service transition
- EVENT_USER - a user-generated request
- EVENT_CONFIG - [NOT CONFIGURABLE]
-
-Node event globals (i.e. when event_type == EVENT_NODE):
-
- node_id - node ID which is transitioning
- node_name - name of node which is transitioning
- node_state - new node state (NODE_ONLINE or NODE_OFFLINE, or if you prefer,
- 1 or 0, respectively)
- node_clean - 0 if the node has not been fenced, 1 if the node has been
- fenced
-
-Service event globals (i.e. when event_type == EVENT_SERVICE):
-
- service_name - Name of service which transitioned
- service_state - new state of service
- service_owner - new owner of service (or <0 if service is no longer
- running)
- service_last_owner - Last owner of service if known. Used for when
- service_state = "recovering" generally, in order to
- apply restart/relocate/disable policy.
-
-User event globals (i.e. when event_type == EVENT_USER):
-
- service_name - service to perform request upon
- user_request - request to perform (USER_ENABLE, USER_DISABLE,
- USER_STOP, USER_RELOCATE, [TODO] USER_MIGRATE)
- user_target - target node ID if applicable
-
-
-Scripting functions - Informational:
-
- node_list = nodes_online();
-
- Returns a list of all online nodes.
-
- service_list = service_list();
-
- Returns a list of all configured services.
-
- (restarts, last_owner, owner, state) = service_status(service_name);
-
- Returns the state, owner, last_owner, and restarts. Note that
- all return values are optional, but are right-justified per S-Lang
- specification. This means if you only want the 'state', you can use:
-
- (state) = service_status(service_name);
-
- However, if you need the restart count, you must provide all four
- return values as above.
-
- (nofailback, restricted, ordered, node_list) =
- service_domain_info(service_name);
-
- Returns the failover domain specification, if it exists, for the
- specified service name. The node list returned is an ordered list
- according to priority levels. In the case of unordered domains,
- the ordering of the returned list is pseudo-random.
-
-Scripting functions - Operational:
-
- err = service_start(service_name, node_list, [avoid_list]);
-
- Start a non-running, (but runnable, i.e. not failed)
- service on the first node in node_list. Failing that, start it on
- the second node in node_list and so forth. One may also specify
- an avoid list, but it's better to just use the subtract() function
- below.
-
- err = service_stop(service_name, [0 = stop, 1 = disable]);
-
- Stop a running service. The second parameter is optional, and if
- non-zero is specified, the service will enter the disabled state.
-
- ... stuff that's not done but needs to be:
-
- err = service_relocate(service_name, node_list);
-
- Move a running service to the specified node_list in order of
- preference. In the case of VMs, this is actually a migrate-or-
- relocate operation.
-
-Utility functions - Node list manipulation
-
- node_list = union(left_node_list, right_node_list);
-
- Calculates the union between the two node list, removing duplicates
- and preserving ordering according to left_node_list. Any added
- values from right_node_list will appear in their order, but
- after left_node_list in the returned list.
-
- node_list = intersection(left_node_list, right_node_list);
-
- Calculates the intersection (items in both lists) between the two
- node lists, removing duplicates and preserving ordering according
- to left_node_list. Any added values from right_node_list will
- appear in their order, but after left_node_list in the returned list.
-
- node_list = delta(left_node_list, right_node_list);
-
- Calculates the delta (items not in both lists) between the two
- node lists, removing duplicates and preserving ordering according
- to left_node_list. Any added values from right_node_list will
- appear in their order, but after left_node_list in the returned list.
-
- node_list = subtract(left_node_list, right_node_list);
-
- Removes any duplicates as well as items specified in right_node_list
- from left_node_list. Example:
-
- all_nodes = nodes_online();
- allowed_nodes = subtract(nodes_online, node_to_avoid);
-
-Utility functions - Logging:
-
- debug(item1, item2, ...); LOG_DEBUG level
- info(...); LOG_INFO level
- notice(...); LOG_NOTICE level
- warning(...); LOG_WARNING level
- err(...); LOG_ERR level
- crit(...); LOG_CRIT level
- alert(...); LOG_ALERT level
- emerg(...); LOG_EMERG level
-
- items - These can be strings, integer lists, or integers. Logging
- string lists is not supported.
-
- level - the level is consistent with syslog(8)
-
- stop_processing();
-
- Calling this function will prevent further event scripts from being
- executed on a particular event. Call this script if, for example,
- you do not wish for the default event handler to process the event.
-
- Note: This does NOT terminate the caller script; that is, the
- script being executed will run to completion.
-
-Event scripts are written in a language called S-Lang; documentation specifics
-about the language are available at http://www.s-lang.org
-
-Example script (creating a follows-but-avoid-after-start behavior):
-%
-% If the main queue server and replication queue server are on the same
-% node, relocate the replication server somewhere else if possible.
-%
-define my_sap_event_trigger()
-{
- variable state, owner_rep, owner_main;
- variable nodes, allowed;
-
- %
- % If this was a service event, don't execute the default event
- % script trigger after this script completes.
- %
- if (event_type == EVENT_SERVICE) {
- stop_processing();
- }
-
- (owner_main, state) = service_status("service:main_queue");
- (owner_rep, state) = service_status("service:replication_server");
-
- if ((event_type == EVENT_NODE) and (owner_main == node_id) and
- (node_state == NODE_OFFLINE) and (owner_rep >= 0)) {
- %
- % uh oh, the owner of the main server died. Restart it
- % on the node running the replication server
- %
- notice("Starting Main Queue Server on node ", owner_rep);
- ()=service_start("service:main_queue", owner_rep);
- return;
- }
-
- %
- % S-Lang doesn't short-circuit prior to 2.1.0
- %
- if ((owner_main >= 0) and
- ((owner_main == owner_rep) or (owner_rep < 0))) {
-
- %
- % Get all online nodes
- %
- nodes = nodes_online();
-
- %
- % Drop out the owner of the main server
- %
- allowed = subtract(nodes, owner_main);
- if ((owner_rep >= 0) and (length(allowed) == 0)) {
- %
- % Only one node is online and the rep server is
- % already running. Don't do anything else.
- %
- return;
- }
-
- if ((length(allowed) == 0) and (owner_rep < 0)) {
- %
- % Only node online is the owner ... go ahead
- % and start it, even though it doesn't increase
- % availability to do so.
- %
- allowed = owner_main;
- }
-
- %
- % Move the replication server off the node that is
- % running the main server if a node's available.
- %
- if (owner_rep >= 0) {
- ()=service_stop("service:replication_server");
- }
- ()=service_start("service:replication_server", allowed);
- }
-
- return;
-}
-
-my_sap_event_trigger();
-
-
-Relevant <rm> section from cluster.conf:
-
- <rm central_processing="1">
- <events>
- <event name="main-start" class="service"
- service="service:main_queue"
- service_state="started"
- file="/tmp/sap.sl"/>
- <event name="rep-start" class="service"
- service="service:replication_server"
- service_state="started"
- file="/tmp/sap.sl"/>
- <event name="node-up" node_state="up"
- class="node"
- file="/tmp/sap.sl"/>
-
- </events>
- <failoverdomains>
- <failoverdomain name="all" ordered="1" restricted="1">
- <failoverdomainnode name="molly"
-priority="2"/>
- <failoverdomainnode name="frederick"
-priority="1"/>
- </failoverdomain>
- </failoverdomains>
- <resources/>
- <service name="main_queue"/>
- <service name="replication_server" autostart="0"/>
- <!-- replication server is started when main-server start
- event completes -->
- </rm>
-
-
diff --git a/rgmanager/examples/cluster.conf b/rgmanager/examples/cluster.conf
deleted file mode 100644
index a53e479..0000000
--- a/rgmanager/examples/cluster.conf
+++ /dev/null
@@ -1,106 +0,0 @@
-<?xml version="1.0"?>
-<cluster name="pretty" config_version="6">
-
-<cman>
-</cman>
-
-<dlm>
-</dlm>
-
-<clusternodes>
- <clusternode name="red" votes="4">
- <fence>
- <method name="power">
- <device name="wti" port="1"/>
- </method>
- </fence>
- </clusternode>
- <clusternode name="green" votes="3">
- <fence>
- <method name="power">
- <device name="wti" port="2"/>
- </method>
- </fence>
- </clusternode>
-</clusternodes>
-
-
-<fencedevices>
- <fencedevice name="wti" agent="fence_wti" ipaddress="nps1" password="wti"/>
-</fencedevices>
-
-
-<!-- The RM block holds resources, failover domains, and any number of
- 'group' (= resource group) blocks -->
-<rm>
- <!-- Similar to failover domains in RHEL3 -->
- <failoverdomains>
- <failoverdomain name="thisdomain" ordered="1">
- <failoverdomainnode name="red" priority="1"/>
- <failoverdomainnode name="green" priority="1"/>
- <failoverdomainnode name="blue" priority="2"/>
- </failoverdomain>
- <failoverdomain name="bluedomain" restricted="1">
- <failoverdomainnode name="blue" priority="2"/>
- </failoverdomain>
- </failoverdomains>
-
- <!-- Define resources here -->
- <resources>
-
- <group name="oracle" domain="thisdomain"/>
- <script name="Oracle Script" file="/etc/init.d/oracle"/>
- <script name="Oracle Script 2" file="/etc/init.d/oracle2"/>
- <ip address="192.168.0.28" monitor_link="yes"/>
- <ip address="192.168.0.29" monitor_link="yes"/>
- <nfsclient name="User group" target="@users" options="ro"/>
- <nfsclient name="Admin group" target="@admin" options="rw"/>
- <nfsexport name="nfs exports"/>
- </resources>
-
- <!-- Define resource groups here -->
- <service ref="oracle">
-
- <!-- Reference the above resources by their primary attribute -->
- <script ref="Oracle Script"/>
- <script ref="Oracle Script 2"/>
- <ip ref="192.168.0.28"/>
- <ip ref="192.168.0.29"/>
-
- <!-- Or define them inline. Fine with me! -->
- <fs fstype="ext3" name="NFS Mount" mountpoint="/mnt/cluster" device="/dev/sdb8">
-
- <!-- nfs export path inherited from parent file system's mount point-->
- <nfsexport ref="nfs exports">
- <!-- Export path inherited from export. So, for this instance
- of "admin group", the export path is /mnt/cluster. -->
- <nfsclient ref="Admin group"/>
- <nfsclient ref="User group"/>
- </nfsexport>
- </fs>
-
- <fs fstype="ext3" name="NFS2" mountpoint="/mnt/sdb7" device="/dev/sdb7">
- <!-- nfs export path inherited from parent file system's mount point-->
- <nfsexport name="NFS Export" type="nfs">
- <!-- Export path inherited from export. So, for this instance
- of "admin group", the export path is /mnt/sdb7. -->
- <nfsclient ref="Admin group"/>
- <nfsclient ref="User group"/>
- </nfsexport>
- </fs>
- </service>
-
- <!-- Define a bunch of test resource groups. -->
- <service name="test1"/>
- <service name="test2"/>
- <service name="test3"/>
- <service name="test4"/>
- <service name="test5"/>
- <service name="test6"/>
- <service name="test7"/>
- <service name="test8"/>
- <service name="test9"/>
- <service name="blueonly" domain="bluedomain"/>
-</rm>
-
-</cluster>
diff --git a/rgmanager/include/cman-private.h b/rgmanager/include/cman-private.h
deleted file mode 100644
index 2cddb39..0000000
--- a/rgmanager/include/cman-private.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _CMAN_PRIVATE_H
-#define _CMAN_PRIVATE_H
-
-#include <libcman.h>
-
-int cman_init_subsys(cman_handle_t ch);
-cman_handle_t cman_lock(int block, int sig);
-cman_handle_t cman_lock_preemptible(int block, int *fd);
-int cman_cleanup_subsys(void);
-int cman_unlock(cman_handle_t ch);
-int cman_send_data_unlocked(void *buf, int len, int flags,
- uint8_t port, int nodeid);
-
-#endif
diff --git a/rgmanager/include/cpglock-internal.h b/rgmanager/include/cpglock-internal.h
deleted file mode 100644
index e05b90a..0000000
--- a/rgmanager/include/cpglock-internal.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _CPGLOCK_INT_H
-#define _CPGLOCK_INT_H
-
-#ifndef CPG_LOCKD_SOCK
-#define CPG_LOCKD_SOCK "/var/run/cpglockd.sk"
-#endif
-
-#include <stdint.h>
-
-typedef enum {
- MSG_LOCK = 1,
- MSG_NAK = 2,
- MSG_GRANT = 3,
- MSG_UNLOCK = 4,
- MSG_PURGE = 5,
- MSG_CONFCHG= 6,
- MSG_JOIN = 7,
- MSG_DUMP = 998,
- MSG_HALT = 999
-} cpg_lock_req_t;
-
-struct cpg_lock_msg {
- int32_t request;
- uint32_t owner_nodeid;
- uint32_t owner_pid;
- uint32_t flags;
- uint32_t lockid;
- uint32_t owner_tid;
- char resource[96];
- char pad[8];
-} __attribute__((packed)); /* 128 */
-
-#define CPG_LOCKD_NAME "cpglockd"
-
-#endif
diff --git a/rgmanager/include/cpglock.h b/rgmanager/include/cpglock.h
deleted file mode 100644
index e451d2f..0000000
--- a/rgmanager/include/cpglock.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef _CPGLOCK_H
-#define _CPGLOCK_H
-
-typedef enum {
- LOCK_FREE = 0,
- LOCK_PENDING = 1,
- LOCK_HELD = 2
-} lock_state_t;
-
-typedef enum {
- FL_TRY = 0x1
-} lock_flag_t;
-
-struct cpg_lock {
- char resource[96];
- int local_fd;
- int local_id;
- lock_state_t state;
- int owner_nodeid;
- int owner_pid;
- int owner_tid;
-};
-
-typedef void * cpg_lock_handle_t;
-
-int cpg_lock_init(cpg_lock_handle_t *h);
-
-/* 0 if successful, -1 if error */
-int cpg_lock(cpg_lock_handle_t h, const char *resource,
- lock_flag_t flags, struct cpg_lock *lock);
-
-int cpg_unlock(cpg_lock_handle_t h,
- struct cpg_lock *lock);
-
-/* Warning: drops all locks with this client */
-int cpg_lock_fin(cpg_lock_handle_t h);
-
-int cpg_lock_dump(FILE *fp);
-
-#endif
diff --git a/rgmanager/include/daemon_init.h b/rgmanager/include/daemon_init.h
deleted file mode 100644
index 99e87c2..0000000
--- a/rgmanager/include/daemon_init.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _DAEMON_INIT_H
-#define _DAEMON_INIT_H
-
-int check_pid_valid(pid_t pid, char *prog);
-int check_process_running(char *prog, pid_t * pid);
-void update_pidfile(char *prog);
-void daemon_init(char *prog);
-void daemon_cleanup(void);
-
-#endif
diff --git a/rgmanager/include/ds.h b/rgmanager/include/ds.h
deleted file mode 100644
index f7c9913..0000000
--- a/rgmanager/include/ds.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _DS_H
-#define _DS_H
-
-int ds_init(void);
-int ds_key_init(char *keyid, int maxsize, int timeout);
-int ds_key_finish(char *keyid);
-int ds_write(char *keyid, void *buf, size_t maxlen);
-int ds_read(char *keyid, void *buf, size_t maxlen);
-int ds_finish(void);
-
-#define DS_MIN_SIZE 512
-
-#endif
diff --git a/rgmanager/include/event.h b/rgmanager/include/event.h
deleted file mode 100644
index 1baa3a5..0000000
--- a/rgmanager/include/event.h
+++ /dev/null
@@ -1,143 +0,0 @@
-#ifndef _EVENT_H
-#define _EVENT_H
-
-/* 128 is a bit big, but it should be okay */
-typedef struct __rge_q {
- char rg_name[128];
- uint32_t rg_state;
- uint32_t pad1;
- int rg_owner;
- int rg_last_owner;
-} group_event_t;
-
-typedef struct __ne_q {
- int ne_local;
- int ne_nodeid;
- int ne_state;
- int ne_clean;
-} node_event_t;
-
-typedef struct __cfg_q {
- int cfg_version; /* Not used or handled for now */
- int cfg_oldversion;
-} config_event_t;
-
-typedef struct __user_q {
- char u_name[128];
- msgctx_t *u_ctx;
- int u_request;
- int u_arg1;
- int u_arg2;
- int u_target; /* Node ID */
-} user_event_t;
-
-typedef enum {
- EVENT_NONE=0,
- EVENT_CONFIG,
- EVENT_NODE,
- EVENT_RG,
- EVENT_USER
-} event_type_t;
-
-/* Data that's distributed which indicates which
- node is the event master */
-typedef struct __rgm {
- uint32_t m_magic;
- uint32_t m_nodeid;
- uint64_t m_master_time;
- uint8_t m_reserved[112];
-} event_master_t;
-
-#define swab_event_master_t(ptr) \
-{\
- swab32((ptr)->m_nodeid);\
- swab32((ptr)->m_magic);\
- swab64((ptr)->m_master_time);\
-}
-
-/* Just a magic # to help us ensure we've got good
- date from VF */
-#define EVENT_MASTER_MAGIC 0xfabab0de
-
-/* Event structure - internal to the event subsystem; use
- the queueing functions below which allocate this struct
- and pass it to the event handler */
-typedef struct _event {
- /* Not used dynamically - part of config info */
- list_head();
- char *ev_name;
- char *ev_script;
- char *ev_script_file;
- int ev_prio;
- int ev_pad;
- /* --- end config part */
- int ev_type; /* config & generated by rgmanager*/
- int ev_transaction;
- union {
- group_event_t group;
- node_event_t node;
- config_event_t config;
- user_event_t user;
- } ev;
-} event_t;
-
-#define EVENT_PRIO_COUNT 100
-
-typedef struct _event_table {
- int max_prio;
- int pad;
- event_t *entries[0];
-} event_table_t;
-
-
-int construct_events(int ccsfd, event_table_t **);
-void deconstruct_events(event_table_t **);
-void print_events(event_table_t *);
-void dump_events(FILE *fp, event_table_t *);
-
-/* Does the event match a configured event? */
-int event_match(event_t *pattern, event_t *actual);
-
-/* Event queueing functions. */
-void node_event_q(int local, int nodeID, int state, int clean);
-void rg_event_q(char *name, uint32_t state, int owner, int last);
-void user_event_q(char *svc, int request, int arg1, int arg2,
- int target, msgctx_t *ctx);
-void config_event_q(void);
-
-/* Call this to see if there's a master. */
-int event_master_info_cached(event_master_t *);
-
-/* Call this to get the node ID of the current
- master *or* become the master if none exists */
-int event_master(void);
-
-/* Setup */
-int central_events_enabled(void);
-void set_central_events(int flag);
-int slang_process_event(event_table_t *event_table, event_t *ev);
-
-/* For distributed events. */
-void set_transition_throttling(int nsecs);
-int get_transition_throttling(void);
-void broadcast_event(const char *svcName, uint32_t state, int owner, int last);
-
-/* Simplified service start. */
-int service_op_start(char *svcName, int *target_list, int target_list_len,
- int *new_owner);
-int service_op_stop(char *svcName, int do_disable, int event_type);
-int service_op_convalesce(const char *svcName);
-int service_op_migrate(char *svcName, int target_node);
-
-
-/* Non-central event processing */
-void node_event(int local, int nodeID, int nodeStatus, int clean);
-
-int32_t master_event_callback(char *key, uint64_t viewno, void *data,
- uint32_t datalen);
-
-int node_has_fencing(int nodeid);
-int fence_domain_joined(void);
-int get_service_state_internal(const char *svcName, rg_state_t *svcStatus);
-
-#endif
diff --git a/rgmanager/include/fdops.h b/rgmanager/include/fdops.h
deleted file mode 100644
index f3194de..0000000
--- a/rgmanager/include/fdops.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _FDOPS_H
-#define _FDOPS_H
-#include <unistd.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <errno.h>
-
-int _select_retry(int fdmax, fd_set * rfds, fd_set * wfds, fd_set * xfds,
- struct timeval *timeout);
-ssize_t _write_retry(int fd, void *buf, int count, struct timeval * timeout);
-ssize_t _read_retry(int sockfd, void *buf, int count,
- struct timeval * timeout);
-
-#endif
diff --git a/rgmanager/include/findproc.h b/rgmanager/include/findproc.h
deleted file mode 100644
index 3b6db59..0000000
--- a/rgmanager/include/findproc.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/** @file
- * Header for findproc.c
- */
-#ifndef __PROC_H
-#define __PROC_H
-
-int findkillproc(char *, pid_t *, size_t, int);
-int findproc(char *, pid_t *, size_t);
-int killall(char *, int);
-
-#endif
diff --git a/rgmanager/include/fo_domain.h b/rgmanager/include/fo_domain.h
deleted file mode 100644
index d8a7813..0000000
--- a/rgmanager/include/fo_domain.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef _FO_DOMAIN_H
-#define _FO_DOMAIN_H
-
-/*
- * Fail-over domain states
- */
-#define FOD_ILLEGAL 0
-#define FOD_GOOD 1
-#define FOD_BETTER 2
-#define FOD_BEST 3
-
-/*
- Fail-over domain flags
- */
-#define FOD_ORDERED (1<<0)
-#define FOD_RESTRICTED (1<<1)
-#define FOD_NOFAILBACK (1<<2)
-
-
-typedef struct _fod_node {
- list_head();
- char *fdn_name;
- int fdn_prio;
- int fdn_nodeid;
-} fod_node_t;
-
-typedef struct _fod {
- list_head();
- char *fd_name;
- fod_node_t *fd_nodes;
- int fd_flags;
- int _pad_; /* align */
-} fod_t;
-
-
-/*
- Construct/deconstruct failover domains
- */
-int construct_domains(int ccsfd, fod_t **domains);
-void deconstruct_domains(fod_t **domains);
-void print_domains(fod_t **domains);
-void dump_domains(FILE *fp, fod_t **domains);
-int node_should_start(int nodeid, cluster_member_list_t *membership,
- const char *rg_name, fod_t **domains);
-int node_domain_set(fod_t **domains, char *name, int **ret,
- int *retlen, int *flags);
-int node_domain_set_safe(char *domainname, int **ret, int *retlen, int *flags);
-
-#endif
diff --git a/rgmanager/include/gettid.h b/rgmanager/include/gettid.h
deleted file mode 100644
index 636560c..0000000
--- a/rgmanager/include/gettid.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __GETTID_H
-#define __GETTID_H
-
-pid_t gettid(void);
-
-#endif
-
diff --git a/rgmanager/include/groups.h b/rgmanager/include/groups.h
deleted file mode 100644
index f02f0e2..0000000
--- a/rgmanager/include/groups.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef _GROUPS_H
-#define _GROUPS_H
-
-int node_should_start_safe(uint32_t, cluster_member_list_t *, const char *);
-int group_property(const char *groupname, const char *property,
- char *ret_val, size_t len);
-int count_resource_groups(cluster_member_list_t *ml);
-int count_resource_groups_local(cman_node_t *mp);
-int is_exclusive(const char *svcName);
-int have_exclusive_resources(void);
-int check_exclusive_resources(cluster_member_list_t *membership,
- const char *svcName);
-int check_depend(resource_t *res);
-
-void dump_config_version(FILE *fp);
-int init_resource_groups(int reconfigure, int do_init);
-void get_recovery_policy(const char *rg_name, char *buf, size_t buflen);
-int get_service_property(const char *rg_name, const char *prop,
- char *buf, size_t buflen);
-
-int add_restart(const char *rg_name);
-int check_restart(const char *rg_name);
-int clear_restart(const char *rg_name);
-void kill_resource_groups(void);
-
-/* do this op on all resource groups. The handler for the request
- will sort out whether or not it's a valid request given the state */
-int rg_doall(int request, int block, const char *debugfmt);
-void do_status_checks(void); /* Queue status checks for locally running
- services */
-
-int svc_exists(const char *svcname);
-int send_rg_states(msgctx_t *ctx, int fast);
-
-int check_depend_safe(const char *servicename);
-int group_migratory(const char *servicename, int lock);
-int group_event(const char *rg_name, uint32_t state, int owner);
-
-char **get_service_names(int *len);
-
-
-
-#endif
diff --git a/rgmanager/include/list.h b/rgmanager/include/list.h
deleted file mode 100644
index 0d1c1d5..0000000
--- a/rgmanager/include/list.h
+++ /dev/null
@@ -1,95 +0,0 @@
-#ifndef _LIST_H
-#define _LIST_H
-
-/**
- Simple list handlig macros.
- Needs rewrite or inclusion of /usr/include/linux/list.h as a replacement.
- */
-
-/* Must be first if structure is going to use it. */
-struct list_entry {
- struct list_entry *le_next, *le_prev;
-};
-
-#define list_head() struct list_entry _list_head
-
-#define le(p) (&((*p)._list_head))
-
-#define list_insert(list, newnode) \
-do { \
- if (!(*list)) { \
- le(newnode)->le_next = \
- le(newnode)->le_prev = le(newnode); \
- *list = (void *)le(newnode); \
- } else { \
- le(*list)->le_prev->le_next = le(newnode); \
- le(newnode)->le_next = le(*list); \
- le(newnode)->le_prev = le(*list)->le_prev; \
- le(*list)->le_prev = le(newnode); \
- } \
-} while (0)
-
-
-#define list_prepend(list, newnode) \
-do { \
- list_insert(list, newnode); \
- *list = newnode; \
-} while (0)
-
-#define list_append list_insert
-
-#define list_remove(list, oldnode) \
-do { \
- if (le(oldnode) == le(*list)) { \
- *list = (void *)le(*list)->le_next; \
- } \
- if (le(oldnode) == le(*list)) { \
- le(oldnode)->le_next = NULL; \
- le(oldnode)->le_prev = NULL; \
- *list = NULL; \
- } else { \
- le(oldnode)->le_next->le_prev = le(oldnode)->le_prev; \
- le(oldnode)->le_prev->le_next = le(oldnode)->le_next; \
- le(oldnode)->le_prev = NULL; \
- le(oldnode)->le_next = NULL; \
- } \
-} while (0)
-
-/*
- list_do(list, node) {
- stuff;
- } while (!list_done(list, node));
- */
-#define list_do(list, curr) \
- if (*list && (curr = *list)) do
-
-#define list_done(list, curr) \
- (curr && (((curr = (void *)le(curr)->le_next)) && (curr == *list)))
-
-/*
- * list_for(list, tmp, counter) {
- * stuff;
- * }
- *
- * counter = # of items in list when done.
- * * sets cnt to 0 before even checking list;
- * * checks for valid list
- * * traverses list, incrementing counter. If we get to the for loop,
- * there must be at least one item in the list
- */
-#define list_for(list, curr, cnt) \
- if (!(cnt=0) && *list) \
- for (curr = *list; \
- (cnt == 0) || (curr != *list); \
- curr = (void*)le(curr)->le_next, \
- cnt++)
-
-#define list_for_rev(list, curr, cnt) \
- if (!(cnt=0) && *list) \
- for (curr = (void *)(le(*list)->le_prev); \
- (cnt == 0) || ((void *)curr != le(*list)->le_prev); \
- curr = (void*)(le(curr)->le_prev), \
- cnt++)
-
-
-#endif
diff --git a/rgmanager/include/lock.h b/rgmanager/include/lock.h
deleted file mode 100644
index 82a1faf..0000000
--- a/rgmanager/include/lock.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _LOCK_H
-#define _LOCK_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <libdlm.h>
-
-/* Default lockspace wrappers */
-int clu_lock_init(const char *default_lsname);
-int cpg_lock_initialize(void);
-
-extern int (*clu_lock)(int, struct dlm_lksb *, int, const char *);
-extern int (*clu_unlock)(struct dlm_lksb *lksb);
-extern void (*clu_lock_finished)(const char *);
-
-#endif
diff --git a/rgmanager/include/logging.h b/rgmanager/include/logging.h
deleted file mode 100644
index 0852118..0000000
--- a/rgmanager/include/logging.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _LOGGING_H
-#define _LOGGING_H
-
-/* #include <corosync/engine/logsys.h>*/
-#include <liblogthread.h>
-
-void init_logging(char *name, int foreground, int debugging);
-void setup_logging(int ccs_handle);
-void close_logging(void);
-
-#endif
diff --git a/rgmanager/include/members.h b/rgmanager/include/members.h
deleted file mode 100644
index 09f7a9a..0000000
--- a/rgmanager/include/members.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef _MEMBERS_H
-#define _MEMBERS_H
-
-#include <rg_types.h>
-
-typedef enum {
- NODE_STATE_DOWN = 0,
- NODE_STATE_UP = 1,
- NODE_STATE_CLEAN = 2
-} node_state_t;
-
-
-int get_my_nodeid(cman_handle_t h);
-int my_id(void);
-int set_my_id(int);
-cluster_member_list_t * get_member_list(cman_handle_t h);
-void free_member_list(cluster_member_list_t *ml);
-void member_set_state(int nodeid, int state);
-int memb_count(cluster_member_list_t *ml);
-int member_online(int nodeid);
-int member_online_set(int **nodes, int *nodecount);
-int memb_online(cluster_member_list_t *ml, int nodeid);
-int memb_online_name(cluster_member_list_t *ml, char *name);
-int memb_name_to_id(cluster_member_list_t *ml, char *name);
-int memb_mark_down(cluster_member_list_t *ml, int nodeid);
-char * memb_id_to_name(cluster_member_list_t *ml, int nodeid);
-cman_node_t * memb_id_to_p(cluster_member_list_t *ml, int nodeid);
-cman_node_t * memb_name_to_p(cluster_member_list_t *ml, char *name);
-void free_member_list(cluster_member_list_t *ml);
-void member_list_shuffle(cluster_member_list_t *ml);
-cluster_member_list_t *memb_gained(cluster_member_list_t *old,
- cluster_member_list_t *new);
-cluster_member_list_t *memb_lost(cluster_member_list_t *old,
- cluster_member_list_t *new);
-
-cluster_member_list_t *member_list_dup(cluster_member_list_t *old);
-cluster_member_list_t *member_list(void);
-void member_list_update(cluster_member_list_t *new_ml);
-
-#endif
diff --git a/rgmanager/include/message.h b/rgmanager/include/message.h
deleted file mode 100644
index e9d7797..0000000
--- a/rgmanager/include/message.h
+++ /dev/null
@@ -1,175 +0,0 @@
-#ifndef _MESSAGE_H
-#define _MESSAGE_H
-#include <stdint.h>
-#include <pthread.h>
-#include <platform.h>
-#include <libcman.h>
-#include <list.h>
-#include <rg_types.h>
-#include <sys/types.h>
-#include <arpa/inet.h>
-#include <sys/select.h>
-
-typedef enum {
- M_NONE = 0,
- M_OPEN = 1,
- M_OPEN_ACK = 2,
- M_CLOSE = 3,
- M_DATA = 4,
- M_STATECHANGE = 5, /* Node transition */
- M_PORTOPENED = 6, /* Port opened */
- M_PORTCLOSED = 7, /* Port closed */
- M_TRY_SHUTDOWN = 8, /* Local node shutdown */
- M_CONFIG_UPDATE = 9 /* (new) Config Update */
-} msg_control_t;
-
-typedef enum {
- MSG_NONE = -1,
- MSG_SOCKET = 1,
- MSG_CLUSTER = 2
-} msgctx_type_t;
-
-/* Header is never presented to applications */
-typedef struct ALIGNED {
- uint32_t src_ctx;
- uint32_t src_nodeid;
- /* 8 */
- uint32_t dest_ctx;
- uint32_t dest_nodeid;
- /* 16 */
- uint8_t msg_control;
- uint8_t msg_port;
- uint8_t pad[2];
- /* 20 */
- uint8_t msg_reserved[12];
-} cluster_msg_hdr_t;
-
-/* Header is never presented to applications */
-typedef struct ALIGNED {
- uint32_t msg_len; /* Size of tailing message */
- uint8_t msg_control;
- uint8_t pad[3];
-} local_msg_hdr_t;
-/* No need for swabbing this one */
-
-
-/* Cluster private queue */
-typedef struct ALIGNED {
- list_head();
- cluster_msg_hdr_t *message;
- int len;
-} msg_q_t;
-
-
-#define swab_cluster_msg_hdr_t(ptr) \
-{\
- swab32((ptr)->dest_ctx);\
- swab32((ptr)->src_ctx);\
- swab32((ptr)->src_nodeid);\
- swab32((ptr)->dest_nodeid);\
-}
-
-
-typedef struct ALIGNED _msgctx {
- struct _msg_ops *ops;
- msgctx_type_t type;
- int flags;
- /* XXX todo make this opaque */
- void *sp;
- union {
- struct {
- msg_q_t *queue;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- cman_handle_t cman_handle;
- int nodeid;
- int port;
- uint32_t local_ctx;
- uint32_t remote_ctx;
- int select_pipe[2];
- } cluster_info;
- struct {
- int sockfd;
- struct ucred cred;
- int pad;
- } local_info;
- } u;
-} msgctx_t;
-
-
-typedef int (*msg_open_t)(int type, int nodeid, int port, msgctx_t *ctx,
- int timeout);
-typedef int (*msg_close_t)(msgctx_t *);
-typedef int (*msg_listen_t)(int me, const void *, msgctx_t **);
-typedef int (*msg_accept_t)(msgctx_t *, msgctx_t *);
-typedef int (*msg_shutdown_t)(void);
-typedef int (*msg_send_t)(msgctx_t *, void *, size_t);
-typedef int (*msg_receive_t)(msgctx_t *, void *, size_t, int);
-typedef int (*msg_wait_t)(msgctx_t *, int);
-typedef int (*msg_fd_set_t)(msgctx_t *, fd_set *, int *);
-typedef int (*msg_fd_isset_t)(msgctx_t *, fd_set *);
-typedef int (*msg_fd_clr_t)(msgctx_t *, fd_set *);
-typedef void (*msg_print_t)(msgctx_t *);
-typedef int (*msg_init_t)(msgctx_t *);
-
-typedef struct _msg_ops {
- msg_open_t mo_open;
- msg_close_t mo_close;
- msg_listen_t mo_listen;
- msg_accept_t mo_accept;
- msg_shutdown_t mo_shutdown;
- msg_wait_t mo_wait;
- msg_send_t mo_send;
- msg_receive_t mo_receive;
- msg_fd_set_t mo_fd_set;
- msg_fd_isset_t mo_fd_isset;
- msg_fd_clr_t mo_fd_clr;
- msg_print_t mo_print;
- msg_init_t mo_init;
-} msg_ops_t;
-
-
-/* Ripped from ccsd's setup_local_socket */
-#define MAX_CONTEXTS 128 /* Testing; production should be 1024-ish */
-
-#define SKF_LISTEN (1<<0)
-#define SKF_READ (1<<1)
-#define SKF_WRITE (1<<2)
-#define SKF_MCAST (1<<3)
-
-
-/* Call once for MSG_CLUSTER, once for MSG_SOCKET */
-/* Private is should be a null-terminated char string for MSG_SOCKET,
- and a pointer to int type for MSG_CLUSTER */
-int msg_listen(int type, const void *port, int me, msgctx_t **new_ctx);
-int msg_open(int type, int nodeid, int port, msgctx_t *ctx, int timeout);
-int msg_init(msgctx_t *ctx);
-int msg_accept(msgctx_t *listenctx, msgctx_t *acceptctx);
-int msg_get_nodeid(msgctx_t *ctx);
-int msg_close(msgctx_t *ctx);
-int msg_receive(msgctx_t *ctx, void *msg, size_t maxlen, int timeout);
-int msg_wait(msgctx_t *ctx, int timeout); /* Select-ish */
-int msg_send(msgctx_t *ctx, void *msg, size_t len);
-msgctx_t *msg_new_ctx(void);
-void msg_free_ctx(msgctx_t *old);
-int msg_fd_set(msgctx_t *ctx, fd_set *fds, int *max);
-int msg_fd_isset(msgctx_t *ctx, fd_set *fds);
-int msg_fd_clr(msgctx_t *ctx, fd_set *fds);
-void msg_print(msgctx_t *ctx);
-int msg_shutdown(void);
-
-
-/* From msg_cluster */
-int cluster_msg_init(msgctx_t *ctx);
-int cluster_msg_listen(int me, const void *, msgctx_t **ctx);
-int cluster_msg_shutdown(void);
-
-/* From msg_socket */
-int sock_msg_init(msgctx_t *ctx);
-int sock_msg_listen(int me, const void *, msgctx_t **ctx);
-int sock_msg_shutdown(void);
-
-/* Debugging */
-void dump_cluster_ctx(FILE *fp);
-
-#endif
diff --git a/rgmanager/include/msgsimple.h b/rgmanager/include/msgsimple.h
deleted file mode 100644
index 66ba927..0000000
--- a/rgmanager/include/msgsimple.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef __MSG_SIMPLE_H
-#define __MSG_SIMPLE_H
-
-#include <errno.h>
-#include <stdint.h>
-#include <resgroup.h>
-
-typedef struct PACKED {
- uint32_t gh_magic;
- uint32_t gh_length;
- uint32_t gh_command;
- uint32_t gh_arg1;
- uint32_t gh_arg2;
- uint32_t gh_arg3;
-} generic_msg_hdr;
-
-#define swab_generic_msg_hdr(ptr)\
-{\
- swab32((ptr)->gh_magic);\
- swab32((ptr)->gh_length);\
- swab32((ptr)->gh_command);\
- swab32((ptr)->gh_arg1);\
- swab32((ptr)->gh_arg2);\
-}
-
-typedef struct PACKED {
- generic_msg_hdr sm_hdr;
- struct {
- char d_svcName[64];
- uint32_t d_action;
- uint32_t d_svcState;
- uint32_t d_svcOwner;
- int32_t d_ret;
- } sm_data;
-} SmMessageSt;
-
-#define swab_SmMessageSt(ptr) \
-{\
- swab_generic_msg_hdr(&((ptr)->sm_hdr));\
- swab32((ptr)->sm_data.d_action);\
- swab32((ptr)->sm_data.d_svcState);\
- swab32((ptr)->sm_data.d_svcOwner);\
- swab32((ptr)->sm_data.d_ret);\
-}
-
-typedef struct ALIGNED {
- generic_msg_hdr rsm_hdr;
- rg_state_t rsm_state;
-} rg_state_msg_t;
-
-#define swab_rg_state_msg_t(ptr) \
-{\
- swab_generic_msg_hdr(&((ptr)->rsm_hdr));\
- swab_rg_state_t(&((ptr)->rsm_state));\
-}
-
-
-#define GENERIC_HDR_MAGIC 0x123abc00
-#define GENERIC_HDR_MAGICV2 0x123abc02
-
-int msg_send_simple(msgctx_t *ctx, int cmd, int arg1, int arg2);
-int msg_receive_simple(msgctx_t *ctx, generic_msg_hdr ** buf, int timeout);
-
-#endif
diff --git a/rgmanager/include/platform.h b/rgmanager/include/platform.h
deleted file mode 100644
index 7681b50..0000000
--- a/rgmanager/include/platform.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/** @file
- * Defines for byte-swapping
- */
-#ifndef _PLATFORM_H
-#define _PLATFORM_H
-
-#include <endian.h>
-#include <sys/param.h>
-#include <byteswap.h>
-#include <bits/wordsize.h>
-
-/*
-
-Configure is gone...
- #ifndef HAVE_CONFIG_H
-#error "Please run configure first"
-#endif
-
-*/
-
-/* #include <config.h> */
-
-/* No swapping on little-endian machines */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define le_swap16(x) (x)
-#define le_swap32(x) (x)
-#define le_swap64(x) (x)
-#else
-#define le_swap16(x) bswap_16(x)
-#define le_swap32(x) bswap_32(x)
-#define le_swap64(x) bswap_64(x)
-#endif
-
-/* No swapping on big-endian machines */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define be_swap16(x) bswap_16(x)
-#define be_swap32(x) bswap_32(x)
-#define be_swap64(x) bswap_64(x)
-#else
-#define be_swap16(x) (x)
-#define be_swap32(x) (x)
-#define be_swap64(x) (x)
-#endif
-
-
-#define swab16(x) x=be_swap16(x)
-#define swab32(x) x=be_swap32(x)
-#define swab64(x) x=be_swap64(x)
-
-
-#if defined(__sparc__)
-#define ALIGNED __attribute__((aligned))
-#define PACKED __attribute__((aligned,packed))
-#else
-#define ALIGNED
-#define PACKED __attribute__((packed))
-#endif
-
-#endif /* _PLATFORM_H */
diff --git a/rgmanager/include/pthread_dbg.h b/rgmanager/include/pthread_dbg.h
deleted file mode 100644
index 7b6d5e0..0000000
--- a/rgmanager/include/pthread_dbg.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef _PTHREAD_DBG_H
-#define _PTHREAD_DBG_H
-#include <pthread.h>
-
-#define pthread_mutex_lock(x) \
-{\
- printf("pthread_mutex_lock(%s) @ %s:%d in %s\n",\
- #x, __FILE__, __LINE__, __FUNCTION__); \
- pthread_mutex_lock(x);\
-}
-
-#define pthread_mutex_unlock(x) \
-{\
- printf("pthread_mutex_unlock(%s) @ %s:%d in %s\n",\
- #x, __FILE__, __LINE__, __FUNCTION__); \
- pthread_mutex_unlock(x);\
-}
-
-
-#define pthread_rwlock_rdlock(x) \
-{\
- printf("pthread_rwlock_rdlock(%s) @ %s:%d in %s\n",\
- #x, __FILE__, __LINE__, __FUNCTION__); \
- pthread_rwlock_rdlock(x);\
-}
-
-#define pthread_rwlock_unlock(x) \
-{\
- printf("pthread_rwlock_unlock(%s) @ %s:%d in %s\n",\
- #x, __FILE__, __LINE__, __FUNCTION__); \
- pthread_rwlock_unlock(x);\
-}
-
-#define pthread_rwlock_wrlock(x) \
-{\
- printf("pthread_rwlock_wrlock(%s) @ %s:%d in %s\n",\
- #x, __FILE__, __LINE__, __FUNCTION__); \
- pthread_rwlock_wrlock(x);\
-}
-
-#endif
diff --git a/rgmanager/include/res-ocf.h b/rgmanager/include/res-ocf.h
deleted file mode 100644
index cc65a4d..0000000
--- a/rgmanager/include/res-ocf.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef _RES_OCF_H
-#define _RES_OCF_H 1
-
-#define OCF_ROOT RESOURCE_ROOTDIR
-
-#define OCF_API_VERSION "1.0"
-
-#define OCF_RES_PREFIX "OCF_RESKEY_"
-
-#define OCF_ROOT_STR "OCF_ROOT"
-#define OCF_RA_VERSION_MAJOR_STR "OCF_RA_VERSION_MAJOR"
-#define OCF_RA_VERSION_MINOR_STR "OCF_RA_VERSION_MINOR"
-#define OCF_RESOURCE_INSTANCE_STR "OCF_RESOURCE_INSTANCE"
-#define OCF_CHECK_LEVEL_STR "OCF_CHECK_LEVEL"
-#define OCF_RESOURCE_TYPE_STR "OCF_RESOURCE_TYPE"
-#define OCF_REFCNT_STR "OCF_RESKEY_RGMANAGER_meta_refcnt"
-#define OCF_TIMEOUT_STR "OCF_RESKEY_RGMANAGER_meta_timeout"
-
-/*
- LSB return codes
- */
-#define OCF_RA_SUCCESS 0
-#define OCF_RA_ERROR 1
-#define OCF_RA_INVALID_ARG 2
-#define OCF_RA_UNIMPLEMENTED 3
-#define OCF_RA_PERMISSION 4
-#define OCF_RA_NOT_INSTALLED 5
-#define OCF_RA_NOT_CONFIGURED 6
-#define OCF_RA_NOT_RUNNING 7
-#define OCF_RA_MAX 7
-
-/*
- Resource operations - not ocf-specified
- */
-#define RS_START (0)
-#define RS_STOP (1)
-#define RS_STATUS (2)
-#define RS_RESINFO (3)
-#define RS_RESTART (4)
-#define RS_RELOAD (5)
-#define RS_CONDRESTART (6)
-#define RS_RECOVER (7)
-#define RS_CONDSTART (8) /** Start if flagged with RF_NEEDSTART */
-#define RS_CONDSTOP (9) /** STOP if flagged with RF_NEEDSTOP */
-#define RS_MONITOR (10)
-#define RS_META_DATA (11)
-#define RS_VALIDATE (12)
-#define RS_MIGRATE (13)
-#define RS_RECONFIG (14)
-#define RS_STATUS_INQUIRY (15) /** Quick status */
-#define RS_CONVALESCE (16)
-
-#endif
diff --git a/rgmanager/include/resgroup.h b/rgmanager/include/resgroup.h
deleted file mode 100644
index 59cd384..0000000
--- a/rgmanager/include/resgroup.h
+++ /dev/null
@@ -1,258 +0,0 @@
-#ifndef __RESGROUP_H
-#define __RESGROUP_H
-
-#include <pthread.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <sys/select.h>
-#include <gettid.h>
-#include <rg_locks.h>
-#include <message.h>
-#include <rg_queue.h>
-#include <signals.h>
-
-/**
- * Service state as represented on disk.
- *
- * This structure represents a service description. This data structure
- * represents the in-memory service description. (There is a separate
- * description of the on-disk format.)
- */
-typedef struct {
- char rs_name[64]; /**< Service name */
- /* 64 */
- uint32_t rs_id; /**< Service ID */
- uint32_t rs_magic; /**< Magic ID */
- uint32_t rs_owner; /**< Member ID running service. */
- uint32_t rs_last_owner; /**< Last member to run the service. */
- /* 80 */
- uint32_t rs_state; /**< State of service. */
- uint32_t rs_restarts; /**< Number of cluster-induced
- restarts */
- uint64_t rs_transition; /**< Last service transition time */
- /* 96 */
- uint32_t rs_flags; /**< User setted flags */
- /* 100 */
- uint8_t rs_version; /**< State version */
- uint8_t _pad_[3];
- /* 104 */
-} rg_state_t;
-
-#define swab_rg_state_t(ptr) \
-{\
- swab32((ptr)->rs_id);\
- swab32((ptr)->rs_magic);\
- swab32((ptr)->rs_owner);\
- swab32((ptr)->rs_last_owner);\
- swab32((ptr)->rs_state);\
- swab32((ptr)->rs_restarts);\
- swab64((ptr)->rs_transition);\
- swab32((ptr)->rs_flags);\
-}
-
-#if 0
-/* Future upgrade compatibility */
-#define RG_STATE_MINSIZE 96
-#define RG_STATE_CURRENT_VERSION 1
-
-extern size_t rg_state_t_version_sizes[];
-#endif
-
-
-#define RG_PORT 177
-
-/* Constants moved to src/clulib/constants.c */
-/* DO NOT EDIT */
-#define RG_MAGIC 0x11398fed
-
-#define RG_ACTION_REQUEST /* Message header */ 0x138582
-/* Argument to RG_ACTION_REQUEST */
-#define RG_ACTION_MASTER 0xfe0db143
-#define RG_ACTION_USER 0x3f173bfd
-/* */
-#define RG_EVENT 0x138583
-
-/* Requests */
-#define RG_SUCCESS 0
-#define RG_FAIL 1
-#define RG_START 2
-#define RG_STOP 3
-#define RG_STATUS 4
-#define RG_DISABLE 5
-#define RG_STOP_RECOVER 6
-#define RG_START_RECOVER 7
-#define RG_RESTART 8
-#define RG_EXITING 9
-#define RG_INIT 10
-#define RG_ENABLE 11
-#define RG_STATUS_NODE 12
-#define RG_RELOCATE 13
-#define RG_CONDSTOP 14
-#define RG_CONDSTART 15
-#define RG_START_REMOTE 16 /* Part of a relocate */
-#define RG_STOP_USER 17 /* User-stop request */
-#define RG_STOP_EXITING 18 /* Exiting. */
-#define RG_LOCK 19
-#define RG_UNLOCK 20
-#define RG_QUERY_LOCK 21
-#define RG_MIGRATE 22
-#define RG_FREEZE 23
-#define RG_UNFREEZE 24
-#define RG_STATUS_INQUIRY 25
-#define RG_CONVALESCE 26
-#define RG_NONE 999
-
-const char *rg_req_str(int req);
-
-int handle_relocate_req(char *svcName, int request, int preferred_target,
- int *new_owner);
-int handle_start_req(char *svcName, int req, int *new_owner);
-int handle_fd_start_req(char *svcName, int req, int *new_owner);
-int handle_recover_req(char *svcName, int *new_owner);
-int handle_start_remote_req(char *svcName, int req);
-
-/* Resource group states (for now) */
-#define RG_STATE_BASE 110
-#define RG_STATE_STOPPED 110 /** Resource group is stopped */
-#define RG_STATE_STARTING 111 /** Resource is starting */
-#define RG_STATE_STARTED 112 /** Resource is started */
-#define RG_STATE_STOPPING 113 /** Resource is stopping */
-#define RG_STATE_FAILED 114 /** Resource has failed */
-#define RG_STATE_UNINITIALIZED 115 /** Thread not running yet */
-#define RG_STATE_CHECK 116 /** Checking status */
-#define RG_STATE_ERROR 117 /** Recoverable error */
-#define RG_STATE_RECOVER 118 /** Pending recovery */
-#define RG_STATE_DISABLED 119 /** Resource not allowd to run */
-#define RG_STATE_MIGRATE 120 /** Resource migrating */
-
-#define DEFAULT_CHECK_INTERVAL 10
-
-/* Resource group flags (for now) */
-#define RG_FLAG_FROZEN (1<<0) /** Resource frozen */
-#define RG_FLAG_PARTIAL (1<<1) /** One or more non-critical
- resources offline */
-
-const char *rg_state_str(int val);
-const char *rg_flag_str(int val);
-const char *rg_flags_str(char *flags_string, size_t size, int val, char *separator);
-int rg_state_str_to_id(const char *val);
-const char *rg_flags_str(char *flags_string, size_t size, int val, char *separator);
-const char *agent_op_str(int val);
-
-int eval_groups(int local, uint32_t nodeid, int nodeStatus);
-int group_migrate(const char *groupname, int target);
-
-int rg_status(const char *resgroupname);
-int group_op(const char *rgname, int op);
-void rg_init(void);
-int init_resource_groups(int, int);
-
-/* Basic service operations */
-int svc_start(const char *svcName, int req);
-int svc_stop(const char *svcName, int error);
-int svc_status(const char *svcName);
-int svc_status_inquiry(const char *svcName);
-int svc_disable(const char *svcName);
-int svc_fail(const char *svcName);
-int svc_freeze(const char *svcName);
-int svc_unfreeze(const char *svcName);
-int svc_convalesce(const char *svcName);
-int svc_migrate(const char *svcName, int target);
-int svc_start_remote(const char *svcName, int request, uint32_t target);
-int svc_report_failure(const char *svcName);
-
-int rt_enqueue_request(const char *resgroupname, int request,
- msgctx_t *resp_ctx,
- int max, uint32_t target, int arg0, int arg1);
-void dump_threads(FILE *fp);
-
-void send_response(int ret, int node, request_t *req);
-void send_ret(msgctx_t *ctx, char *name, int ret, int orig_request,
- int new_owner);
-
-/* from rg_state.c */
-int set_rg_state(const char *name, rg_state_t *svcblk);
-int get_rg_state(const char *servicename, rg_state_t *svcblk);
-int get_rg_state_local(const char *servicename, rg_state_t *svcblk);
-uint32_t best_target_node(cluster_member_list_t *allowed, uint32_t owner,
- const char *rg_name, int lock);
-
-extern int cluster_timeout;
-
-#ifdef DEBUG
-int _rg_lock(const char *name, struct dlm_lksb *p);
-int _rg_lock_dbg(const char *, struct dlm_lksb *, const char *, int);
-#define rg_lock(name, p) _rg_lock_dbg(name, p, __FILE__, __LINE__)
-
-int _rg_unlock(struct dlm_lksb *p);
-int _rg_unlock_dbg(struct dlm_lksb *, const char *, int);
-#define rg_unlock(p) _rg_unlock_dbg(p, __FILE__, __LINE__)
-
-#else
-int rg_lock(const char *name, struct dlm_lksb *p);
-int rg_unlock(struct dlm_lksb *p);
-#endif
-
-
-/* Return codes */
-#define RG_EWARNING -19 /* Warning (see logs) */
-#define RG_EPERM -18 /* Permission denied */
-#define RG_ERELO -17 /* Relocation failure; service running
- on original node */
-#define RG_EEXCL -16 /* Service not runnable due to
- inability to start exclusively */
-#define RG_EDOMAIN -15 /* Service not runnable given the
- set of nodes and its failover
- domain */
-#define RG_ESCRIPT -14 /* S/Lang script failed */
-#define RG_EFENCE -13 /* Fencing operation pending */
-#define RG_ENODE -12 /* Node is dead/nonexistent */
-#define RG_EFROZEN -11 /* Service is frozen */
-#define RG_ERUN -10 /* Service is already running */
-#define RG_EQUORUM -9 /* Operation requires quorum */
-#define RG_EINVAL -8 /* Invalid operation for resource */
-#define RG_EDEPEND -7 /* Operation violates dependency */
-#define RG_EAGAIN -6 /* Try again */
-#define RG_EDEADLCK -5 /* Aborted - would deadlock */
-#define RG_ENOSERVICE -4 /* Service does not exist */
-#define RG_EFORWARD -3 /* Service not mastered locally */
-#define RG_EABORT -2 /* Abort; service unrecoverable */
-#define RG_EFAIL -1 /* Generic failure */
-#define RG_ESUCCESS 0
-#define RG_YES 1
-#define RG_NO 2
-
-
-const char *rg_strerror(int val);
-
-/*
- Status tree flags
- */
-#define SFL_FAILURE (1<<0)
-#define SFL_RECOVERABLE (1<<1)
-#define SFL_PARTIAL (1<<2)
-
-//#define DEBUG
-#ifdef DEBUG
-
-#define dbg_printf(fmt, args...) \
-{\
- printf("{%d} ", gettid());\
- printf(fmt, ##args);\
- fflush(stdout);\
-}
-
-#else /* DEBUG */
-
-#define dbg_printf(fmt, args...)
-
-#endif
-
-#endif
diff --git a/rgmanager/include/reslist.h b/rgmanager/include/reslist.h
deleted file mode 100644
index 93efeaa..0000000
--- a/rgmanager/include/reslist.h
+++ /dev/null
@@ -1,210 +0,0 @@
-#ifndef _RESLIST_H
-#define _RESLIST_H
-
-#include <stdint.h>
-#include <libxml/parser.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/xpath.h>
-
-
-#define RA_PRIMARY (1<<0) /** Primary key */
-#define RA_UNIQUE (1<<1) /** Unique for given type */
-#define RA_REQUIRED (1<<2) /** Required (or an error if not present */
-#define RA_INHERIT (1<<3) /** Inherit a parent resource's attr */
-#define RA_RECONFIG (1<<4) /** Allow inline reconfiguration */
-
-#define RF_INLINE (1<<0)
-#define RF_DEFINED (1<<1)
-#define RF_NEEDSTART (1<<2) /** Used when adding/changing resources */
-#define RF_NEEDSTOP (1<<3) /** Used when deleting/changing resources */
-#define RF_COMMON (1<<4) /** " */
-#define RF_INDEPENDENT (1<<5) /** Define this for a resource if it is
- otherwise an independent subtree */
-#define RF_RECONFIG (1<<6)
-
-#define RF_INIT (1<<7) /** Resource rule: Initialize this resource
- class on startup */
-#define RF_DESTROY (1<<8) /** Resource rule flag: Destroy this
- resource class if you delete it from
- the configuration */
-#define RF_ENFORCE_TIMEOUTS (1<<9) /** Enforce timeouts for this node */
-#define RF_NON_CRITICAL (1<<10) /** stop this resource if it fails */
-#define RF_QUIESCE (1<<11) /** don't restart this resource */
-
-
-
-#define RES_STOPPED (0)
-#define RES_STARTED (1)
-#define RES_FAILED (2)
-#define RES_DISABLED (3)
-
-#ifndef SHAREDIR
-#define SHAREDIR "/usr/share/rgmanager"
-#endif
-
-#define RESOURCE_ROOTDIR SHAREDIR
-#define RESOURCE_TREE_ROOT "/cluster/rm"
-#define RESOURCE_BASE RESOURCE_TREE_ROOT "/resources"
-#define RESOURCE_DEFAULTS RESOURCE_TREE_ROOT "/resource-defaults"
-#define RESOURCE_ROOT_FMT RESOURCE_TREE_ROOT "/%s[%d]"
-
-#define RESOURCE_MAX_LEVELS 100
-
-/* Include OCF definitions */
-#include <res-ocf.h>
-
-
-typedef struct _resource_attribute {
- char *ra_name;
- char *ra_value;
- int ra_flags;
- int _pad_;
-} resource_attr_t;
-
-
-typedef struct _resource_child {
- char *rc_name;
- int rc_startlevel;
- int rc_stoplevel;
- int rc_forbid;
- int rc_flags;
-} resource_child_t;
-
-
-typedef struct _resource_act {
- char *ra_name;
- time_t ra_timeout;
- time_t ra_last;
- time_t ra_interval;
- int ra_depth;
- int ra_flags;
-} resource_act_t;
-
-
-typedef struct _resource_rule {
- list_head();
- char * rr_type;
- char * rr_agent;
- char * rr_version; /** agent XML spec version; OCF-ism */
- int rr_flags;
- int rr_maxrefs;
- resource_attr_t * rr_attrs;
- resource_child_t * rr_childtypes;
- resource_act_t * rr_actions;
-} resource_rule_t;
-
-
-typedef struct _resource {
- list_head();
- pthread_mutex_t r_mutex;
- resource_rule_t * r_rule;
- char * r_name;
- resource_attr_t * r_attrs;
- resource_act_t * r_actions;
- int r_flags;
- int r_refs;
- int r_incarnations; /** Number of instances running locally */
- int _pad_; /* align */
-} resource_t;
-
-
-typedef struct _rg_node {
- list_head();
- struct _rg_node *rn_child, *rn_parent;
- resource_t *rn_resource;
- resource_act_t *rn_actions;
- restart_counter_t rn_restart_counter;
- restart_counter_t rn_failure_counter;
- int rn_state; /* State of this instance of rn_resource */
- int rn_flags;
- int rn_last_status;
- int rn_last_depth;
- int rn_checked;
- int rn_pad;
-} resource_node_t;
-
-
-/*
- Exported Functions
- */
-int res_start(resource_node_t **tree, resource_t *res, void *ret);
-int res_stop(resource_node_t **tree, resource_t *res, void *ret);
-int res_status(resource_node_t **tree, resource_t *res, void *ret);
-int res_status_inquiry(resource_node_t **tree, resource_t *res, void *ret);
-int res_convalesce(resource_node_t **tree, resource_t *res, void *ret);
-int res_condstart(resource_node_t **tree, resource_t *res, void *ret);
-int res_condstop(resource_node_t **tree, resource_t *res, void *ret);
-int res_exec(resource_node_t *node, int op, const char *arg, int depth);
-/*int res_resinfo(resource_node_t **tree, resource_t *res, void *ret);*/
-int expand_time(const char *val);
-int store_action(resource_act_t **actsp, char *name, int depth, int timeout, int interval);
-
-
-/*
- Calculate differences
- */
-int resource_delta(resource_t **leftres, resource_t **rightres);
-int resource_tree_delta(resource_node_t **, resource_node_t **);
-
-
-/*
- Load/kill resource rule sets
- */
-int load_resource_rules(const char *rpath, resource_rule_t **rules);
-int load_resource_defaults(int ccsfd, resource_rule_t **rules);
-void print_resource_rule(FILE *fp, resource_rule_t *rule);
-void print_resource_rules(resource_rule_t **rules);
-void dump_resource_rules(FILE *fp, resource_rule_t **rules);
-void destroy_resource_rules(resource_rule_t **rules);
-
-/*
- Load/kill resource sets
- */
-int load_resources(int ccsfd, resource_t **reslist, resource_rule_t **rulelist);
-void print_resource(FILE *fp, resource_t *res);
-void print_resources(resource_t **reslist);
-void dump_resources(FILE *fp, resource_t **reslist);
-void destroy_resources(resource_t **list);
-
-/*
- Construct/deconstruct resource trees
- */
-int build_resource_tree(int ccsfd, resource_node_t **tree,
- resource_rule_t **rulelist, resource_t **reslist);
-void print_resource_tree(resource_node_t **tree);
-void dump_resource_tree(FILE *fp, resource_node_t **tree);
-void destroy_resource_tree(resource_node_t **tree);
-
-resource_act_t *act_dup(resource_act_t *acts);
-void dump_resource_info(FILE *fp);
-
-
-/*
- Handy functions
- */
-resource_t *find_resource_by_ref(resource_t **reslist, const char *type,
- const char *ref);
-resource_t *find_root_by_ref(resource_t **reslist, const char *ref);
-resource_rule_t *find_rule_by_type(resource_rule_t **rulelist,
- const char *type);
-void res_build_name(char *, size_t, resource_t *);
-
-/*
- Internal functions; shouldn't be needed.
- */
-char *xpath_get_one(xmlDocPtr doc, xmlXPathContextPtr ctx,
- const char *query);
-int store_attribute(resource_attr_t **attrsp, char *name, char *value,
- int flags);
-
-resource_t *load_resource(int ccsfd, resource_rule_t *rule, char *base);
-int store_resource(resource_t **reslist, resource_t *newres);
-void destroy_resource(resource_t *res);
-
-const char *attr_value(resource_node_t *node, const char *attrname);
-const char *rg_attr_value(resource_node_t *node, const char *attrname);
-const char *res_attr_value(resource_t *res, const char *attrname);
-const char *primary_attr_value(resource_t *);
-int rescmp(resource_t *l, resource_t *r);
-
-#endif /* _RESLIST_H */
diff --git a/rgmanager/include/restart_counter.h b/rgmanager/include/restart_counter.h
deleted file mode 100644
index d003584..0000000
--- a/rgmanager/include/restart_counter.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* Time-based restart counters for rgmanager */
-
-#ifndef _RESTART_COUNTER_H
-#define _RESTART_COUNTER_H
-
-typedef void *restart_counter_t;
-
-int restart_add(restart_counter_t arg);
-int restart_clear(restart_counter_t arg);
-int restart_count(restart_counter_t arg);
-int restart_threshold_exceeded(restart_counter_t arg);
-restart_counter_t restart_init(time_t expire_timeout, int max_restarts);
-int restart_cleanup(restart_counter_t arg);
-
-#endif
diff --git a/rgmanager/include/rg_dbus.h b/rgmanager/include/rg_dbus.h
deleted file mode 100644
index 3ef5ae1..0000000
--- a/rgmanager/include/rg_dbus.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef _RGM_DBUS_H
-#define _RGM_DBUS_H
-
-int rgm_dbus_init(void);
-int rgm_dbus_release(void);
-extern int rgm_dbus_notify;
-
-#ifdef DBUS
-
-#define RGM_DBUS_DEFAULT 1
-#define RGM_DBUS_UPDATE (rgm_dbus_notify?rgm_dbus_update:0)
-int32_t rgm_dbus_update(char *key, uint64_t view, void *data, uint32_t size);
-
-#else
-
-#define RGM_DBUS_DEFAULT 0
-#define RGM_DBUS_UPDATE NULL
-
-#endif /* DBUS */
-#endif
diff --git a/rgmanager/include/rg_locks.h b/rgmanager/include/rg_locks.h
deleted file mode 100644
index a64d58f..0000000
--- a/rgmanager/include/rg_locks.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef __RG_LOCKS_H
-#define __RG_LOCKS_H
-
-int rg_running(void);
-
-int rg_locked(void);
-
-#define L_SHUTDOWN (1<<2)
-#define L_SYS (1<<1)
-#define L_USER (1<<0)
-
-int rg_lockall(int flag);
-int rg_unlockall(int flag);
-
-int rg_quorate(void);
-int rg_set_quorate(void);
-int rg_set_inquorate(void);
-
-int rg_inc_threads(void);
-int rg_dec_threads(void);
-int rg_wait_threads(void);
-
-int rg_initialized(void);
-int rg_set_initialized(int);
-int rg_clear_initialized(int);
-int rg_wait_initialized(int);
-
-#define FL_INIT 0x1
-#define FL_CONFIG 0x2
-
-int rg_inc_status(void);
-int rg_dec_status(void);
-int rg_set_statusmax(int max);
-
-int rg_inc_children(void);
-int rg_dec_children(void);
-int rg_set_childmax(int max);
-
-int ccs_lock(void);
-int ccs_unlock(int fd);
-
-#ifdef NO_CCS
-int conf_get(const char *query, char **ret);
-void conf_setconfig(const char *path);
-#endif
-
-#endif
diff --git a/rgmanager/include/rg_queue.h b/rgmanager/include/rg_queue.h
deleted file mode 100644
index e7ea29a..0000000
--- a/rgmanager/include/rg_queue.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef _RG_QUEUE_H
-#define _RG_QUEUE_H
-#include <list.h>
-#include <stdint.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <message.h>
-
-
-/**
- * Resource Group thread request queue entry.
- */
-typedef struct _request {
- list_head(); /** Next/prev pointers */
- char rr_group[64]; /** Resource Group */
- uint32_t rr_request; /** Request */
- uint32_t rr_errorcode; /** Error condition */
- uint32_t rr_orig_request; /** Original request */
- uint32_t rr_target; /** Target node */
- uint32_t rr_arg0; /** Integer argument */
- uint32_t rr_arg1; /** Integer argument */
- uint32_t rr_arg2; /** Integer argument */
- uint32_t rr_line; /** Line no */
- msgctx_t * rr_resp_ctx; /** FD to send response */
- const char *rr_file; /** Who made req */
- time_t rr_when; /** time to execute */
-} request_t;
-
-
-int _rq_queue_request(request_t **queue, char *name, uint32_t request,
- uint32_t err, uint32_t oldreq, msgctx_t *ctx, time_t when,
- uint32_t target, uint32_t arg0, uint32_t arg1,
- const char *file, int line);
-
-#define rq_queue_request(queue, name, request, err, oldreq,\
- fd, when, target, arg0, arg1) \
- _rq_queue_request(queue, name, request, err, oldreq, fd, when, \
- target, arg0, arg1, __FILE__, __LINE__)
-
-request_t *rq_next_request(request_t **q);
-int rq_queue_empty(request_t **q);
-void rq_free(request_t *foo);
-
-void forward_request(request_t *req);
-void forward_message(msgctx_t *ctx, void *msg, int nodeid);
-
-
-#endif
diff --git a/rgmanager/include/rg_types.h b/rgmanager/include/rg_types.h
deleted file mode 100644
index a6a2b5f..0000000
--- a/rgmanager/include/rg_types.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _RG_TYPES_H
-#define _RG_TYPES_H
-
-#include <stdint.h>
-#include <arpa/inet.h>
-#include <libcman.h>
-#include <libdlm.h>
-
-typedef struct cluster_members {
- int cml_count;
- int pad;
- cman_node_t *cml_members;
-} cluster_member_list_t;
-
-#define RG_PORT 177
-#define RGMGR_SOCK "/var/run/cluster/rgmanager.sk"
-
-#endif
diff --git a/rgmanager/include/rmtab.h b/rgmanager/include/rmtab.h
deleted file mode 100644
index f0bd9b1..0000000
--- a/rgmanager/include/rmtab.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/** @file
- * Header for rmtab.c.
- */
-/*
- * Author: Lon H. Hohberger <lhh at redhat.com>
- */
-#ifndef _RMTAB_H
-#define _RMTAB_H
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-/* Shamelessly ripped from nfs-utils */
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-#ifndef _PATH_RMTAB
-#define _PATH_RMTAB "/var/lib/nfs/rmtab"
-#endif
-
-/* private types */
-#ifndef MSG_RMTAB_UPDATE
-#define MSG_RMTAB_UPDATE 978
-#endif
-
-#ifndef MSG_RMTAB_BOOT
-#define MSG_RMTAB_BOOT 603
-#endif
-
-/* Just a mem-size trim for now */
-#define __MAXPATHLEN 1024
-
-/**
- * rmtab node list entry.
- *
- * This contains all the information necessary to reconstruct a line in
- * /var/lib/nfs/rmtab.
- */
-typedef struct _rmtab_node {
- struct _rmtab_node *rn_next; /**< Next pointer */
- char *rn_hostname; /**< Mount entry hostname */
- char *rn_path; /**< Export mounted */
- uint32_t rn_count; /**< Number of times export is
- mounted. */
-} rmtab_node;
-
-
-/*
- * list addition (insert)
- */
-int __rmtab_insert(rmtab_node **head, rmtab_node *rnew);
-rmtab_node *rmtab_insert(rmtab_node **head, rmtab_node *pre, char *host,
- char *path, int count);
-
-/*
- * list deletion/removal/etc.
- */
-rmtab_node *__rmtab_remove(rmtab_node **head, rmtab_node *entry);
-rmtab_node *rmtab_remove(rmtab_node **head, char *host, char *path);
-void rmtab_kill(rmtab_node **head);
-
-/*
- * diff/merge functions
- */
-int rmtab_diff(rmtab_node *old, rmtab_node *new, rmtab_node **diff);
-int rmtab_merge(rmtab_node **head, rmtab_node *patch);
-
-/*
- * Read/write/import/export...
- */
-int rmtab_import(rmtab_node **head, FILE *fp);
-int rmtab_export(rmtab_node *head, FILE *fp);
-
-int rmtab_read(rmtab_node **head, char *filename);
-int rmtab_write_atomic(rmtab_node *head, char *filename);
-
-/*
- * Translation to/from network block [array] style
- */
-int rmtab_pack(char *dest, rmtab_node *head);
-int rmtab_unpack(rmtab_node **dest, char *src, size_t srclen);
-
-/*
- * utility functions
- */
-int rmtab_cmp_min(rmtab_node *left, rmtab_node *right);
-int rmtab_cmp(rmtab_node *left, rmtab_node *right);
-size_t rmtab_pack_size(rmtab_node *head);
-int rmtab_move(rmtab_node **dest, rmtab_node **src);
-
-/*
- * DEBUG junk
- */
-#ifdef DEBUG
-int rmtab_dump(rmtab_node *head);
-#endif
-
-#endif
diff --git a/rgmanager/include/sets.h b/rgmanager/include/sets.h
deleted file mode 100644
index eb499e6..0000000
--- a/rgmanager/include/sets.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- @file sets.h - Header file for sets.c
- @author Lon Hohberger <lhh at redhat.com>
- */
-#ifndef _SETS_H
-#define _SETS_H
-
-/* #include <stdint.h> */
-typedef int set_type_t;
-
-int s_add(set_type_t *, int *, set_type_t);
-int s_union(set_type_t *, int, set_type_t *,
- int, set_type_t **, int *);
-
-int s_intersection(set_type_t *, int, set_type_t *,
- int, set_type_t **, int *);
-int s_delta(set_type_t *, int, set_type_t *,
- int, set_type_t **, int *);
-int s_subtract(set_type_t *, int, set_type_t *, int, set_type_t **, int *);
-int s_shuffle(set_type_t *, int);
-
-#endif
diff --git a/rgmanager/include/signals.h b/rgmanager/include/signals.h
deleted file mode 100644
index c5f7d6c..0000000
--- a/rgmanager/include/signals.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __SIGNALS_H
-#define __SIGNALS_H
-
-void *setup_signal(int, void (*)(int));
-int block_signal(int sig);
-int unblock_signal(int sig);
-int block_all_signals(void);
-
-#endif
diff --git a/rgmanager/include/sock.h b/rgmanager/include/sock.h
deleted file mode 100644
index 6cd2331..0000000
--- a/rgmanager/include/sock.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _SOCK_H
-#define _SOCK_H
-
-ssize_t read_retry(int sockfd, void *buf, size_t count,
- struct timeval * timeout);
-int select_retry(int fdmax, fd_set * rfds, fd_set * wfds, fd_set * xfds,
- struct timeval *timeout);
-ssize_t write_retry(int fd, void *buf, size_t count,
- struct timeval *timeout);
-
-int sock_listen(const char *sockpath);
-int sock_connect(const char *sockpath, int tout);
-int sock_accept(int fd);
-void hexdump(const void *buf, size_t len);
-
-void *do_alloc(size_t);
-
-#endif
diff --git a/rgmanager/include/vf.h b/rgmanager/include/vf.h
deleted file mode 100644
index d57b0cf..0000000
--- a/rgmanager/include/vf.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/** @file
- * Header for vf.c.
- */
-#ifndef __VF_H
-#define __VF_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <msgsimple.h>
-
-/*
- * We use this to initiate the VF protocol. This doesn't really belong here.
- */
-typedef struct __attribute__ ((packed)) _vf_msg_info {
- uint32_t vf_command;
- uint32_t vf_transaction;
- char vf_keyid[64];
- uint32_t vf_coordinator; /* Node ID of who coordinates */
- uint32_t vf_datalen;
- uint64_t vf_view;
- char vf_data[0];
-} vf_msg_info_t;
-
-#define swab_vf_msg_info_t(ptr) \
-{\
- swab32((ptr)->vf_command);\
- swab32((ptr)->vf_transaction);\
- swab32((ptr)->vf_coordinator);\
- swab64((ptr)->vf_view);\
- swab32((ptr)->vf_datalen);\
-}
-
-
-typedef struct __attribute__ ((packed)) _vf_msg {
- generic_msg_hdr vm_hdr;
- vf_msg_info_t vm_msg;
-} vf_msg_t;
-
-#define swab_vf_msg_t(ptr) \
-{\
- swab_generic_msg_hdr(&((ptr)->vm_hdr));\
- swab_vf_msg_info_t(&((ptr)->vm_msg));\
-}
-
-
-/*
- * Exp: Callback function proto definitions.
- */
-typedef int32_t (*vf_vote_cb_t)(char *, uint64_t, void *, uint32_t);
-typedef int32_t (*vf_commit_cb_t)(char *, uint64_t, void *, uint32_t);
-
-/*
- * INTERNAL VF STRUCTURES
- */
-
- /**
- * A view node. This holds the data from a VF_JOIN_VIEW message until it
- * is committed.
- */
-typedef struct _view_node {
- struct _view_node *
- vn_next; /**< Next pointer. */
- uint32_t vn_transaction; /**< Transaction ID */
- uint32_t vn_nodeid; /**< Node ID of coordinator. */
- struct timeval vn_timeout; /**< Expiration time. */
- uint64_t vn_viewno; /**< View Number. */
- uint32_t vn_datalen; /**< Length of included data. */
- uint32_t vn_pad; /**< pad */
- char vn_data[0]; /**< Included data. */
-} view_node_t;
-
-
-/**
- * A commit node. This holds a commit message until it is possible to
- * resolve it with its corresponding view_node_t.
- */
-typedef struct _commit_node {
- struct _commit_node *
- vc_next; /**< Next pointer. */
- uint32_t vc_transaction; /**< Transaction ID */
-} commit_node_t;
-
-
-/**
- * A key node. For each type of data used, a key node is created
- * and managed by the programmer.
- */
-typedef struct _key_node {
- struct _key_node *kn_next; /**< Next pointer. */
- char *kn_keyid; /**< Key ID this key node refers to. */
- uint32_t kn_pid; /**< PID. Child process running
- View-Formation on this key. */
- uint32_t kn_datalen; /**< Current length of data. */
- view_node_t *kn_jvlist; /**< Buffered join-view list. */
- commit_node_t *kn_clist; /**< Buffered commit list. */
- uint64_t kn_viewno; /**< Current view number of data. */
- char *kn_data; /**< Current data. */
- int kn_tsec; /**< Default timeout (in seconds */
- int kn_pad; /**< pad */
- vf_vote_cb_t kn_vote_cb; /**< Voting callback function */
- vf_commit_cb_t kn_commit_cb; /**< Commit callback function */
-} key_node_t;
-
-
-
-
-/*
- * VF message types.
- */
-/* Main programs handle this */
-#define VF_MESSAGE 0x3000
-
-/* Subtypes */
-#define VF_JOIN_VIEW 0x3001
-#define VF_VOTE 0x3002
-#define VF_ABORT 0x3004
-#define VF_VIEW_FORMED 0x3005
-#define VF_CURRENT 0x3006
-#define VF_ACK 0x3007
-#define VF_NACK 0x3008
-
-#define vf_command(x) (x&0x0000ffff)
-#define vf_flags(x) (x&0xffff0000)
-
-#define VFMF_AFFIRM 0x00010000
-
-
-#define VF_COORD_TIMEOUT 60 /* 60 seconds MAX timeout */
-#define VF_COMMIT_TIMEOUT_MIN (2 * VF_COORD_TIMEOUT)
-
-/* Return codes for vf_handle_msg... */
-#define VFR_ERROR 100
-#define VFR_TIMEOUT 101
-#define VFR_OK 0
-#define VFR_YES VFR_OK
-#define VFR_NO 1
-#define VFR_COMMIT 2
-#define VFR_ABORT 3
-#define VFR_NODATA 4
-
-/*
- * Operational flags for vf_start
- */
-#define VFF_RETRY 0x1
-#define VFF_IGN_CONN_ERRORS 0x2
-#define VFF_IGN_WRITE_ERRORS 0x4
-#define VFF_IGN_READ_ERRORS 0x8
-#define VFF_IGN_ALL_ERRORS (VFF_IGN_CONN_ERRORS|VFF_IGN_WRITE_ERRORS|\
- VFF_IGN_READ_ERRORS)
-
-
-/*
- * VF Stuff. VF only talks to peers.
- */
-int vf_init(int, uint16_t, vf_vote_cb_t, vf_commit_cb_t, int);
-int vf_invalidate(void);
-int vf_shutdown(void);
-
-/*
- * Returns a file descriptor on which the caller can select().
- *
- * This is a pipe which is used to notify the parent process that
- * the child has exited
- */
-int vf_write(cluster_member_list_t *membership, uint32_t flags,
- const char *keyid, const void *data, uint32_t datalen);
-int vf_read(cluster_member_list_t *membership, const char *keyid,
- uint64_t *view, void **data, uint32_t *datalen);
-int vf_read_local(const char *keyid, uint64_t *view, void **data,
- uint32_t *datalen);
-
-int vf_key_init(const char *keyid, int timeout, vf_vote_cb_t vote_cb,
- vf_commit_cb_t commit_cb);
-int getuptime(struct timeval *tv);
-int vf_process_msg(msgctx_t *ctx, int nodeid, generic_msg_hdr *msgp, int nbytes);
-void dump_vf_states(FILE *fp);
-
-#define MSGP_VFS 0x18dcf1
-#define MSGP_VFC 0x0103fab
-
-#endif
diff --git a/rgmanager/init.d/Makefile b/rgmanager/init.d/Makefile
deleted file mode 100644
index 959ddb3..0000000
--- a/rgmanager/init.d/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-TARGET=rgmanager cpglockd cpglockd.init.defaults
-
-INITDT=rgmanager cpglockd
-
-all: $(TARGET)
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-%: $(S)/%.in
- cat $^ | sed \
- -e 's#@SBINDIR@#${sbindir}#g' \
- -e 's#@INITDDIR@#${initddir}#g' \
- > $@
-
-clean: generalclean
-
-check:
diff --git a/rgmanager/init.d/cpglockd.in b/rgmanager/init.d/cpglockd.in
deleted file mode 100644
index 772e0e8..0000000
--- a/rgmanager/init.d/cpglockd.in
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/bin/bash
-#
-# chkconfig: - 99 01
-# description: Starts and stops the CPG lock daemon
-#
-#
-### BEGIN INIT INFO
-# Provides: cpglockd
-# Required-Start: cman
-# Required-Stop: cman
-# Default-Start:
-# Default-Stop:
-# Short-Description: Starts and stops the CPG lock daemon
-# Description: Starts and stops the CPG lock daemon
-### END INIT INFO
-
-ID="CPG lock daemon"
-CPGLOCKD="cpglockd"
-
-# set secure PATH
-PATH="/sbin:/bin:/usr/sbin:/usr/bin:@SBINDIR@"
-
-success()
-{
- echo -ne "[ OK ]\r"
-}
-
-failure()
-{
- echo -ne "[FAILED]\r"
-}
-
-status()
-{
- pid=$(pidof $1 2>/dev/null)
- statusrtrn=$?
- if [ $statusrtrn -ne 0 ]; then
- echo "$1 is stopped"
- else
- echo "$1 (pid $pid) is running..."
- fi
- return $statusrtrn
-}
-
-# rpm based distros
-if [ -d /etc/sysconfig ]; then
- [ -f @INITDDIR@/functions ] && . @INITDDIR@/functions
- [ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster
- [ -f /etc/sysconfig/rgmanager ] && . /etc/sysconfig/rgmanager
- [ -f /etc/sysconfig/cpglockd ] && . /etc/sysconfig/cpglockd
- [ -z "$LOCK_FILE" ] && LOCK_FILE="/var/lock/subsys/cpglockd"
-fi
-
-# deb based distros
-if [ -d /etc/default ]; then
- [ -f /etc/default/cluster ] && . /etc/default/cluster
- [ -f /etc/default/rgmanager ] && . /etc/default/rgmanager
- [ -f /etc/default/cpglockd ] && . /etc/default/cpglockd
- [ -z "$LOCK_FILE" ] && LOCK_FILE="/var/lock/cpglockd"
-fi
-
-[ -z "$CPGLOCKD_WAIT_FOR_QUORUM" ] && CPGLOCKD_WAIT_FOR_QUORUM="yes"
-[ -z "$CPGLOCKD_WAIT_FOR_FENCE_JOIN" ] && CPGLOCKD_WAIT_FOR_FENCE_JOIN="yes"
-
-#
-# Stop cpglockd
-#
-stop_cpglockd()
-{
- kill -TERM $(pidof $CPGLOCKD)
-}
-
-rtrn=0
-
-if [ "$EUID" != "0" ]; then
- echo "Only root can execute $0 script"
- exit 4
-fi
-
-case "$1" in
-start)
- echo -n "Starting $ID: "
-
- # most recent distributions use tmpfs for /var/run
- # to avoid to clean it up on every boot.
- # they also assume that init scripts will create
- # required subdirectories for proper operations
- mkdir -p /var/run/cluster
- [ "$CPGLOCKD_WAIT_FOR_QUORUM" = "no" ] && CPGLOCKD_OPTS+=" -Q"
- [ "$CPGLOCKD_WAIT_FOR_FENCE_JOIN" = "no" ] && CPGLOCKD_OPTS+=" -F"
-
- if status $CPGLOCKD > /dev/null 2>&1; then
- success
- else
- if $CPGLOCKD $CPGLOCKD_OPTS; then
- touch $LOCK_FILE
- success
- else
- failure
- rtrn=1
- fi
- fi
- echo
-;;
-restart)
- $0 stop
- $0 start
-;;
-condrestart|try-restart)
- if status $CPGLOCKD > /dev/null 2>&1; then
- $0 stop
- $0 start
- rtrn=$?
- fi
-;;
-reload|force-reload)
- # not required anymore
- # return not implemented
- rtrn=3
-;;
-status)
- status $CPGLOCKD
- rtrn=$?
-;;
-stop)
- echo -n "Stopping $ID: "
-
- if status $CPGLOCKD > /dev/null 2>&1; then
- if stop_cpglockd; then
- success
- else
- failure
- rtrn=1
- fi
- else
- success
- fi
- echo
- rm -f $LOCK_FILE
-;;
-*)
- echo "usage: $0 {start|stop|restart|condrestart|try-restart|reload|force-reload|status}"
- rtrn=2
-;;
-esac
-
-exit $rtrn
diff --git a/rgmanager/init.d/cpglockd.init.defaults.in b/rgmanager/init.d/cpglockd.init.defaults.in
deleted file mode 100644
index 29caf27..0000000
--- a/rgmanager/init.d/cpglockd.init.defaults.in
+++ /dev/null
@@ -1,7 +0,0 @@
-# CPGLOCKD_WAIT_FOR_QUORUM -- Wait for cluster quorum formation
-# at startup.
-#CPGLOCKD_WAIT_FOR_QUORUM=yes
-#
-# CPGLOCKD_WAIT_FOR_FENCE_JOIN -- Wait for the current node to join the
-# fence domain at startup.
-#CPGLOCKD_WAIT_FOR_FENCE_JOIN=yes
diff --git a/rgmanager/init.d/rgmanager.in b/rgmanager/init.d/rgmanager.in
deleted file mode 100644
index 931df37..0000000
--- a/rgmanager/init.d/rgmanager.in
+++ /dev/null
@@ -1,162 +0,0 @@
-#!/bin/bash
-#
-# chkconfig: - 99 01
-# description: Starts and stops Red Hat Service (resource group) Manager
-#
-#
-### BEGIN INIT INFO
-# Provides: rgmanager
-# Required-Start: cman cpglockd
-# Required-Stop: cman cpglockd
-# Default-Start:
-# Default-Stop:
-# Short-Description: Starts and stops Red Hat Service (resource group) Manager
-# Description: Starts and stops Red Hat Service (resource group) Manager
-### END INIT INFO
-
-ID="Cluster Service Manager"
-RGMGRD="rgmanager"
-
-# set secure PATH
-PATH="/sbin:/bin:/usr/sbin:/usr/bin:@SBINDIR@"
-
-success()
-{
- echo -ne "[ OK ]\r"
-}
-
-failure()
-{
- echo -ne "[FAILED]\r"
-}
-
-status()
-{
- pid=$(pidof $1 2>/dev/null)
- statusrtrn=$?
- if [ $statusrtrn -ne 0 ]; then
- echo "$1 is stopped"
- else
- echo "$1 (pid $pid) is running..."
- fi
- return $statusrtrn
-}
-
-# rpm based distros
-if [ -d /etc/sysconfig ]; then
- [ -f @INITDDIR@/functions ] && . @INITDDIR@/functions
- [ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster
- [ -f /etc/sysconfig/rgmanager ] && . /etc/sysconfig/rgmanager
- [ -z "$LOCK_FILE" ] && LOCK_FILE="/var/lock/subsys/rgmanager"
-fi
-
-# deb based distros
-if [ -d /etc/default ]; then
- [ -f /etc/default/cluster ] && . /etc/default/cluster
- [ -f /etc/default/rgmanager ] && . /etc/default/rgmanager
- [ -z "$LOCK_FILE" ] && LOCK_FILE="/var/lock/rgmanager"
-fi
-
-#
-# Bring down the cluster on a node.
-#
-stop_cluster()
-{
- kill -TERM $(pidof $RGMGRD)
-
- # this unbreakable loop is meant to be done this way.
- # there are resources that can take up to several minutes
- # to stop and there is no "right timeout".
- while status $RGMGRD > /dev/null 2>&1; do
- sleep 1
- done
-}
-
-#
-# start cpglock if necessary
-#
-start_cpglockd()
-{
- rings="$(corosync-objctl 2>/dev/null |grep ringnumber | wc -l)"
- [ "$rings" -gt "1" ] && service cpglockd start && \
- while ! cpglockdump > /dev/null 2>&1; do sleep 1; done
-}
-
-rtrn=0
-
-if [ "$EUID" != "0" ]; then
- echo "Only root can execute $0 script"
- exit 4
-fi
-
-case "$1" in
-start)
- echo -n "Starting $ID: "
-
- # most recent distributions use tmpfs for /var/run
- # to avoid to clean it up on every boot.
- # they also assume that init scripts will create
- # required subdirectories for proper operations
- mkdir -p /var/run/cluster
-
- # failure to start cpglockd should not be fatal here
- # rgmanager will take care to report the correct errors
- # later
- start_cpglockd || true
-
- if status $RGMGRD > /dev/null 2>&1; then
- success
- else
- if $RGMGRD $RGMGR_OPTS; then
- touch $LOCK_FILE
- success
- else
- failure
- rtrn=1
- fi
- fi
- echo
-;;
-restart)
- $0 stop
- $0 start
-;;
-condrestart|try-restart)
- if status $RGMGRD > /dev/null 2>&1; then
- $0 stop
- $0 start
- rtrn=$?
- fi
-;;
-reload|force-reload)
- # not required anymore
- # return not implemented
- rtrn=3
-;;
-status)
- status $RGMGRD
- rtrn=$?
-;;
-stop)
- echo -n "Stopping $ID: "
-
- if status $RGMGRD > /dev/null 2>&1; then
- if stop_cluster; then
- success
- else
- failure
- rtrn=1
- fi
- else
- success
- fi
- echo
- rm -f $LOCK_FILE
-;;
-*)
- echo "usage: $0 {start|stop|restart|condrestart|try-restart|reload|force-reload|status}"
- rtrn=2
-;;
-esac
-
-exit $rtrn
diff --git a/rgmanager/man/Makefile b/rgmanager/man/Makefile
deleted file mode 100644
index 4d6a1dd..0000000
--- a/rgmanager/man/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-MANTARGET= \
- clubufflush.8 \
- clufindhostname.8 \
- clulog.8 \
- rgmanager.8 \
- clurgmgrd.8 \
- clustat.8 \
- clusvcadm.8 \
- cpglockd.8
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-all:
-
-clean:
-
-check:
diff --git a/rgmanager/man/clubufflush.8 b/rgmanager/man/clubufflush.8
deleted file mode 100644
index 848d01e..0000000
--- a/rgmanager/man/clubufflush.8
+++ /dev/null
@@ -1,13 +0,0 @@
-.TH "clubufflush" "8" "Jan 2005" "" "Red Hat Cluster Suite Internal Commands"
-.SH "NAME"
-clubufflush \- Flush buffers on a service's file system.
-
-.SH "DESCRIPTION"
-.PP
-The
-.B clubufflush
-command is an internal command used to synchronize buffers to disk
-prior to stopping a clustered service.
-
-.SH "SEE ALSO"
-sync(1), sync(2), fsync(2), fdatasync(2)
diff --git a/rgmanager/man/clufindhostname.8 b/rgmanager/man/clufindhostname.8
deleted file mode 100644
index 7035cd5..0000000
--- a/rgmanager/man/clufindhostname.8
+++ /dev/null
@@ -1,22 +0,0 @@
-.TH "clufindhostname" "8" "Jan 2005" "" "Red Hat Cluster Suite Internal Commands"
-.SH "NAME"
-clufindhostname \- Find a hostname or IP address given the other.
-.SH "SYNOPSIS"
-.B clufindhostname
-.B [\-i <ip_address>]
-.B [\-n <hostname>]
-
-.SH "DESCRIPTION"
-.PP
-The
-.B clufindhostname
-command is a wrapper around gethostbyname(3) and gethostbyaddr(3).
-
-.SH "OPTIONS"
-.IP "\-i <ip_address>"
-Call gethostbyaddr(3) on specified IP address.
-.IP "\-n <hostname>"
-Call gethostbyname(3) on specified hostname.
-
-.SH "SEE ALSO"
-host(1), gethostbyname(3), gethostbyaddr(3)
diff --git a/rgmanager/man/clulog.8 b/rgmanager/man/clulog.8
deleted file mode 100644
index 9f0cf12..0000000
--- a/rgmanager/man/clulog.8
+++ /dev/null
@@ -1,27 +0,0 @@
-.TH "clulog" "8" "Jul 2010" "" "Red Hat Cluster Suite Internal Commands"
-.SH "NAME"
-clulog \- Log a message to the cluster and/or system logs
-.SH "SYNOPSIS"
-.B clulog
-.B \-s
-.I severity
-.B [\-m
-.I program_name
-.B ]
-.B message
-.SH "DESCRIPTION"
-.PP
-The
-.B clulog
-command sends a message to syslogd(8).
-.SH "OPTIONS"
-.IP "\-s <severity>"
-Log at the specified severity (0-7; 0=ALERT, 7=DEBUG).
-.IP "\-l <priority_filter>"
-Apply the specified filter (0-7) for the message. By default,
-.B clulog
-uses the rgmanager's assigned log level.
-.IP "\-m <program_name>"
-Add the specified program name to the log message
-.SH "SEE ALSO"
-syslog(2), syslogd(8)
diff --git a/rgmanager/man/clurgmgrd.8 b/rgmanager/man/clurgmgrd.8
deleted file mode 100644
index 7541418..0000000
--- a/rgmanager/man/clurgmgrd.8
+++ /dev/null
@@ -1 +0,0 @@
-.so man8/rgmanager.8
diff --git a/rgmanager/man/clustat.8 b/rgmanager/man/clustat.8
deleted file mode 100644
index ca84a84..0000000
--- a/rgmanager/man/clustat.8
+++ /dev/null
@@ -1,53 +0,0 @@
-.TH "clustat" "8" "Jan 2005" "" "Red Hat Cluster Suite"
-.SH "NAME"
-clustat \- Cluster Status Utility
-.SH "SYNOPSIS"
-.B clustat
-.B [\-i
-.I delay
-.B ]
-.B [\-I]
-.B [\-m
-.I member
-.B ]
-.B [\-Q]
-.B [\-s
-.I service
-.B ]
-.B [\-v]
-.B [\-x]
-
-.SH "DESCRIPTION"
-.PP
-The
-.B clustat
-command displays the status of the cluster. It shows membership information,
-quorum view, and the state of all configured user services. The
-.B clustat
-command displays cluster status only from the viewpoint of the cluster system
-on which it is running.
-.SH "OPTIONS"
-.IP "\-I"
-Display the member ID of the current member.
-.IP "\-i <delay>"
-Display cluster status and refresh the status every
-.I delay
-seconds. Mutually exclusive with the
-.B "\-x"
-option.
-.B "\-m <member>"
-Display the status of the specified member.
-.IP "\-Q"
-Return cluster quorum status to calling shell. (No output)
-.IP "\-s <service>"
-Displays the status of the specified service.
-.IP "\-x"
-Display cluster configuration combined with status in XML format. Mutually
-exclusive with
-.B "\-i"
-option.
-.IP \-v
-Display version information and exit.
-
-.SH "SEE ALSO"
-clusvcadm(8)
diff --git a/rgmanager/man/clusvcadm.8 b/rgmanager/man/clusvcadm.8
deleted file mode 100644
index 055a0bf..0000000
--- a/rgmanager/man/clusvcadm.8
+++ /dev/null
@@ -1,147 +0,0 @@
-.TH "clusvcadm" "8" "Jan 2005" "" "Red Hat Cluster Suite"
-.SH "NAME"
-clusvcadm \- Cluster User Service Administration Utility
-.SH "SYNOPSIS"
-.B clusvcadm
-.B [\-d
-.I <service>
-.B ]
-.B [\-e
-.I <service>
-.B [\-F] ]
-.B [\-l]
-.B [\-u]
-.B [\-S]
-.B [\-m
-.I <member>
-.B ]
-.B [\-r
-.I <service>
-.B ]
-.B [\-R
-.I <service>
-.B ]
-.B [\-M
-.I <service>
-.B ]
-.B [\-Z
-.I <service>
-.B ]
-.B [\-U
-.I <service>
-.B ]
-.B [\-s
-.I <service>
-.B ]
-.B [\-c
-.I <service>
-.B ]
-.B [\-v]
-
-.SH "DESCRIPTION"
-.PP
-The
-.B clusvcadm
-command allows an administrator to enable, disable, relocate, and restart
-user services in a cluster. In order to perform cluster service operations,
-the cluster daemons must be running (and have quorum) on the member system
-on which the command is invoked.
-
-.SH "OPTIONS"
-.IP "\-d <service>"
-Stops and disables the user service named
-.I
-service
-.IP "\-e <service> [\-F]"
-Enables and starts the user service named
-.I
-service
-
-Normally, rgmanager starts the service locally (i.e. on
-the host where clusvcadm was run). However, if the \fB-F\fP
-option is specified, rgmanager will use the assigned failover
-domain rules as hints on where to start the service.
-.IP \-l
-Lock services in preparation for cluster shutdown. This should only
-be used if the administrator intends to perform a global, cluster
-wide shutdown. This prevents services from starting (but not stopping,
-like
-.B -Z
-does). Once the cluster quorum is dissolved, this state is reset.
-If a new instance of rgmanager boots while others are locked, the
-behavior is undefined.
-.IP \-u
-Unlock resource group managers. This allows services to start again.
-.IP "\-S"
-Display whether the resource group managers are locked or not. This
-can be used to verify the correct operation of the \fB-l\fR and \fB-u\fR
-options, but is only useful for debugging.
-.IP "\-m <member>"
-When used in conjunction with either the
-.B
-\-e
-or
-.B
-\-r
-options, this specifies the
-.I
-preferred
-target member on which to start the
-service.
-.IP "\-r <service>"
-Relocates the user service named
-.I
-service
-to another cluster member.
-.IP "\-R <service>"
-Restarts the user service named
-.I
-service
-on the cluster member on which it is currently running.
-.IP "\-M <service>"
-Use a special "migration" operation to move the user service named
-.I
-service
-to another cluster member. Currently, this is only useful for
-virtual machines. Use of migration usually requires special
-configuration of the local virtual machine manager in order
-to work correctly.
-.IP "\-Z <service>"
-Freezes the service named
-.I
-service
-on the cluster member on which it is currently running. This will
-prevent status checks of the service as well as failover in the
-event the node fails or rgmanager is stopped.
-.IP "\-U <service>"
-Unfreezes the user service named
-.I
-service
-on the cluster member on which it is currently running. This will
-re-enable status checks.
-.IP "\-s <service>"
-Stops the service named
-.I
-service
-until a member transition or until it is enabled again.
-
-.IP "\-c <service>"
-Attempt to convalesce the named
-.I
-service
-by restarting failed, non-critical components.
-
-.IP \-v
-Display version information and exit.
-
-.SH "NOTES"
-Executing
-.I -U
-(unfreeze) on a service which was frozen in the
-.B started
-state while the service owner is offline results in an undefined
-(and possibly dangerous) condition. Manually ensure all resources are
-clear before doing this.
-
-.SH "SEE ALSO"
-clustat(8)
diff --git a/rgmanager/man/cpglockd.8 b/rgmanager/man/cpglockd.8
deleted file mode 100644
index 8084d96..0000000
--- a/rgmanager/man/cpglockd.8
+++ /dev/null
@@ -1,21 +0,0 @@
-.TH "cpglockd" "8" "May 2012" "" "Red Hat High Availability"
-.SH "NAME"
-cpglockd \- CPG lock server for rgmanager
-.SH "DESCRIPTION"
-.PP
-.B cpglockd
-utilizes the extended virtual synchrony features of the Corosync
-Cluster Engine to implement a simplistic, distributed lock server
-for rgmanager.
-.SH "COMMAND LINE OPTIONS"
-.IP \-F
-Don't wait for the current node to join the fencing domain at startup
-.IP \-Q
-Don't wait for quorum formation at startup
-.IP \-f
-Operate in the foreground mode; do not daemonize
-.IP \-h
-Print command line usage.
-
-.SH "SEE ALSO"
-rgmanager(8), corosync(8)
diff --git a/rgmanager/man/rgmanager.8 b/rgmanager/man/rgmanager.8
deleted file mode 100644
index bab52ef..0000000
--- a/rgmanager/man/rgmanager.8
+++ /dev/null
@@ -1,392 +0,0 @@
-.TH "rgmanager" "8" "Jul 2010" "" "Red Hat Cluster Suite"
-.SH "NAME"
-rgmanager \- Resource Group (Cluster Service) Manager Daemon
-.SH "DESCRIPTION"
-.PP
-.B rgmanager
-handles management of user-defined cluster services (also known as resource
-groups). This includes handling of user requests including service start,
-service disable, service relocate, and service restart. The service
-manager daemon also handles restarting and relocating services in the
-event of failures.
-.SH "HOW IT WORKS"
-.PP
-The service manager is spawned by an init script after the cluster
-infrastructure has been started and only functions when the cluster
-is quorate and locks are working.
-.LP
-During initialization, the service manager runs scripts which ensure that all
-services are clear to be started. After that, it determines which services
-need to be started and starts them.
-.LP
-When an event is received, members which are no longer online have their
-services taken away from them. The event should only occur in the case that
-the member has been fenced whenever fencing is available.
-.LP
-When a cluster member determines that it is no longer in the cluster quorum,
-the service manager stops all services and waits for a new quorum to form.
-
-.SH "CONFIGURATION"
-.PP
-Rgmanager is configured via cluster.conf. With the exception of logging,
-all of rgmanager's configuration resides with the
-.B <rm>
-tag. The general parameters for rgmanager are as follows:
-.LP
-.B central_processing
-- Enable central processing mode (requires cluster-wide shut down and
-restart of rgmanager). This alternative mode of handling failures
-externalizes most of rgmanager's features into a user-editable script.
-This mode is disabled by default.
-.LP
-.B status_poll_interval
-- This defines the amount of time, in seconds, rgmanager waits
-between resource tree scans for status checks. Decreasing this value
-may improve rgmanager's ability to detect failures in services, but
-at a cost of decreased performance and increased system utilization.
-The default is 10 seconds.
-.LP
-.B status_child_max
-- Maximum number of status check threads (default = 5). It is not
-recommended that this ever be changed. This simply controls how
-many instances of clustat queries may be outstanding on a single
-node at any given time.
-.LP
-.B transition_throttling
-- This is the amount of time the event processing thread stays alive
-after the last event has been processed. The default is 5 seconds.
-It is not recommended that this ever be changed.
-.LP
-.B log_level
-- DEPRECATED; DO NOT USE. Controls log level filtering to syslog.
-Default is 5; valid values range from 0-7. See cluster.conf(5)
-for the current method to configure logging.
-.LP
-.B log_facility
-- DEPRECATED; DO NOT USE. Controls log level facility when sending
-messages to syslog. Default is "daemon". See cluster.conf(5)
-for the current method to configure logging.
-
-.SH "RESOURCE AGENTS"
-.PP
-.B Resource agents
-define resource classes rgmanager can manage. Rgmanager follows the Open
-Cluster Framework Resource Agent API v1.0 (draft) standard, with the following
-two notable exceptions:
-.LP
-.in 8
-* Rgmanager does not call \fImonitor\fP; it only calls \fIstatus\fP
-.in
-.in 8
-* Rgmanager looks for resource agets in /usr/share/cluster
-.in
-.LP
-Rgmanager uses the metadata from resource agents to determine what
-parameters to look for in cluster.conf for a each resource type. Viewing
-the resource agent metadata is the best way to understand all the various
-resource agent parameters.
-
-.SH "SERVICES / RESOURCE GROUPS"
-.PP
-A
-.B service
-or
-.B resource group
-is a collection of resources defined in cluster.conf for rgmanager's
-use. Resource groups are also called
-.B resource trees.
-.LP
-A resource group is the atomic unit of failover in rgmanager. That
-is, even though rgmanager calls out to various resource agents
-individually in order to start or stop various resources, everything
-in the resource group is always moved around together
-in the event of a relocation or failover.
-
-.SH "STARTUP POLICIES"
-.PP
-Rgmanager supports only two startup policies,
-.LP
-.B autostart
-- if set to 1 (the default), the service is started when a quorum
-forms. If set to 0, the service is not automatically started.
-.LP
-Startup Policy Configuration:
-Recovery Configuration:
-.in 8
-<rm>
-.in 10
-<service name="service1" autostart="[0|1]" .../>
-.in 8
-.in 10
- ...
-.in 8
-</rm>
-
-.SH "RECOVERY POLICIES"
-.PP
-Rgmanager supports three recovery policies for services; this is
-configured by the
-.B
-recovery
-parameter in the service definition.
-.LP
-.B restart
-- means to attempt to restart the resource group in place in the
-event of one or more failures of individual resources. This can
-further be augmented by the
-.B max_restarts
-and
-.B restart_expire_time
-parameters, which define a tolerance for the amount of service
-restarts over the given amount of time.
-.LP
-.B relocate
-- means to move the resource group to another host in the cluster
-instead of restarting on the same host.
-.LP
-.B disable
-- means to not try to recover the resource group. Instead, just
-place it in to the disabled state.
-.LP
-Recovery Configuration:
-.in 8
-<rm>
-.in 10
-<service name="service1" recovery="[restart|relocate|disable]" .../>
-.in 8
-.in 10
- ...
-.in 8
-</rm>
-
-.SH "FAILOVER DOMAINS"
-.PP
-A failover domain is an ordered subset of members to which a
-service may be bound. The following is a list of semantics
-governing the options as to how the different configuration
-options affect the behavior of a failover domain:
-.LP
-.B preferred node
-or
-.B preferred member
-: The preferred node was the member designated to run a given
-service if the member is online. We can emulate this behavior
-by specifying an unordered, unrestricted failover domain of
-exactly one member.
-.LP
-.B restricted domain
-: Services bound to the domain may only run on cluster members
-which are also members of the failover domain. If no members
-of the failover domain are available, the service is placed
-in the stopped state.
-.LP
-.B unrestricted domain
-: Services bound to this domain may run on all cluster members,
-but will run on a member of the domain whenever one is
-available. This means that if a service is running outside of
-the domain and a member of the domain comes online, the
-service will migrate to that member.
-.LP
-.B ordered domain
-: The order specified in the configuration dictates the order
-of preference of members within the domain. The
-highest-ranking member of the domain will run the service
-whenever it is online. This means that if member A has a
-higher rank than member B, the service will migrate to A if it
-was running on B if A transitions from offline to online.
-.LP
-.B unordered domain
-: Members of the domain have no order of preference; any
-member may run the service. Services will always migrate to
-members of their failover domain whenever possible, however,
-in an unordered domain.
-.LP
-.B nofailback
-: Enabling this option for an ordered failover domain will
-prevent automated fail-back after a more-preferred node
-rejoins the cluster. Consequently, nofailback requires an
-ordered domain in order to be meaningful. When nofailback
-is used, the following two behaviors should be noted:
-.in 8
-* If a subset of cluster nodes forms a quorum, the node
-with the highest priority in the failover domain is selected
-to run a service bound to the domain. After this point, a
-higher priority member joining the cluster will not trigger a
-relocation.
-.in
-.in 8
-* When a service is running outside of its unrestricted
-failover domain and a cluster member boots which is a part
-of the service's failover domain, the service will relocate
-to that member. That is, nofailback does not prevent
-transitions from outside of a failover domain to inside a
-failover domain. After this point, a higher priority member
-joining the cluster will not trigger a relocation.
-.in
-.LP
-Ordering, restriction, and nofailback are flags and may
-be combined in almost any way (ie, ordered+restricted,
-unordered+unrestricted, etc.). These combinations affect both
-where services start after initial quorum formation and which
-cluster members will take over services in the event that
-the service has failed.
-.LP
-Failover Domain Configuration:
-.in 8
-<rm>
-.in 10
-<failoverdomains>
-.in 12
-<failoverdomain name="NAME" ordered="[0|1]" restricted="[0|1]" nofailback="[0|1" >
-.in 14
-<failoverdomainnode name="node1" priority="[1..100]" />
-.in 12
-.in 14
- ...
-.in 12
-</failoverdomain>
-.in 10
-</failoverdomains>
-.in 8
-.in 10
- ...
-.in 8
-</rm>
-
-.SH "SERVICE OPERATIONS"
-.PP
-These are how the basic user-initiated service operations
-(via
-.B clusvcadm
-) work.
-.LP
-.B enable
-- start the service, optionally on a preferred target and
-optionally according to failover domain rules. In absence
-of either, the local host where clusvcadm is run will start
-the service. If the original start fails, the service behaves
-as though a relocate operation was requested (see below). If
-the operation succeeds, the service is placed in the started state.
-.LP
-.B disable
-- stop the service and place into the disabled state. This
-is the only permissible operation when a service is in the failed state.
-.LP
-.B relocate
-- move the service to another node. Optionally, the
-administrator may specify a preferred node to receive the
-service, but the inability for the service to run on that
-host (e.g. if the service fails to start or the host is offline)
-does not prevent relocation, and another node is chosen.
-Rgmanager attempts to start the service on every permissible node
-in the cluster. If no permissible target node in the cluster
-successfully starts the service, the relocation fails and the
-service is attempted to be restarted on the original owner.
-If the original owner can not restart the service, the service is
-placed in the stopped state.
-.LP
-.B stop
-- stop the service and place into the stopped state.
-.LP
-.B migrate
-- migrate the virtual machine to another node. The administrator
-must specify a target node. Depending on the failure, a failure
-to migrate may result with the virtual machine in the failed state
-or in the started state on the original owner.
-.LP
-.B freeze
-- freeze the service or virtual machine in place and prevent
-status checks from occurring. Administrators may do this in order
-to perform maintenance on one or more parts of a given service
-without having rgmanager interfere. It is very important that
-the administrator unfreezes the service once maintenance is
-complete, as a frozen service will not fail over. Freezing
-a service does NOT affect is operational state. For example,
-it does not 'pause' virtual machines or suspend them to disk.
-.LP
-.B unfreeze
-- unfreeze (thaw) the service or virtual machine. This command
-makes rgmanager perform status checks on the service again.
-
-.SH "SERVICE STATES"
-.PP
-These are the most common service states.
-.LP
-.B disabled
-- The service will remain in the disabled state until either an
-administrator re-enables the service or the cluster loses quorum
-(when the cluster regains quorum, the autostart parameter is
-evaluated). An administrator may enable the service from this state.
-.LP
-.B failed
-- The service is presumed dead. A service is placed in to this
-state whenever a resource's stop operation fails. After a service
-is placed in to this state, the administrator must verify that there
-are no allocated resources (mounted file systems, etc.) prior to
-issuing a disable request. The only operation which can take place
-when a service has entered this state is a disable.
-.LP
-.B stopped
-- When in the stopped state, the service will be evaluated for
-starting after the next service or node transition. This is considered
-a temporary state. An administrator may disable or enable the service
-from this state.
-.LP
-.B recovering
-- The cluster is trying to recover the service. An administrator may
-disable the service to prevent recovery if desired.
-.LP
-.B started
-- If a service status check fails, recover it according to the service
-recovery policy. If the host running the service fails, recover it
-following failover domain & exclusive service rules. An
-administrator may relocate, stop, disable, and (with virtual
-machines) migrate the service from this state.
-
-.SH "VIRTUAL MACHINE FEATURES"
-.PP
-Apart from what is noted in the VM resource agent, rgmanager
-provides a few convenience features when dealing with virtual machines.
-.in 8
-* it will use live migration when transferring a virtual machine
-to a more-preferred host in the cluster as a consequence of
-failover domain operation
-.in
-.in 8
-* it will search the other instances of rgmanager in the cluster
-in the case that a user accidentally moves a virtual machine
-using other management tools
-.in
-.in 8
-* unlike services, adding a virtual machine to rgmanager's
-configuration will not cause the virtual machine to be restarted
-.in
-.in 8
-* removing a virtual machine from rgmanager's configuration
-will leave the virtual machine running.
-.in
-
-.SH "COMMAND LINE OPTIONS"
-.IP \-f
-Run in the foreground (do not fork).
-.IP \-d
-Enable debug-level logging.
-.IP \-q
-Disable DBus signals which are normally sent when services change state.
-.IP \-w
-Disable internal process monitoring (for debugging).
-.IP \-N
-Do not perform stop-before-start. Combined with the
-.I -Z
-flag to clusvcadm, this can be used to allow rgmanager to be upgraded
-without stopping a given user service or set of services.
-.IP \-C [0|1]
-Explicitly disable or enable CPG-based locking. The default is to
-enable this when RRP is turned on (which requires a cluster outage).
-This option MUST be the same on all hosts in the cluster and must
-only be enabled or disabled with all instances of rgmanager turned off.
-
-.SH "SEE ALSO"
-http://sources.redhat.com/cluster/wiki/RGManager
-
-clusvcadm(8), cluster.conf(5), cpglockd(8)
diff --git a/rgmanager/src/Makefile b/rgmanager/src/Makefile
deleted file mode 100644
index c79d053..0000000
--- a/rgmanager/src/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS=resources clulib daemons utils
diff --git a/rgmanager/src/clulib/Makefile b/rgmanager/src/clulib/Makefile
deleted file mode 100644
index f14acd9..0000000
--- a/rgmanager/src/clulib/Makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-TARGET1= libclulib.a
-TARGET2= msgtest
-
-all: ${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
-
-OBJS1= logging.o daemon_init.o signals.o msgsimple.o \
- gettid.o rg_strings.o message.o members.o fdops.o \
- lock.o cman.o vft.o msg_cluster.o msg_socket.o \
- wrap_lock.o sets.o sock.o libcpglock.o dlm_lock.o cpg_lock.o
-
-OBJS2= msgtest.o
-
-CFLAGS += -fPIC -D_GNU_SOURCE
-CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${dlmincdir}
-CFLAGS += -I${logtincdir}
-CFLAGS += -I$(S)/../../include
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${cmanlibdir} -lcman
-LDFLAGS += -L. -lclulib
-LDFLAGS += -lpthread
-LDFLAGS += -L${logtlibdir} -llogthread
-LDFLAGS += -L${libdir}
-
-${TARGET1}: ${OBJS1}
- ${AR} cru $@ $^
- ${RANLIB} $@
-
-${TARGET2}: ${OBJS2} ${TARGET1}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-clean: generalclean
-
--include $(OBJS1:.o=.Tpo)
--include $(OBJS2:.o=.Tpo)
diff --git a/rgmanager/src/clulib/ckpt_state.c b/rgmanager/src/clulib/ckpt_state.c
deleted file mode 100644
index 766097b..0000000
--- a/rgmanager/src/clulib/ckpt_state.c
+++ /dev/null
@@ -1,536 +0,0 @@
-//#define DEBUG
-/** @file
- * Distributed states using saCkpt interface
- */
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/resource.h>
-#include <sys/wait.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <pthread.h>
-#include <saAis.h>
-#include <saCkpt.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <assert.h>
-#include <ds.h>
-
-typedef struct _key_node {
- struct _key_node *kn_next;
- char *kn_keyid;
- SaTimeT kn_timeout;
- uint16_t kn_ready;
- SaNameT kn_cpname;
- SaCkptCheckpointHandleT kn_cph;
-} key_node_t;
-
-
-static key_node_t *key_list = NULL;
-static SaCkptHandleT ds_ckpt;
-static int ds_ready = 0;
-static pthread_mutex_t ds_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-
-int ais_to_posix(SaAisErrorT err);
-
-
-static key_node_t *
-kn_find_key(char *keyid)
-{
- key_node_t *cur;
-
- for (cur = key_list; cur; cur = cur->kn_next)
- if (!strcmp(cur->kn_keyid,keyid))
- return cur;
-
- return NULL;
-}
-
-
-/**
- * Adds a key to key node list and sets up callback functions.
- */
-static SaAisErrorT
-ds_key_init_nt(char *keyid, int maxsize, int timeout)
-{
- SaCkptCheckpointCreationAttributesT attrs;
- SaCkptCheckpointOpenFlagsT flags;
-#if 0
- SaCkptCheckpointDescriptorT status;
-#endif
- SaAisErrorT err = SA_AIS_OK;
- key_node_t *newnode = NULL;
-
- newnode = kn_find_key(keyid);
- if (newnode) {
- printf("Key %s already initialized\n", keyid);
- return SA_AIS_OK;
- }
-
- newnode = malloc(sizeof(*newnode));
- // FIXME: detect failed malloc
- memset(newnode,0,sizeof(*newnode));
- snprintf((char *)newnode->kn_cpname.value, SA_MAX_NAME_LENGTH-1,
- "%s", keyid);
- newnode->kn_cpname.length = strlen(keyid);
- newnode->kn_keyid = (char *)newnode->kn_cpname.value;
- newnode->kn_ready = 0;
-
- if (timeout < 5) {
- /* Join View message timeout must exceed the
- coordinator timeout */
- timeout = 5;
- }
- newnode->kn_timeout = timeout * SA_TIME_ONE_SECOND;
-
- flags = SA_CKPT_CHECKPOINT_READ |
- SA_CKPT_CHECKPOINT_WRITE;
-
- err = saCkptCheckpointOpen(ds_ckpt,
- &newnode->kn_cpname,
- NULL,
- flags,
- newnode->kn_timeout,
- &newnode->kn_cph);
-
- if (err == SA_AIS_OK) {
-#if 0
- saCkptCheckpointStatusGet(newnode->kn_cph,
- &status);
-
- printf("Checkpoint Size = %d bytes\n", (int)
- status.checkpointCreationAttributes.checkpointSize);
- printf("Flags = ");
- if (status.checkpointCreationAttributes.creationFlags &
- SA_CKPT_WR_ALL_REPLICAS) {
- printf("%s ", "SA_CKPT_WR_ALL_REPLICAS");
- }
- if (status.checkpointCreationAttributes.creationFlags &
- SA_CKPT_WR_ACTIVE_REPLICA) {
- printf("%s ", "SA_CKPT_WR_ACTIVE_REPLICA");
- }
- if (status.checkpointCreationAttributes.creationFlags &
- SA_CKPT_WR_ACTIVE_REPLICA_WEAK) {
- printf("%s ", "SA_CKPT_WR_ACTIVE_REPLICA_WEAK");
- }
- if (status.checkpointCreationAttributes.creationFlags &
- SA_CKPT_CHECKPOINT_COLLOCATED) {
- printf("%s ", "SA_CKPT_CHECKPOINT_COLLOCATED");
- }
- printf("\nMax sections = %d\n",
- (int)status.checkpointCreationAttributes.maxSections);
- printf("Max section size = %d\n",
- (int)status.checkpointCreationAttributes.maxSectionSize);
- printf("Max section ID size = %d\n",
- (int)status.checkpointCreationAttributes.maxSectionIdSize);
- printf("Section count = %d\n", status.numberOfSections);
- printf("\n");
-#endif
- goto good;
- }
-
- attrs.creationFlags = SA_CKPT_WR_ALL_REPLICAS;
- attrs.checkpointSize = (SaSizeT)maxsize;
- attrs.retentionDuration = SA_TIME_ONE_HOUR;
- attrs.maxSections = 1;
- attrs.maxSectionSize = (SaSizeT)maxsize;
- attrs.maxSectionIdSize = (SaSizeT)32;
-
- flags = SA_CKPT_CHECKPOINT_READ |
- SA_CKPT_CHECKPOINT_WRITE |
- SA_CKPT_CHECKPOINT_CREATE;
-
- err = saCkptCheckpointOpen(ds_ckpt,
- &newnode->kn_cpname,
- &attrs,
- flags,
- newnode->kn_timeout,
- &newnode->kn_cph);
- if (err == SA_AIS_OK)
- goto good;
-
- /* No checkpoint */
- free(newnode);
- return err;
-good:
-
- newnode->kn_ready = 1;
- newnode->kn_next = key_list;
- key_list = newnode;
-#if 0
- printf("Opened ckpt %s\n", keyid);
-#endif
-
- return err;
-}
-
-
-int
-ds_key_init(char *keyid, int maxsize, int timeout)
-{
- SaAisErrorT err;
-
- pthread_mutex_lock(&ds_mutex);
- err = ds_key_init_nt(keyid, maxsize, timeout);
- pthread_mutex_unlock(&ds_mutex);
-
- errno = ais_to_posix(err);
- if (errno)
- return -1;
- return 0;
-}
-
-
-static SaAisErrorT
-ds_key_cleanup(key_node_t *node)
-{
- if (!node || !node->kn_ready) {
- printf("Key %s already freed\n", node->kn_keyid);
- return SA_AIS_OK;
- }
-
- return saCkptCheckpointClose(node->kn_cph);
-}
-
-
-
-static SaAisErrorT
-ds_key_finish_nt(char *keyid)
-{
- key_node_t *node;
-
- node = kn_find_key(keyid);
- /* TODO: Free list entry */
-
- return ds_key_cleanup(node);
-}
-
-
-int
-ds_key_finish(char *keyid)
-{
- SaAisErrorT err;
-
- pthread_mutex_lock(&ds_mutex);
- err = ds_key_finish_nt(keyid);
- pthread_mutex_unlock(&ds_mutex);
-
- errno = ais_to_posix(err);
- if (errno)
- return -1;
- return 0;
-}
-
-
-
-static void
-open_callback(SaInvocationT invocation,
- SaCkptCheckpointHandleT handle,
- SaAisErrorT error)
-{
- /* Do Open callback here. Since we use sync calls instead
- of async calls, this is never used. */
-}
-
-
-static void
-sync_callback(SaInvocationT invocation,
- SaAisErrorT error)
-{
- /* Do Sync callback here. Since we use sync calls instead
- of async calls, this is never used. */
-}
-
-
-int
-ais_to_posix(SaAisErrorT err)
-{
- switch (err) {
- case SA_AIS_OK:
- return 0;
- case SA_AIS_ERR_LIBRARY:
- return ELIBBAD;
- case SA_AIS_ERR_VERSION:
- return EPROTONOSUPPORT; //XXX
- case SA_AIS_ERR_INIT:
- return EFAULT; //XXX
- case SA_AIS_ERR_TIMEOUT:
- return ETIMEDOUT;
- case SA_AIS_ERR_TRY_AGAIN:
- return EAGAIN;
- case SA_AIS_ERR_INVALID_PARAM:
- return EINVAL;
- case SA_AIS_ERR_NO_MEMORY:
- return ENOMEM;
- case SA_AIS_ERR_BAD_HANDLE:
- return EBADF;
- case SA_AIS_ERR_BUSY:
- return EBUSY;
- case SA_AIS_ERR_ACCESS:
- return EACCES;
- case SA_AIS_ERR_NOT_EXIST:
- return ENOENT;
- case SA_AIS_ERR_NAME_TOO_LONG:
- return ENAMETOOLONG;
- case SA_AIS_ERR_EXIST:
- return EEXIST;
- case SA_AIS_ERR_NO_SPACE:
- return ENOSPC;
- case SA_AIS_ERR_INTERRUPT:
- return EINTR;
- case SA_AIS_ERR_NAME_NOT_FOUND:
- return ENOENT;
- case SA_AIS_ERR_NO_RESOURCES:
- return ENOMEM; //XXX
- case SA_AIS_ERR_NOT_SUPPORTED:
- return ENOSYS;
- case SA_AIS_ERR_BAD_OPERATION:
- return EINVAL; //XXX
- case SA_AIS_ERR_FAILED_OPERATION:
- return EIO; //XXX
- case SA_AIS_ERR_MESSAGE_ERROR:
- return EIO; // XXX
- case SA_AIS_ERR_QUEUE_FULL:
- return ENOBUFS;
- case SA_AIS_ERR_QUEUE_NOT_AVAILABLE:
- return ENOENT;
- case SA_AIS_ERR_BAD_FLAGS:
- return EINVAL;
- case SA_AIS_ERR_TOO_BIG:
- return E2BIG;
- case SA_AIS_ERR_NO_SECTIONS:
- return ENOENT; // XXX
- }
-
- return -1;
-}
-
-
-int
-ds_init(void)
-{
- int ret = 0;
- SaAisErrorT err;
- SaVersionT ver;
- SaCkptCallbacksT callbacks;
-
- pthread_mutex_lock(&ds_mutex);
- if (ds_ready) {
- pthread_mutex_unlock(&ds_mutex);
- return 0;
- }
-
- ver.releaseCode = 'B';
- ver.majorVersion = 1;
- ver.minorVersion = 1;
-
- callbacks.saCkptCheckpointOpenCallback = open_callback;
- callbacks.saCkptCheckpointSynchronizeCallback = sync_callback;
-
- err = saCkptInitialize(&ds_ckpt, &callbacks, &ver);
-
- if (err != SA_AIS_OK)
- ret = -1;
- else
- ds_ready= 1;
-
- pthread_mutex_unlock(&ds_mutex);
-
- if (ret != 0)
- errno = ais_to_posix(err);
- return ret;
-}
-
-
-int
-ds_write(char *keyid, void *buf, size_t maxlen)
-{
- key_node_t *node;
- SaCkptIOVectorElementT iov = {SA_CKPT_DEFAULT_SECTION_ID,
- NULL, 0, 0, 0};
- SaAisErrorT err;
-
- //printf("writing to ckpt %s\n", keyid);
-
- pthread_mutex_lock(&ds_mutex);
-
- while ((node = kn_find_key(keyid)) == NULL) {
-
- err = ds_key_init_nt(keyid,
- (maxlen>DS_MIN_SIZE?maxlen:DS_MIN_SIZE), 5);
- if (err != SA_AIS_OK)
- goto out;
- }
-
- iov.dataBuffer = buf;
- iov.dataSize = (SaSizeT)maxlen;
- iov.dataOffset = 0;
- iov.readSize = 0;
-
- err = saCkptCheckpointWrite(node->kn_cph, &iov, 1, NULL);
-
- if (err == SA_AIS_OK)
- saCkptCheckpointSynchronize(node->kn_cph, node->kn_timeout);
-
-out:
- pthread_mutex_unlock(&ds_mutex);
-
- errno = ais_to_posix(err);
- if (errno)
- return -1;
- return maxlen; /* XXX */
-}
-
-
-int
-ds_read(char *keyid, void *buf, size_t maxlen)
-{
- key_node_t *node;
- SaCkptIOVectorElementT iov = {SA_CKPT_DEFAULT_SECTION_ID,
- NULL, 0, 0, 0};
- SaAisErrorT err;
-
- //printf("reading ckpt %s\n", keyid);
-
- pthread_mutex_lock(&ds_mutex);
-
- node = kn_find_key(keyid);
- if (!node) {
- pthread_mutex_unlock(&ds_mutex);
- errno = ENOENT;
- return -1;
- }
-
- iov.dataBuffer = buf;
- iov.dataSize = (SaSizeT)maxlen;
- iov.dataOffset = 0;
- iov.readSize = 0;
-
- err = saCkptCheckpointRead(node->kn_cph, &iov, 1, NULL);
-
- pthread_mutex_unlock(&ds_mutex);
-
- errno = ais_to_posix(err);
- if (errno)
- return -1;
- return iov.readSize; /* XXX */
-}
-
-
-int
-ds_finish(void)
-{
- int ret = 0;
- SaAisErrorT err;
- key_node_t *node;
-
- pthread_mutex_lock(&ds_mutex);
- if (!ds_ready) {
- pthread_mutex_unlock(&ds_mutex);
- return 0;
- }
-
- /* Zap all the checkpoints */
- for (node = key_list; node; node = node->kn_next) {
- ds_key_cleanup(node);
- }
-
- err = saCkptFinalize(ds_ckpt);
-
- if (err != SA_AIS_OK)
- ret = -1;
- else
- ds_ready = 0;
-
- pthread_mutex_unlock(&ds_mutex);
-
- if (ret != 0)
- errno = ais_to_posix(err);
- return ret;
-}
-
-
-#ifdef STANDALONE
-void
-usage(int ret)
-{
- printf("usage: ckpt <-r key|-w key -d data>\n");
- exit(ret);
-}
-
-int
-main(int argc, char **argv)
-{
- char *keyid = "testing";
- char *val;
- char buf[DS_MIN_SIZE];
- int ret;
- int op = 0;
-
- while((ret = getopt(argc, argv, "w:r:d:j?")) != EOF) {
- switch(ret) {
- case 'w':
- op = 'w';
- keyid = optarg;
- break;
- case 'r':
- op = 'r';
- keyid = optarg;
- break;
- case 'd':
- val = optarg;
- break;
- case '?':
- case 'h':
- usage(0);
- default:
- usage(1);
- }
- }
-
- if (!op) {
- usage(1);
- }
-
- if (!keyid) {
- usage(1);
- }
-
- if (ds_init() < 0) {
- perror("ds_init");
- return 1;
- }
-
- if (ds_key_init(keyid, DS_MIN_SIZE, 5) < 0) {
- perror("ds_key_init");
- return 1;
- }
-
- if (op == 'w') {
- if (ds_write(keyid, val, strlen(val)+1) < 0) {
- perror("ds_write");
- return 1;
- }
- } else if (op == 'r') {
- ret = ds_read(keyid, buf, sizeof(buf));
- if (ret < 0) {
- perror("ds_write");
- return 1;
- }
-
- printf("%d bytes\nDATA for '%s':\n%s\n", ret, keyid,
- buf);
- }
-
- ds_key_finish(keyid);
-
- if (ds_finish() < 0) {
- perror("ds_finish");
- return 0;
- }
-
- return 0;
-}
-#endif
diff --git a/rgmanager/src/clulib/cman.c b/rgmanager/src/clulib/cman.c
deleted file mode 100644
index 841e43c..0000000
--- a/rgmanager/src/clulib/cman.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/**
- pthread mutex wrapper for a global CMAN handle
- */
-#include <stdio.h>
-#include <pthread.h>
-#include <libcman.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <signal.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-#include <cman-private.h>
-
-static cman_handle_t _chandle = NULL;
-static pthread_mutex_t _chandle_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t _chandle_cond = PTHREAD_COND_INITIALIZER;
-static pthread_t _chandle_holder = 0;
-static int _chandle_preempt = 0;
-static int _wakeup_pipe[2] = { -1, -1 };
-
-static void
-_set_nonblock(int fd)
-{
- int flags;
-
- flags = fcntl(fd, F_GETFL, 0);
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0)
- perror("fcntl");
-}
-
-
-/**
- Lock / return the global CMAN handle.
-
- @param block If nonzero, we wait until the handle is released
- @param preempt If nonzero, *try* to wake up the holder who has
- taken the lock with cman_lock_preemptible. Will not
- wake up holders which took it with cman_lock().
- @return NULL / errno on failure; the global CMAN handle
- on success.
- */
-cman_handle_t
-cman_lock(int block, int preempt)
-{
- int err;
- pthread_t tid;
- cman_handle_t *ret = NULL;
-
- pthread_mutex_lock(&_chandle_lock);
- if (_chandle == NULL) {
- errno = ENOSYS;
- goto out_unlock;
- }
-
- tid = pthread_self();
- if (_chandle_holder == tid) {
- errno = EDEADLK;
- goto out_unlock;
- }
-
- if (_chandle_holder > 0) {
- if (!block) {
- errno = EAGAIN;
- goto out_unlock;
- }
-
- /* Try to wake up the holder! */
- if (preempt)
- err = write(_wakeup_pipe[1], "!", 1); /** XXX we don't care about errors here **/
-
- /* Blocking call; do the cond-thing */
- pthread_cond_wait(&_chandle_cond, &_chandle_lock);
- }
-
- _chandle_holder = tid;
- ret = _chandle;
-out_unlock:
- pthread_mutex_unlock(&_chandle_lock);
- return ret;
-}
-
-
-/**
- Lock / return the global CMAN handle.
-
- @param block If nonzero, we wait until the handle is released
- @param preempt_fd Caller should include this file descriptor in
- blocking calls to select(2), so that we can wake
- it up if someone calls with cman_lock(xxx, 1);
- @return NULL / errno on failure; the global CMAN handle
- on success.
- */
-cman_handle_t
-cman_lock_preemptible(int block, int *preempt_fd)
-{
- pthread_t tid;
- cman_handle_t *ret = NULL;
-
- if (preempt_fd == NULL) {
- errno = EINVAL;
- return NULL;
- }
-
- pthread_mutex_lock(&_chandle_lock);
- if (_chandle == NULL) {
- errno = ENOSYS;
- goto out_unlock;
- }
-
- tid = pthread_self();
- if (_chandle_holder == tid) {
- errno = EDEADLK;
- goto out_unlock;
- }
-
- if (_chandle_holder > 0) {
- if (!block) {
- errno = EAGAIN;
- goto out_unlock;
- }
-
- /* Blocking call; do the cond-thing */
- pthread_cond_wait(&_chandle_cond, &_chandle_lock);
- }
-
- *preempt_fd = _wakeup_pipe[0];
- _chandle_holder = tid;
- _chandle_preempt = 1;
- ret = _chandle;
-out_unlock:
- pthread_mutex_unlock(&_chandle_lock);
- return ret;
-}
-
-
-/**
- Release the global CMAN handle
-
- @param ch Should match the global handle
- @return -1 on failure, 0 on success
- */
-int
-cman_unlock(cman_handle_t ch)
-{
- int err;
- int ret = -1;
- char c;
-
- pthread_mutex_lock(&_chandle_lock);
- if (_chandle == NULL) {
- errno = ENOSYS;
- goto out_unlock;
- }
-
- if (_chandle_holder != pthread_self() || !_chandle_holder) {
- errno = EBUSY;
- goto out_unlock;
- }
-
- if (_chandle != ch) {
- errno = EINVAL;
- goto out_unlock;
- }
-
- /* Empty wakeup pipe if we took it with the preempt flag */
- if (_chandle_preempt)
- err = read(_wakeup_pipe[0], &c, 1); /** XXX we don't care about errors here **/
-
- _chandle_preempt = 0;
- _chandle_holder = 0;
- ret = 0;
-
-out_unlock:
- pthread_mutex_unlock(&_chandle_lock);
- if (ret == 0)
- pthread_cond_broadcast(&_chandle_cond);
- return ret;
-}
-
-
-int
-cman_init_subsys(cman_handle_t ch)
-{
- int ret = -1;
-
- pthread_mutex_lock(&_chandle_lock);
- if (_chandle) {
- errno = EAGAIN;
- goto out_unlock;
- }
-
- if (!ch) {
- errno = EAGAIN;
- goto out_unlock;
- }
-
- if (pipe(_wakeup_pipe) < 0) {
- goto out_unlock;
- }
-
- _set_nonblock(_wakeup_pipe[0]);
- _chandle = ch;
- _chandle_holder = 0;
- ret = 0;
-
-out_unlock:
- pthread_mutex_unlock(&_chandle_lock);
- return ret;
-}
-
-
-int
-cman_cleanup_subsys(void)
-{
- int ret = -1;
-
- pthread_mutex_lock(&_chandle_lock);
- if (!_chandle) {
- errno = EAGAIN;
- goto out_unlock;
- }
-
- if (_chandle_holder > 0) {
- pthread_cond_wait(&_chandle_cond, &_chandle_lock);
- }
-
- ret = 0;
- _chandle = NULL;
- _chandle_holder = 0;
-
- close(_wakeup_pipe[0]);
- close(_wakeup_pipe[1]);
-
-out_unlock:
- pthread_mutex_unlock(&_chandle_lock);
- return ret;
-}
-
-
-int
-cman_send_data_unlocked(void *buf, int len, int flags,
- uint8_t port, int nodeid)
-{
- return cman_send_data(_chandle, buf, len, flags, port, nodeid);
-}
diff --git a/rgmanager/src/clulib/cpg_lock.c b/rgmanager/src/clulib/cpg_lock.c
deleted file mode 100644
index 7c1c8c3..0000000
--- a/rgmanager/src/clulib/cpg_lock.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/** @file
- * Locking.
- */
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <sys/ioctl.h>
-#include <lock.h>
-#include <sys/types.h>
-#include <sys/select.h>
-#include <pthread.h>
-#include <signal.h>
-
-#include <cpglock.h>
-
-/* Default lockspace stuff */
-static cpg_lock_handle_t _cpgh = NULL;
-static pthread_mutex_t _default_lock = PTHREAD_MUTEX_INITIALIZER;
-
-static void
-dlm2cpg(struct dlm_lksb *dlm, struct cpg_lock *cpg)
-{
- memset(cpg, 0, sizeof(*cpg));
- cpg->local_id = dlm->sb_lkid;
- switch(dlm->sb_status) {
- case 0:
- cpg->state = LOCK_HELD;
- break;
- case EINPROG:
- cpg->state = LOCK_PENDING;
- break;
- default:
- cpg->state = LOCK_FREE;
- break;
- }
-}
-
-static void
-cpg2dlm(struct cpg_lock *cpg, struct dlm_lksb *dlm)
-{
- memset(dlm, 0, sizeof(*dlm));
- dlm->sb_lkid = cpg->local_id;
- switch(cpg->state) {
- case LOCK_HELD:
- dlm->sb_status = 0;
- break;
- case LOCK_PENDING:
- default:
- /* XXX LOCK_FREE -> DLM state? */
- dlm->sb_status = EINPROG;
- break;
- }
-}
-
-
-static int
-_cpg_lock(int mode,
- struct dlm_lksb *lksb,
- int options,
- const char *resource)
-{
- int ret = 0;
-
- struct cpg_lock l;
-
- if (options == LKF_NOQUEUE)
- ret = cpg_lock(_cpgh, resource, 1, &l);
- else
- ret = cpg_lock(_cpgh, resource, 0, &l);
-
- if (ret == 0) {
- cpg2dlm(&l, lksb);
- } else {
- if (errno == EPIPE) {
- raise(SIGSEGV);
- }
- }
-
- return ret;
-}
-
-
-static int
-_cpg_unlock(struct dlm_lksb *lksb)
-{
- struct cpg_lock l;
-
- dlm2cpg(lksb, &l);
- return cpg_unlock(_cpgh, &l);
-}
-
-
-static void
-_cpg_lock_finished(const char *name)
-{
- pthread_mutex_lock(&_default_lock);
- cpg_lock_fin(_cpgh);
- pthread_mutex_unlock(&_default_lock);
-}
-
-
-int
-cpg_lock_initialize(void)
-{
- int ret, err, retries = 0;
-
- while (retries < 10) {
- pthread_mutex_lock(&_default_lock);
- if (_cpgh) {
- pthread_mutex_unlock(&_default_lock);
- return 0;
- }
-
- cpg_lock_init(&_cpgh);
- ret = (_cpgh == NULL);
- err = errno;
- pthread_mutex_unlock(&_default_lock);
-
- if (ret == 0)
- break;
- else {
- sleep(1);
- ++retries;
- }
- }
-
- /* Set up function pointers */
- clu_lock = _cpg_lock;
- clu_unlock = _cpg_unlock;
- clu_lock_finished = _cpg_lock_finished;
-
- errno = err;
- return ret;
-}
diff --git a/rgmanager/src/clulib/daemon_init.c b/rgmanager/src/clulib/daemon_init.c
deleted file mode 100644
index 711e06d..0000000
--- a/rgmanager/src/clulib/daemon_init.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/** @file
- * daemon_init function, does sanity checks and calls daemon().
- *
- * $Id$
- *
- * Author: Jeff Moyer <moyer(a)mclinux.com>
- */
-/*
- * TODO: Clean this up so that only one function constructs the
- * pidfile /var/run/loggerd.PID, and perhaps only one function
- * forms the /proc/PID/ path.
- *
- * Also need to add file locking for the pid file.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <sys/mman.h>
-#include <sys/errno.h>
-#include <libgen.h>
-#include <signal.h>
-#include <daemon_init.h>
-
-/*
- * Local prototypes.
- */
-static int setup_sigmask(void);
-static char pid_filename[PATH_MAX];
-
-
-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) {
- 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 (strstr(proc_cmdline, prog) == NULL) {
- return 0;
- }
-
- 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;
-}
-
-
-void
-update_pidfile(char *prog)
-{
- FILE *fp = NULL;
- char *cmd;
-
- memset(pid_filename, 0, PATH_MAX);
-
- cmd = basename(prog);
- snprintf(pid_filename, sizeof (pid_filename), "/var/run/%s.pid", cmd);
-
- fp = fopen(pid_filename, "w");
- if (fp == NULL) {
- exit(1);
- }
-
- fprintf(fp, "%d", getpid());
- fclose(fp);
-}
-
-
-static int
-setup_sigmask(void)
-{
- sigset_t set;
-
- sigfillset(&set);
-
- /*
- * Dont't block signals which would cause us to dump core.
- */
- sigdelset(&set, SIGQUIT);
- sigdelset(&set, SIGILL);
- sigdelset(&set, SIGTRAP);
- sigdelset(&set, SIGABRT);
- sigdelset(&set, SIGFPE);
- sigdelset(&set, SIGSEGV);
- sigdelset(&set, SIGBUS);
-
- return (sigprocmask(SIG_BLOCK, &set, NULL));
-}
-
-
-void
-daemon_init(char *prog)
-{
- uid_t uid;
- pid_t pid;
-
- uid = getuid();
- if (uid) {
- fprintf(stderr,
- "daemon_init: Sorry, only root wants to run this.\n");
- exit(1);
- }
-
- if (check_process_running(prog, &pid) && (pid != getpid())) {
- fprintf(stderr,
- "daemon_init: Process \"%s\" already running.\n",
- prog);
- exit(1);
- }
- if (setup_sigmask() < 0) {
- fprintf(stderr, "daemon_init: Unable to set signal mask.\n");
- exit(1);
- }
-
- if (daemon(0, 0)) {
- fprintf(stderr, "daemon_init: Unable to daemonize.\n");
- exit(1);
- }
-
- update_pidfile(prog);
- if (nice(-1) < 0)
- fprintf(stderr, "daemon_init: Unable to renice.\n");
-
- //mlockall(MCL_CURRENT | MCL_FUTURE);
-}
-
-
-void
-daemon_cleanup(void)
-{
- if (!strlen(pid_filename))
- return;
-
- unlink(pid_filename);
- memset(pid_filename, 0, sizeof(pid_filename));
-}
diff --git a/rgmanager/src/clulib/dlm_lock.c b/rgmanager/src/clulib/dlm_lock.c
deleted file mode 100644
index 0752b41..0000000
--- a/rgmanager/src/clulib/dlm_lock.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/** @file
- * Locking.
- */
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <sys/ioctl.h>
-#include <lock.h>
-#include <sys/types.h>
-#include <sys/select.h>
-#include <pthread.h>
-#include <logging.h>
-
-/* Default lockspace stuff */
-static dlm_lshandle_t _default_ls = NULL;
-static pthread_mutex_t _default_lock = PTHREAD_MUTEX_INITIALIZER;
-
-
-static void
-ast_function(void * __attribute__ ((unused)) arg)
-{
-}
-
-
-static int
-wait_for_dlm_event(dlm_lshandle_t ls)
-{
- fd_set rfds;
- int fd = dlm_ls_get_fd(ls);
-
- FD_ZERO(&rfds);
- FD_SET(fd, &rfds);
-
- if (select(fd + 1, &rfds, NULL, NULL, NULL) == 1)
- return dlm_dispatch(fd);
-
- return -1;
-}
-
-
-static int
-clu_ls_lock(dlm_lshandle_t ls,
- int mode,
- struct dlm_lksb *lksb,
- int options,
- const char *resource)
-{
- int ret;
-
- if (!ls || !lksb || !resource || !strlen(resource)) {
- logt_print(LOG_DEBUG, "Invalid lock request: %p %p %p %d\n",
- ls, lksb, resource, resource ? strlen(resource) : 0);
- errno = EINVAL;
- return -1;
- }
-
- ret = dlm_ls_lock(ls, mode, lksb, options, resource,
- strlen(resource), 0, ast_function, lksb,
- NULL, NULL);
-
- if (ret < 0) {
- if (errno == ENOENT)
- assert(0);
-
- return -1;
- }
-
- if ((ret = (wait_for_dlm_event(ls) < 0))) {
- logt_print(LOG_DEBUG, "wait_for_dlm_event: %d / %d\n",
- ret, errno);
- return -1;
- }
-
- if (lksb->sb_status == 0)
- return 0;
-
- errno = lksb->sb_status;
- return -1;
-}
-
-
-static dlm_lshandle_t
-clu_open_lockspace(const char *lsname)
-{
- dlm_lshandle_t ls = NULL;
-
- //printf("opening lockspace %s\n", lsname);
-
- while (!ls) {
- ls = dlm_open_lockspace(lsname);
- if (ls)
- break;
-
- /*
- printf("Failed to open: %s; trying create.\n",
- strerror(errno));
- */
-
- ls = dlm_create_lockspace(lsname, 0644);
- if (ls)
- break;
-
- /* Work around race: Someone was closing lockspace as
- we were trying to open it. Retry. */
- if (errno == ENOENT)
- continue;
-
- logt_print(LOG_DEBUG, "failed acquiring lockspace: %s\n",
- strerror(errno));
-
- return NULL;
- }
-
- return ls;
-}
-
-
-static int
-clu_ls_unlock(dlm_lshandle_t ls, struct dlm_lksb *lksb)
-{
- int ret;
-
- if (!ls || !lksb) {
- errno = EINVAL;
- return -1;
- }
-
- ret = dlm_ls_unlock(ls, lksb->sb_lkid, 0, lksb, NULL);
-
- if (ret != 0)
- return ret;
-
- /* lksb->sb_status should be EINPROG at this point */
-
- if (wait_for_dlm_event(ls) < 0) {
- errno = lksb->sb_status;
- return -1;
- }
-
- return 0;
-}
-
-
-static int
-clu_close_lockspace(dlm_lshandle_t ls, const char *name)
-{
- return dlm_release_lockspace(name, ls, 1);
-}
-
-
-static int
-_clu_lock(int mode,
- struct dlm_lksb *lksb,
- int options,
- const char *resource)
-{
- int ret = 0, block = 0, conv = 0, err;
-
- block = !(options & LKF_NOQUEUE);
-
- errno = EINVAL;
- if (!lksb)
- return -1;
-
- memset(lksb, 0, sizeof(struct dlm_lksb));
-
- /*
- Try to use a conversion lock mechanism when possible
- If the caller calls explicitly with a NULL lock, then
- assume the caller knows what it is doing.
-
- Only take the NULL lock if:
- (a) the user isn't specifying CONVERT; if they are, they
- know what they are doing.
-
- ...and one of...
-
- (b) This is a blocking call, or
- (c) The user requested a NULL lock explicitly. In this case,
- short-out early; there's no reason to convert a NULL lock
- to a NULL lock.
- */
- if (!(options & LKF_CONVERT) &&
- (block || (mode == LKM_NLMODE))) {
- /* Acquire NULL lock */
- pthread_mutex_lock(&_default_lock);
- ret = clu_ls_lock(_default_ls, LKM_NLMODE, lksb,
- (options & ~LKF_NOQUEUE),
- resource);
- err = errno;
- pthread_mutex_unlock(&_default_lock);
- if (ret == 0) {
- if (mode == LKM_NLMODE) {
- /* User only wanted a NULL lock... */
- return 0;
- }
- /*
- Ok, NULL lock was taken, rest of blocking
- call should be done using lock conversions.
- */
- options |= LKF_CONVERT;
- conv = 1;
- } else {
- switch(err) {
- case EINVAL:
- /* Oops, null locks don't work on this
- plugin; use normal spam mode */
- break;
- default:
- errno = err;
- return -1;
- }
- }
- }
-
- while (1) {
- pthread_mutex_lock(&_default_lock);
- ret = clu_ls_lock(_default_ls, mode, lksb,
- (options | LKF_NOQUEUE),
- resource);
- err = errno;
- pthread_mutex_unlock(&_default_lock);
-
- if ((ret != 0) && (err == EAGAIN) && block) {
- usleep(random()&32767);
- continue;
- }
-
- break;
- }
-
- if (ret != 0 && conv) {
- /* If we get some other error, release the NL lock we
- took so we don't leak locks*/
- pthread_mutex_lock(&_default_lock);
- clu_ls_unlock(_default_ls, lksb);
- pthread_mutex_unlock(&_default_lock);
- errno = err;
- }
-
- return ret;
-}
-
-
-static int
-_clu_unlock(struct dlm_lksb *lksb)
-{
- int ret, err;
- pthread_mutex_lock(&_default_lock);
- ret = clu_ls_unlock(_default_ls, lksb);
- err = errno;
- pthread_mutex_unlock(&_default_lock);
-
- usleep(random()&32767);
- errno = err;
- return ret;
-}
-
-
-static void
-_clu_lock_finished(const char *name)
-{
- pthread_mutex_lock(&_default_lock);
- if (_default_ls)
- clu_close_lockspace(_default_ls, name);
- pthread_mutex_unlock(&_default_lock);
-}
-
-
-int
-clu_lock_init(const char *dflt_lsname)
-{
- int ret, err;
-
- pthread_mutex_lock(&_default_lock);
- if (_default_ls) {
- pthread_mutex_unlock(&_default_lock);
- return 0;
- }
-
- if (!dflt_lsname || !strlen(dflt_lsname)) {
- pthread_mutex_unlock(&_default_lock);
- errno = EINVAL;
- return -1;
- }
-
- _default_ls = clu_open_lockspace(dflt_lsname);
- ret = (_default_ls == NULL);
- err = errno;
- pthread_mutex_unlock(&_default_lock);
-
- clu_lock = _clu_lock;
- clu_unlock = _clu_unlock;
- clu_lock_finished = _clu_lock_finished;
-
- errno = err;
- return ret;
-}
diff --git a/rgmanager/src/clulib/fdops.c b/rgmanager/src/clulib/fdops.c
deleted file mode 100644
index c7857c6..0000000
--- a/rgmanager/src/clulib/fdops.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/** @file
- * Wrapper functions around read/write/select to retry in the event
- * of interrupts.
- */
-#include <unistd.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <fdops.h>
-
-/**
- * This is a wrapper around select which will retry in the case we receive
- * EINTR. This is necessary for _read_retry, since it wouldn't make sense
- * to have _read_retry terminate if and only if two EINTRs were received
- * in a row - one during the read() call, one during the select call...
- *
- * See select(2) for description of parameters.
- */
-int
-_select_retry(int fdmax, fd_set * rfds, fd_set * wfds, fd_set * xfds,
- struct timeval *timeout)
-{
- int rv;
-
- while (1) {
- rv = select(fdmax, rfds, wfds, xfds, timeout);
- if ((rv == -1) && (errno == EINTR))
- /* return on EBADF/EINVAL/ENOMEM; continue on EINTR */
- continue;
- return rv;
- }
-}
-
-/**
- * Retries a write in the event of a non-blocked interrupt signal.
- *
- * @param fd File descriptor to which we are writing.
- * @param buf Data buffer to send.
- * @param count Number of bytes in buf to send.
- * @param timeout (struct timeval) telling us how long we should retry.
- * @return The number of bytes written to the file descriptor,
- * or -1 on error (with errno set appropriately).
- */
-ssize_t
-_write_retry(int fd, void *buf, int count, struct timeval * timeout)
-{
- int n, total = 0, remain = count, rv = 0;
- fd_set wfds, xfds;
-
- while (total < count) {
-
- /* Create the write FD set of 1... */
- FD_ZERO(&wfds);
- FD_SET(fd, &wfds);
- FD_ZERO(&xfds);
- FD_SET(fd, &xfds);
-
- /* wait for the fd to be available for writing */
- rv = _select_retry(fd + 1, NULL, &wfds, &xfds, timeout);
- if (rv == -1)
- return -1;
- else if (rv == 0) {
- errno = ETIMEDOUT;
- return -1;
- }
-
- if (FD_ISSET(fd, &xfds)) {
- errno = EPIPE;
- return -1;
- }
-
- /*
- * Attempt to write to fd
- */
- n = write(fd, (char *)buf + (off_t) total, remain);
-
- /*
- * When we know our fd was select()ed and we receive 0 bytes
- * when we write, the fd was closed.
- */
- if ((n == 0) && (rv == 1)) {
- errno = EPIPE;
- return -1;
- }
-
- if (n == -1) {
- if ((errno == EAGAIN) || (errno == EINTR)) {
- /*
- * Not ready?
- */
- continue;
- }
-
- /* Other errors: EIO, EINVAL, etc */
- return -1;
- }
-
- total += n;
- remain -= n;
- }
-
- return total;
-}
-
-/**
- * Retry reads until we (a) time out or (b) get our data. Of course, if
- * timeout is NULL, it'll wait forever.
- *
- * @param sockfd File descriptor we want to read from.
- * @param buf Preallocated buffer into which we will read data.
- * @param count Number of bytes to read.
- * @param timeout (struct timeval) describing how long we should retry.
- * @return The number of bytes read on success, or -1 on failure.
- Note that we will always return (count) or (-1).
- */
-ssize_t
-_read_retry(int sockfd, void *buf, int count, struct timeval * timeout)
-{
- int n, total = 0, remain = count, rv = 0;
- fd_set rfds, xfds;
-
- while (total < count) {
- FD_ZERO(&rfds);
- FD_SET(sockfd, &rfds);
- FD_ZERO(&xfds);
- FD_SET(sockfd, &xfds);
-
- /*
- * Select on the socket, in case it closes while we're not
- * looking...
- */
- rv = _select_retry(sockfd + 1, &rfds, NULL, &xfds, timeout);
- if (rv == -1)
- return -1;
- else if (rv == 0) {
- errno = ETIMEDOUT;
- return -1;
- }
-
- if (FD_ISSET(sockfd, &xfds)) {
- errno = EPIPE;
- return -1;
- }
-
- /*
- * Attempt to read off the socket
- */
- n = read(sockfd, (char*)buf + (off_t) total, remain);
-
- /*
- * When we know our socket was select()ed and we receive 0 bytes
- * when we read, the socket was closed.
- */
- if ((n == 0) && (rv == 1)) {
- errno = EPIPE;
- return -1;
- }
-
- if (n == -1) {
- if ((errno == EAGAIN) || (errno == EINTR)) {
- /*
- * Not ready? Wait for data to become available
- */
- continue;
- }
-
- /* Other errors: EPIPE, EINVAL, etc */
- return -1;
- }
-
- total += n;
- remain -= n;
- }
-
- return total;
-}
diff --git a/rgmanager/src/clulib/gettid.c b/rgmanager/src/clulib/gettid.c
deleted file mode 100644
index ba571c6..0000000
--- a/rgmanager/src/clulib/gettid.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <sys/types.h>
-#include <sys/syscall.h>
-#include <linux/unistd.h>
-#include <gettid.h>
-#include <errno.h>
-#include <unistd.h>
-
-/* Patch from Adam Conrad / Ubuntu: Don't use _syscall macro */
-
-#ifdef __NR_gettid
-pid_t gettid (void)
-{
- return syscall(__NR_gettid);
-}
-#else
-
-#warn "gettid not available -- substituting with pthread_self()"
-
-#include <pthread.h>
-pid_t gettid (void)
-{
- return (pid_t)pthread_self();
-}
-#endif
diff --git a/rgmanager/src/clulib/libcpglock.c b/rgmanager/src/clulib/libcpglock.c
deleted file mode 100644
index 75fc9f6..0000000
--- a/rgmanager/src/clulib/libcpglock.c
+++ /dev/null
@@ -1,287 +0,0 @@
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <pthread.h>
-#include <unistd.h>
-
-#include "cpglock.h"
-#include "cpglock-internal.h"
-#include "list.h"
-#include "sock.h"
-
-
-struct pending_node {
- list_head();
- struct cpg_lock_msg m;
-};
-
-
-struct cpg_lock_handle {
- pthread_mutex_t mutex;
- struct pending_node *pending;
- int fd;
- int pid;
- int seq;
-};
-
-
-static int
-check_pending(struct pending_node **l,
- struct cpg_lock_msg *exp,
- struct cpg_lock_msg *ret)
-{
- struct pending_node *p;
- int x;
-
- list_for(l, p, x) {
- if (!strcmp(exp->resource, p->m.resource) &&
- exp->owner_tid == p->m.owner_tid) {
- list_remove(l, p);
- memcpy(ret, &p->m, sizeof(*ret));
- free(p);
- return 0;
- }
- }
-
- return 1;
-}
-
-
-static void
-add_pending(struct pending_node **l,
- struct cpg_lock_msg *m)
-{
- struct pending_node *p = do_alloc(sizeof(*p));
-
- memcpy(&p->m, m, sizeof(p->m));
- list_insert(l, p);
-}
-
-
-/* Not thread safe */
-int
-cpg_lock_init(void **handle)
-{
- struct cpg_lock_handle *h;
- int esv;
-
- h = do_alloc(sizeof (*h));
- if (!h)
- return -1;
-
- h->fd = sock_connect(CPG_LOCKD_SOCK, 3);
- if (h->fd < 0) {
- esv = errno;
- free(h);
- errno = esv;
- return -1;
- }
-
- h->pid = getpid();
- pthread_mutex_init(&h->mutex, NULL);
-
- *handle = (void *)h;
- return 0;
-}
-
-
-int
-cpg_lock(void *handle, const char *resource, lock_flag_t flags, struct cpg_lock *lock)
-{
- struct cpg_lock_handle *h = handle;
- struct cpg_lock_msg l, r;
- struct timeval tv;
- int ret = -1;
-
- if (!h) {
- errno = EINVAL;
- return -1;
- }
-
- pthread_mutex_lock(&h->mutex);
-
- if (h->pid != (int)getpid()) {
- errno = EBADF;
- goto out;
- }
-
- if (strlen(resource) > sizeof(l.resource)-1) {
- errno = ENAMETOOLONG;
- goto out;
- }
-
- memset(&l, 0, sizeof(l));
- memset(&r, 0, sizeof(r));
- strncpy(l.resource, resource, sizeof(l.resource));
- strncpy(lock->resource, resource, sizeof(lock->resource));
- l.owner_pid = h->pid;
- ++h->seq;
- l.owner_tid = h->seq;
- l.request = MSG_LOCK;
- l.flags = (uint32_t)flags;
-
- if (write_retry(h->fd, &l, sizeof(l), 0) < 0)
- goto out;
-
- /* Thread concurrency: in case multiple threads wake up
- from select, peek at the message to see if it's ours */
- do {
- if (check_pending(&h->pending, &l, &r) == 0)
- break;
-
- tv.tv_sec = 0;
- tv.tv_usec = random() & 16383;
-
- if (read_retry(h->fd, &r, sizeof(r), &tv) < 0) {
- if (errno == ETIMEDOUT) {
- pthread_mutex_unlock(&h->mutex);
- usleep(random() & 16383);
- pthread_mutex_lock(&h->mutex);
- continue;
- }
- goto out;
- }
-
- if (strcmp(r.resource, l.resource)) {
- add_pending(&h->pending, &r);
- pthread_mutex_unlock(&h->mutex);
- usleep(random() & 16383);
- pthread_mutex_lock(&h->mutex);
- continue;
- }
- if (r.owner_tid != l.owner_tid) {
- add_pending(&h->pending, &r);
- pthread_mutex_unlock(&h->mutex);
- usleep(random() & 16383);
- pthread_mutex_lock(&h->mutex);
- continue;
- }
- break;
- } while (1);
- /* locked */
-
- if (r.owner_nodeid == 0)
- goto out;
-
- if (r.request == MSG_NAK) {
- errno = EAGAIN;
- ret = -1;
- goto out;
- }
-
- if (r.request != MSG_GRANT) {
- //ret = -1;
- goto out;
- }
-
- lock->state = LOCK_HELD;
- lock->owner_nodeid = r.owner_nodeid;
- lock->owner_pid = h->pid; /* XXX */
- lock->local_id = r.lockid;
-
- ret = 0;
-
-out:
- pthread_mutex_unlock(&h->mutex);
- return ret;
-}
-
-
-int
-cpg_unlock(void *handle, struct cpg_lock *lock)
-{
- struct cpg_lock_handle *h = handle;
- struct cpg_lock_msg l;
- int ret = -1;
-
- if (!h) {
- errno = EINVAL;
- goto out;
- }
-
- /* Only block on lock requests, not unlock */
- if (h->pid != (int)getpid()) {
- errno = EBADF;
- goto out;
- }
-
- if (lock->state != LOCK_HELD) {
- errno = EINVAL;
- goto out;
- }
-
- if (!lock->local_id) {
- errno = EINVAL;
- goto out;
- }
-
- strncpy(l.resource, lock->resource, sizeof(l.resource));
- l.request = MSG_UNLOCK;
- l.owner_nodeid = lock->owner_nodeid;
- l.owner_pid = lock->owner_pid;
- l.lockid = lock->local_id;
- l.owner_tid = 0;
- lock->state = LOCK_FREE;
-
- ret = write_retry(h->fd, &l, sizeof(l), 0);
-out:
- return ret;
-}
-
-
-int
-cpg_lock_dump(FILE *fp)
-{
- struct cpg_lock_msg l;
- int fd;
- char c;
-
- fd = sock_connect(CPG_LOCKD_SOCK, 3);
- if (fd < 0)
- return -1;
-
- memset(&l, 0, sizeof(l));
- l.request = MSG_DUMP;
-
- if (write_retry(fd, &l, sizeof(l), 0) < 0) {
- close(fd);
- return -1;
- }
-
- while (read_retry(fd, &c, 1, 0) == 1)
- fprintf(fp, "%c", c);
-
- close(fd);
- return 0;
-}
-
-
-
-/* Not thread safe */
-int
-cpg_lock_fin(void *handle)
-{
- struct cpg_lock_handle *h = handle;
-
- if (!h) {
- errno = EINVAL;
- return -1;
- }
-
- pthread_mutex_lock(&h->mutex);
-
- if (h->pid != (int)getpid()) {
- errno = EBADF;
- return -1;
- }
-
- close(h->fd);
-
- pthread_mutex_unlock(&h->mutex);
- pthread_mutex_destroy(&h->mutex);
- free(h);
- return 0;
-}
-
diff --git a/rgmanager/src/clulib/lock.c b/rgmanager/src/clulib/lock.c
deleted file mode 100644
index 74cd8b1..0000000
--- a/rgmanager/src/clulib/lock.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <lock.h>
-
-int (*clu_lock)(int, struct dlm_lksb *, int, const char *) = NULL;
-int (*clu_unlock)(struct dlm_lksb *lksb) = NULL;
-void (*clu_lock_finished)(const char *) = NULL;
-
diff --git a/rgmanager/src/clulib/locktest.c b/rgmanager/src/clulib/locktest.c
deleted file mode 100644
index c0d37b7..0000000
--- a/rgmanager/src/clulib/locktest.c
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <lock.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <pthread.h>
-#include <signal.h>
-
-
-void *
-lock_thread(void *arg)
-{
- struct dlm_lksb lksb;
-
- while(1) {
- printf("Taking lock..\n");
- clu_lock(LKM_EXMODE, &lksb, 0, arg);
- printf("Thread acquired lock on %s\n", (char *)arg);
- clu_unlock(&lksb);
- }
-}
-
-
-
-
-int
-main(int argc, char **argv)
-{
- struct dlm_lksb lksb;
- int ret;
- pthread_t th;
-
- if (clu_lock_init("Testing") != 0) {
- perror("clu_lock_init");
- return 1;
- }
-
- if (argc < 2) {
- printf("Lock what?\n");
- return 1;
- }
-
- if (argc == 3) {
- pthread_create(&th, NULL, lock_thread, strdup(argv[1]));
- }
-
- memset(&lksb,0,sizeof(lksb));
- ret = clu_lock(LKM_EXMODE, &lksb, 0, argv[1]);
- if (ret < 0) {
- perror("clu_lock");
- return 1;
- }
-
- printf("Acquired lock on %s; press enter to release\n", argv[1]);
- getchar();
-
- clu_unlock(&lksb);
-
- if (argc == 3) {
- printf("Press enter to kill lock thread...\n");
- getchar();
- pthread_kill(th, SIGTERM);
- }
-
- clu_lock_finished("Testing");
-
- return 0;
-}
diff --git a/rgmanager/src/clulib/logging.c b/rgmanager/src/clulib/logging.c
deleted file mode 100644
index 51c28b9..0000000
--- a/rgmanager/src/clulib/logging.c
+++ /dev/null
@@ -1,112 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#define SYSLOG_NAMES
-#include <syslog.h>
-#include <logging.h>
-#include <unistd.h>
-#include <string.h>
-#include <limits.h>
-#include <malloc.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <ccs.h>
-#include <limits.h>
-
-#define DAEMON_NAME "rgmanager"
-static char daemon_name[PATH_MAX];
-
-/* default: errors go to syslog (/var/log/messages) and <daemon>.log
- logging/debug=on: errors continue going to syslog (/var/log/messages)
- and <daemon>.log, debug messages are added to <daemon>.log. */
-
-#define DEFAULT_MODE LOG_MODE_OUTPUT_SYSLOG| \
- LOG_MODE_OUTPUT_FILE
-static int default_mode = DEFAULT_MODE;
-
-#define DEFAULT_FACILITY SYSLOGFACILITY /* cluster config setting */
-#define DEFAULT_PRIORITY SYSLOGLEVEL /* cluster config setting */
-static int default_priority = DEFAULT_PRIORITY;
-
-#define DEFAULT_FILE LOGDIR "/" DAEMON_NAME ".log"
-
-
-void
-init_logging(char *name, int foreground, int default_prio)
-{
- if (!name)
- name = (char *)DAEMON_NAME;
-
- strncpy(daemon_name, name, PATH_MAX);
-
- if (foreground)
- default_mode |= LOG_MODE_OUTPUT_STDERR;
- if (default_prio >= 0)
- default_priority = default_prio;
- logt_init(name, default_mode, DEFAULT_FACILITY,
- default_priority, default_priority, DEFAULT_FILE);
-}
-
-
-static int
-ccs_read_old_logging(int ccsfd, int *facility, int *priority)
-{
- char query[256];
- char *val;
- int x, ret = 0;
-
- /* Get log log_facility */
- snprintf(query, sizeof(query), "/cluster/rm/@log_facility");
- if (ccs_get(ccsfd, query, &val) == 0) {
- for (x = 0; facilitynames[x].c_name; x++) {
- if (strcasecmp(val, facilitynames[x].c_name))
- continue;
- *facility = facilitynames[x].c_val;
- ret = 1;
- break;
- }
- free(val);
- }
-
- /* Get log level */
- snprintf(query, sizeof(query), "/cluster/rm/@log_level");
- if (ccs_get(ccsfd, query, &val) == 0) {
- *priority = atoi(val);
- free(val);
- if (*priority < 0)
- *priority = default_priority;
- else
- ret = 1;
- }
-
- return ret;
-}
-
-
-/* this function is also called when we get a cman config-update event */
-void
-setup_logging(int ccs_handle)
-{
- int mode = default_mode;
- int facility = DEFAULT_FACILITY;
- int loglevel = default_priority, filelevel = default_priority;
- int debug = 0;
- char file[PATH_MAX];
-
- memset(file, 0, PATH_MAX);
- snprintf(file, sizeof(file)-1, DEFAULT_FILE);
- if (ccs_read_old_logging(ccs_handle, &facility, &loglevel))
- filelevel = loglevel;
-
- ccs_read_logging(ccs_handle, (char *)DAEMON_NAME, &debug, &mode,
- &facility, &loglevel, &filelevel, (char *)file);
-
- /* clulog uses rgmanager's config but getppid()'s name */
- logt_conf(daemon_name, mode, facility, loglevel,
- filelevel, file);
-}
-
-void
-close_logging(void)
-{
- logt_exit();
-}
diff --git a/rgmanager/src/clulib/members.c b/rgmanager/src/clulib/members.c
deleted file mode 100644
index 8a98f98..0000000
--- a/rgmanager/src/clulib/members.c
+++ /dev/null
@@ -1,527 +0,0 @@
-#include <sys/types.h>
-#include <arpa/inet.h>
-#include <stdint.h>
-#include <malloc.h>
-#include <libcman.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <members.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <rg_types.h>
-#include <pthread.h>
-#include <errno.h>
-
-static int my_node_id = -1;
-static pthread_rwlock_t memblock = PTHREAD_RWLOCK_INITIALIZER;
-static cluster_member_list_t *membership = NULL;
-
-
-/**
- Return the stored node ID. Since this should never
- change during the duration of running rgmanager, it is
- not protected by a lock.
- */
-int
-my_id(void)
-{
- return my_node_id;
-}
-
-
-int
-set_my_id(int id)
-{
- my_node_id = id;
- return 0;
-}
-
-
-/**
- Determine and store the local node ID. This should
- only ever be called once during initialization.
- */
-int
-get_my_nodeid(cman_handle_t h)
-{
- cman_node_t node;
- memset(&node,0,sizeof(node));
-
- if (cman_get_node(h, CMAN_NODEID_US, &node) != 0)
- return -1;
-
- return node.cn_nodeid;
-}
-
-
-
-/**
- Generate and return a list of members which are now online in a new
- membership list, given the old membership list. User must call
- @ref free_member_list
- to free the returned
- @ref cluster_member_list_t
- structure.
-
- @param old Old membership list
- @param new New membership list
- @return NULL if no members were gained, or a newly
- allocated cluster_member_list_t structure.
- */
-cluster_member_list_t *
-memb_gained(cluster_member_list_t *old, cluster_member_list_t *new)
-{
- int count, x, y;
- char in_old = 0;
- cluster_member_list_t *gained = NULL;
-
- /* No nodes in new? Then nothing could have been gained */
- if (!new || !new->cml_count)
- return NULL;
-
- /* Nothing in old? Duplicate 'new' and return it. */
- if (!old || !old->cml_count)
- return member_list_dup(new);
-
- /* Use greatest possible count */
- count = (old->cml_count > new->cml_count ?
- old->cml_count : new->cml_count);
- count *= sizeof(cman_node_t);
-
- gained = malloc(sizeof(cluster_member_list_t));
- if (!gained)
- return NULL;
- memset(gained, 0, sizeof(*gained));
-
- gained->cml_members = malloc(count);
- if (!gained->cml_members) {
- free(gained);
- return NULL;
- }
- memset(gained->cml_members, 0, count);
-
- for (x = 0; x < new->cml_count; x++) {
-
- /* This one isn't active at the moment; it could not have
- been gained. */
- if (!new->cml_members[x].cn_member)
- continue;
-
- in_old = 0;
- for (y = 0; y < old->cml_count; y++) {
- if ((new->cml_members[x].cn_nodeid !=
- old->cml_members[y].cn_nodeid) ||
- !old->cml_members[y].cn_member)
- continue;
- in_old = 1;
- break;
- }
-
- if (in_old)
- continue;
- memcpy(&gained->cml_members[gained->cml_count++],
- &new->cml_members[x], sizeof(cman_node_t));
- }
-
- if (gained->cml_count == 0) {
- free(gained->cml_members);
- free(gained);
- gained = NULL;
- }
-
- return gained;
-}
-
-
-/**
- Generate and return a list of members which are lost or no longer online
- in a new membership list, given the old membership list. User must call
- @ref free_member_list
- to free the returned
- @ref cluster_member_list_t
- structure.
-
- @param old Old membership list
- @param new New membership list
- @return NULL if no members were lost, or a newly
- allocated cluster_member_list_t structure.
- */
-cluster_member_list_t *
-memb_lost(cluster_member_list_t *old, cluster_member_list_t *new)
-{
- cluster_member_list_t *ret = NULL;
- int x;
-
- /* Reverse. ;) */
- ret = memb_gained(new, old);
- if (!ret)
- return NULL;
-
- for (x = 0; x < ret->cml_count; x++) {
- ret->cml_members[x].cn_member = 0;
- }
-
- return ret;
-}
-
-
-
-void
-member_list_update(cluster_member_list_t *new_ml)
-{
- pthread_rwlock_wrlock(&memblock);
- if (membership)
- free_member_list(membership);
- if (new_ml)
- membership = member_list_dup(new_ml);
- else
- membership = NULL;
- pthread_rwlock_unlock(&memblock);
-}
-
-
-cluster_member_list_t *
-member_list(void)
-{
- cluster_member_list_t *ret = NULL;
- pthread_rwlock_rdlock(&memblock);
- if (membership)
- ret = member_list_dup(membership);
- pthread_rwlock_unlock(&memblock);
- return ret;
-}
-
-
-int
-member_online_set(int **nodes, int *nodecount)
-{
- int ret = 1, i;
-
- pthread_rwlock_rdlock(&memblock);
- if (!membership)
- goto out_unlock;
-
- *nodes = malloc(sizeof(int) * membership->cml_count);
- if (!*nodes)
- goto out_unlock;
-
- *nodecount = 0;
- for (i = 0; i < membership->cml_count; i++) {
- if (membership->cml_members[i].cn_member &&
- membership->cml_members[i].cn_nodeid != 0) {
- (*nodes)[*nodecount] = membership->cml_members[i].cn_nodeid;
- ++(*nodecount);
- }
- }
-
- ret = 0;
-out_unlock:
- pthread_rwlock_unlock(&memblock);
- return ret;
-}
-
-
-void
-member_set_state(int nodeid, int state)
-{
- int x = 0;
-
- pthread_rwlock_wrlock(&memblock);
- if (!membership) {
- pthread_rwlock_unlock(&memblock);
- return;
- }
-
- for (x = 0; x < membership->cml_count; x++) {
- if (membership->cml_members[x].cn_nodeid == nodeid)
- membership->cml_members[x].cn_member = state;
- }
- pthread_rwlock_unlock(&memblock);
-}
-
-
-int
-member_online(int nodeid)
-{
- int x = 0, ret = 0;
-
- pthread_rwlock_rdlock(&memblock);
- if (!membership) {
- pthread_rwlock_unlock(&memblock);
- return 0;
- }
-
- for (x = 0; x < membership->cml_count; x++) {
- if (membership->cml_members[x].cn_nodeid == nodeid) {
- ret = membership->cml_members[x].cn_member;
- break;
- }
- }
- pthread_rwlock_unlock(&memblock);
-
- return ret;
-}
-
-
-cluster_member_list_t *
-get_member_list(cman_handle_t h)
-{
- int c;
- int tries = 0, local = 0;
- cluster_member_list_t *ml = NULL;
- cman_node_t *nodes = NULL;
-
- if (h == NULL) {
- local = 1;
- h = cman_init(NULL);
- if (!h)
- return NULL;
- }
-
- do {
-retry:
- ++tries;
- if (nodes) {
- free(nodes);
- nodes = NULL;
- }
-
- c = cman_get_node_count(h);
- if (c <= 0) {
- if (errno == EINTR)
- /* continue if ml == NULL -> crash */
- goto retry;
- if (ml)
- free(ml);
- ml = NULL;
- goto out;
- }
-
- if (!ml)
- ml = malloc(sizeof(*ml));
- if (!ml)
- goto out;
-
- nodes = malloc(sizeof(*nodes) * c);
- if (!nodes) {
- free(ml);
- ml = NULL;
- goto out;
- }
-
- memset(ml, 0, sizeof(*ml));
- memset(nodes, 0, sizeof(*nodes)*c);
-
- cman_get_nodes(h, c, &ml->cml_count, nodes);
-
- } while (ml->cml_count != c);
-
- ml->cml_members = nodes;
- ml->cml_count = c;
-
-out:
- if (local)
- cman_finish(h);
- return ml;
-}
-
-
-void
-free_member_list(cluster_member_list_t *ml)
-{
- if (ml) {
- if (ml->cml_members)
- free(ml->cml_members);
- free(ml);
- }
-}
-
-
-int
-memb_online(cluster_member_list_t *ml, int nodeid)
-{
- int x = 0;
-
- if (!ml)
- return 0;
-
- for (x = 0; x < ml->cml_count; x++) {
- if (ml->cml_members[x].cn_nodeid == nodeid)
- return ml->cml_members[x].cn_member;
- }
-
- return 0;
-}
-
-
-int
-memb_count(cluster_member_list_t *ml)
-{
- int x = 0, count = 0;
-
- if (!ml)
- return 0;
-
- for (x = 0; x < ml->cml_count; x++) {
- if (ml->cml_members[x].cn_member)
- ++count;
- }
-
- return count;
-}
-
-
-int
-memb_mark_down(cluster_member_list_t *ml, int nodeid)
-{
- int x = 0;
-
- if (!ml)
- return -1;
-
- for (x = 0; x < ml->cml_count; x++) {
- if (ml->cml_members[x].cn_nodeid == nodeid)
- ml->cml_members[x].cn_member = 0;
- }
-
- return 0;
-}
-
-
-
-char *
-memb_id_to_name(cluster_member_list_t *ml, int nodeid)
-{
- int x = 0;
- if (!ml)
- return NULL;
-
- for (x = 0; x < ml->cml_count; x++) {
- if (ml->cml_members[x].cn_nodeid == nodeid)
- return ml->cml_members[x].cn_name;
- }
-
- return NULL;
-}
-
-
-cman_node_t *
-memb_id_to_p(cluster_member_list_t *ml, int nodeid)
-{
- int x = 0;
- if (!ml)
- return NULL;
-
- for (x = 0; x < ml->cml_count; x++) {
- if (ml->cml_members[x].cn_nodeid == nodeid)
- return &ml->cml_members[x];
- }
-
- return NULL;
-}
-
-
-int
-memb_online_name(cluster_member_list_t *ml, char *name)
-{
- int x = 0;
- if (!ml)
- return 0;
-
- for (x = 0; x < ml->cml_count; x++) {
- if (!strcasecmp(ml->cml_members[x].cn_name, name))
- return ml->cml_members[x].cn_member;
- }
-
- return 0;
-}
-
-
-int
-memb_name_to_id(cluster_member_list_t *ml, char *name)
-{
- int x = 0;
- if (!ml)
- return 0;
-
- for (x = 0; x < ml->cml_count; x++) {
- if (!strcasecmp(ml->cml_members[x].cn_name, name))
- return ml->cml_members[x].cn_nodeid;
- }
-
- return 0;
-}
-
-
-cman_node_t *
-memb_name_to_p(cluster_member_list_t *ml, char *name)
-{
- int x = 0;
- if (!ml)
- return NULL;
-
- for (x = 0; x < ml->cml_count; x++) {
- if (!strcasecmp(ml->cml_members[x].cn_name, name))
- return &ml->cml_members[x];
- }
-
- return NULL;
-}
-
-/**
- Duplicate and return a cluster member list structure, sans the DNS resolution
- information.
-
- @param orig List to duplicate.
- @return NULL if there is nothing to duplicate or duplication
- fails, or a newly allocated cluster_member_list_t
- structure.
- */
-cluster_member_list_t *
-member_list_dup(cluster_member_list_t *orig)
-{
- cluster_member_list_t *ret = NULL;
-
- if (!orig)
- return NULL;
-
- ret = malloc(sizeof(cluster_member_list_t));
- if (!ret)
- return NULL;
- memset(ret, 0, sizeof(cluster_member_list_t));
- ret->cml_members = malloc(sizeof(cman_node_t) * orig->cml_count);
-
- if (!ret->cml_members) {
- free(ret);
- return NULL;
- }
- ret->cml_count = orig->cml_count;
- memcpy(ret->cml_members, orig->cml_members,
- orig->cml_count * sizeof(cman_node_t));
-
- return ret;
-}
-
-void member_list_shuffle(cluster_member_list_t *ml) {
- int i;
- unsigned st;
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- st = (int)(tv.tv_usec);
-
-
- for (i = 0 ; i < ml->cml_count ; i++) {
- cman_node_t temp;
- int newidx = rand_r(&st) % ml->cml_count;
- if (newidx == i)
- continue;
- memcpy(&temp, &ml->cml_members[i], sizeof(cman_node_t));
- memcpy(&ml->cml_members[i], &ml->cml_members[newidx], sizeof(cman_node_t));
- memcpy(&ml->cml_members[newidx], &temp, sizeof(cman_node_t));
- }
-}
diff --git a/rgmanager/src/clulib/message.c b/rgmanager/src/clulib/message.c
deleted file mode 100644
index 441d421..0000000
--- a/rgmanager/src/clulib/message.c
+++ /dev/null
@@ -1,273 +0,0 @@
-#define _MESSAGE_BUILD
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <message.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-/**
- Message sending API. Sends to the cluster or a socket, depending on
- the context.
- */
-int
-msg_send(msgctx_t *ctx, void *msg, size_t len)
-{
- errno = EINVAL;
- if (!ctx || !msg || !len)
- return -1;
-
- if (ctx->ops && ctx->ops->mo_send)
- return ctx->ops->mo_send(ctx, msg, len);
- errno = ENOSYS;
- return -1;
-}
-
-
-/* XXX get API for this ready */
-int
-msg_get_nodeid(msgctx_t *ctx)
-{
- /* XXX */
- switch(ctx->type) {
- case MSG_CLUSTER:
- return ctx->u.cluster_info.nodeid;
- case MSG_SOCKET:
- return 0;
- default:
- break;
- }
-
- return -1;
-}
-
-
-int
-msg_fd_set(msgctx_t *ctx, fd_set *fds, int *max)
-{
- errno = EINVAL;
- if (!ctx)
- return -1;
-
- if (ctx->ops && ctx->ops->mo_fd_set)
- return ctx->ops->mo_fd_set(ctx, fds, max);
- errno = ENOSYS;
- return -1;
-}
-
-
-int
-msg_fd_isset(msgctx_t *ctx, fd_set *fds)
-{
- errno = EINVAL;
- if (!ctx)
- return -1;
-
- if (ctx->ops && ctx->ops->mo_fd_isset)
- return ctx->ops->mo_fd_isset(ctx, fds);
- errno = ENOSYS;
- return -1;
-}
-
-
-int
-msg_fd_clr(msgctx_t *ctx, fd_set *fds)
-{
- errno = EINVAL;
- if (!ctx)
- return -1;
-
- if (ctx->ops && ctx->ops->mo_fd_clr)
- return ctx->ops->mo_fd_clr(ctx, fds);
- errno = ENOSYS;
- return -1;
-}
-
-
-/**
- This polls the context for 'timeout' seconds waiting for data
- to become available. Return codes are M_DATA, M_CLOSE, and M_OPEN
-
- M_DATA - data available
- M_OPEN - needs msg_accept(
- M_CLOSE - context / socket closed by remote host
- M_NONE - nothing available
-
- For the cluster connection, the return code could also map to one of
- the CMAN return codes
-
- M_STATECHANGE - node has changed state
-
- */
-int
-msg_wait(msgctx_t *ctx, int timeout)
-{
- errno = EINVAL;
- if (!ctx)
- return -1;
-
- if (ctx->ops && ctx->ops->mo_wait)
- return ctx->ops->mo_wait(ctx, timeout);
- errno = ENOSYS;
- return -1;
-}
-
-
-
-int
-msg_receive(msgctx_t *ctx, void *msg, size_t maxlen, int timeout)
-{
- errno = EINVAL;
- if (!ctx)
- return -1;
-
- if (ctx->ops && ctx->ops->mo_receive)
- return ctx->ops->mo_receive(ctx, msg, maxlen, timeout);
- errno = ENOSYS;
- return -1;
-}
-
-
-/**
- Open a connection to the specified node ID.
- If the speficied node is 0, this connects via the socket in
- /var/run/cluster...
- */
-int
-msg_open(int type, int nodeid, int port, msgctx_t *ctx, int timeout)
-{
- errno = EINVAL;
- if (!ctx)
- return -1;
-
- /* XXX SPECIAL CASE... ow. */
- switch(type) {
- case MSG_SOCKET:
- sock_msg_init(ctx);
- break;
- case MSG_CLUSTER:
- cluster_msg_init(ctx);
- break;
- default:
- return -1;
- }
-
- /* Record where this was called, in case we have to debug */
- ctx->sp = __builtin_return_address(0);
-
- if (ctx->ops && ctx->ops->mo_open)
- return ctx->ops->mo_open(ctx->type, nodeid, port, ctx, timeout);
- errno = ENOSYS;
- return -1;
-}
-
-
-/**
- Close a connection context (cluster or socket; it doesn't matter)
- In the case of a cluster context, we need to clear out the
- receive queue and what-not. This isn't a big deal. Also, we
- need to tell the other end that we're done -- just in case it does
- not know yet ;)
-
- With a socket, the O/S cleans up the buffers for us.
- */
-int
-msg_close(msgctx_t *ctx)
-{
- errno = EINVAL;
- if (!ctx)
- return -1;
- if (ctx->ops && ctx->ops->mo_close)
- return ctx->ops->mo_close(ctx);
- errno = ENOSYS;
- return -1;
-}
-
-
-int
-msg_accept(msgctx_t *listenctx, msgctx_t *acceptctx)
-{
- errno = EINVAL;
- if (!listenctx || !acceptctx)
- return -1;
- if (listenctx->ops && listenctx->ops->mo_accept)
- return listenctx->ops->mo_accept(listenctx, acceptctx);
- errno = ENOSYS;
- return -1;
-}
-
-
-/* XXX Special case */
-int
-msg_listen(int type, const void *port, int me, msgctx_t **ctx)
-{
- errno = EINVAL;
- if (!me)
- return -1;
- if (type == MSG_NONE)
- return -1;
- if (!ctx)
- return -1;
-
- if (type == MSG_CLUSTER) {
- return cluster_msg_listen(me, port, ctx);
- } else if (type == MSG_SOCKET) {
- return sock_msg_listen(me, port, ctx);
- }
-
- return -1;
-}
-
-
-void
-msg_print(msgctx_t *ctx)
-{
- if (!ctx) {
- printf("Attempt to call %s on NULL\n", __FUNCTION__);
- return;
- }
-
- if (ctx->ops && ctx->ops->mo_print)
- return ctx->ops->mo_print(ctx);
-
- printf("Warning: Attempt to call %s on uninitialized context %p\n",
- __FUNCTION__, ctx);
- printf(" ctx->type = %d\n", ctx->type);
-}
-
-
-/* XXX INCOMPLETE */
-int
-msg_shutdown(void)
-{
- sock_msg_shutdown();
- cluster_msg_shutdown();
-
- return 0;
-}
-
-
-msgctx_t *
-msg_new_ctx(void)
-{
- msgctx_t *p;
-
- p = malloc(sizeof(msgctx_t));
- if (!p)
- return NULL;
-
- memset(p, 0, sizeof(*p));
- p->type = MSG_NONE;
-
- return p;
-}
-
-
-void
-msg_free_ctx(msgctx_t *dead)
-{
- free(dead);
-}
diff --git a/rgmanager/src/clulib/msg_cluster.c b/rgmanager/src/clulib/msg_cluster.c
deleted file mode 100644
index 1fc283d..0000000
--- a/rgmanager/src/clulib/msg_cluster.c
+++ /dev/null
@@ -1,1278 +0,0 @@
-#define _MESSAGE_BUILD
-#include <stdio.h>
-#include <pthread.h>
-#include <libcman.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <message.h>
-#include <string.h>
-#include <sys/types.h>
-#include <time.h>
-#include <sys/time.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <signal.h>
-#include <signals.h>
-#include <gettid.h>
-#include <cman-private.h>
-#include <logging.h>
-
-#define CTX_INVALID ((uint32_t)-1)
-
-static void process_cman_event(cman_handle_t handle, void *private,
- int reason, int arg);
-/* Ripped from ccsd's setup_local_socket */
-
-int cluster_msg_close(msgctx_t *ctx);
-
-/* Context 0 is reserved for control messages */
-
-/* Local-ish contexts */
-static pthread_mutex_t context_lock = PTHREAD_MUTEX_INITIALIZER;
-static msgctx_t *contexts[MAX_CONTEXTS];
-static int _me = 0;
-pthread_t comms_thread;
-int thread_running = 0;
-
-#define is_established(ctx) \
- (((ctx->type == MSG_CLUSTER) && \
- (ctx->u.cluster_info.remote_ctx && \
- ctx->u.cluster_info.local_ctx)) || \
- ((ctx->type == MSG_SOCKET) && \
- (ctx->u.local_info.sockfd != -1)))
-
-static msg_ops_t cluster_msg_ops;
-static void cluster_msg_print(msgctx_t *ctx);
-
-
-#define proto_error(ctx, msg, str) \
-do { \
- printf("<<< CUT HERE >>>\n"); \
- printf("[%d] PROTOCOL ERROR in %s: %s\n", gettid(), __FUNCTION__, str); \
- msg_print(ctx); \
- if (msg) { \
- printf(" msg->msg_control = %d\n", ((cluster_msg_hdr_t *)msg)->msg_control); \
- printf(" msg->src_ctx = %d\n", ((cluster_msg_hdr_t *)msg)->src_ctx); \
- printf(" msg->dest_ctx = %d\n", ((cluster_msg_hdr_t *)msg)->dest_ctx); \
- printf(" msg->src_nodeid = %d\n", ((cluster_msg_hdr_t *)msg)->src_nodeid); \
- printf(" msg->msg_port = %d\n", ((cluster_msg_hdr_t *)msg)->msg_port); \
- } \
- printf(">>> CUT HERE <<<\n"); \
-} while(0)
-
-
-
-static int
-cluster_msg_send(msgctx_t *ctx, void *msg, size_t len)
-{
- char ALIGNED buf[4096];
- cluster_msg_hdr_t *h = (void *)buf;
- char *msgptr = (buf + sizeof(*h));
- int ret;
-
- errno = EINVAL;
- if (ctx->type != MSG_CLUSTER)
- return -1;
- if (!(ctx->flags & SKF_WRITE))
- return -1;
- if ((len + sizeof(*h)) > sizeof(buf)) {
- errno = E2BIG;
- return -1;
- }
-
- h->msg_control = M_DATA;
- h->dest_nodeid = ctx->u.cluster_info.nodeid;
- h->src_ctx = ctx->u.cluster_info.local_ctx;
- h->dest_ctx = ctx->u.cluster_info.remote_ctx;
- h->msg_port = ctx->u.cluster_info.port;
- memcpy(msgptr, msg, len);
- h->src_nodeid = _me;
-
- /*
- printf("sending cluster message, length = %d to nodeid %d port %d\n",
- len + sizeof(*h), ctx->u.cluster_info.nodeid,
- ctx->u.cluster_info.port);
- */
-
- swab_cluster_msg_hdr_t(h);
-
- ret = cman_send_data_unlocked((void *)h, len + sizeof(*h), 0,
- ctx->u.cluster_info.port,
- ctx->u.cluster_info.nodeid);
-
- if (ret < 0)
- return ret;
-
- if (ret >= (len + sizeof(*h)))
- return len;
-
- errno = EAGAIN;
- return -1;
-}
-
-
-/**
- Assign a (free) cluster context ID if possible
- */
-static int
-assign_ctx(msgctx_t *ctx)
-{
- int start;
- static uint32_t context_index = 1;
-
- /* Assign context index */
- pthread_mutex_lock(&context_lock);
-
- start = context_index;
- do {
- context_index++;
- if (context_index >= MAX_CONTEXTS)
- context_index = 1;
-
- if (!contexts[context_index]) {
- contexts[context_index] = ctx;
- ctx->u.cluster_info.local_ctx = context_index;
- pthread_mutex_unlock(&context_lock);
- return 0;
- }
- } while (context_index != start);
-
- pthread_mutex_unlock(&context_lock);
-
- errno = EAGAIN;
- return -1;
-}
-
-
-/* See if anything's on the cluster socket. If so, dispatch it
- on to the requisite queues
- XXX should be passed a connection arg! */
-static int
-poll_cluster_messages(int timeout)
-{
- int ret = -1;
- fd_set rfds;
- int fd, lfd, max;
- struct timeval tv;
- struct timeval *p = NULL;
- cman_handle_t ch;
-
- if (timeout >= 0) {
- p = &tv;
- tv.tv_sec = tv.tv_usec = timeout;
- }
-
- FD_ZERO(&rfds);
-
- /* This sucks - it could cause other threads trying to get a
- membership list to block for a long time. Now, that should not
- happen. Basically, when we get a membership event, we generate
- a new membership list in a locally cached copy and reference
- that.
-
- */
- ch = cman_lock_preemptible(1, &lfd);
- if (!ch) {
- printf("%s\n", strerror(errno));
- }
-
- fd = cman_get_fd(ch);
- if (fd < 0) {
- cman_unlock(ch);
- return 0;
- }
- FD_SET(fd, &rfds);
- FD_SET(lfd, &rfds);
-
- max = (lfd > fd ? lfd : fd);
- if (select(max + 1, &rfds, NULL, NULL, p) > 0) {
- /* Someone woke us up */
- if (FD_ISSET(lfd, &rfds)) {
- cman_unlock(ch);
- errno = EAGAIN;
- return -1;
- }
-
- if (cman_dispatch(ch, 0) < 0) {
- process_cman_event(ch, NULL,
- CMAN_REASON_TRY_SHUTDOWN, 1);
- }
- ret = 0;
- }
- cman_unlock(ch);
-
- return ret;
-}
-
-
-/**
- This is used to establish and tear down pseudo-private
- contexts which are shared with the cluster context.
- */
-static int
-cluster_send_control_msg(msgctx_t *ctx, int type)
-{
- cluster_msg_hdr_t cm;
- int ret;
-
- cm.msg_control = (uint8_t)type;
- cm.dest_nodeid = ctx->u.cluster_info.nodeid;
- cm.src_nodeid = _me;
- cm.dest_ctx = ctx->u.cluster_info.remote_ctx;
- cm.src_ctx = ctx->u.cluster_info.local_ctx;
- cm.msg_port = ctx->u.cluster_info.port;
-
- swab_cluster_msg_hdr_t(&cm);
-
- ret = (cman_send_data_unlocked((void *)&cm, sizeof(cm), 0,
- ctx->u.cluster_info.port,
- ctx->u.cluster_info.nodeid) );
- return ret;
-}
-
-
-/**
- Wait for a message on a context.
- */
-static int
-cluster_msg_wait(msgctx_t *ctx, int timeout)
-{
- struct timespec ts = {0, 0};
- struct timeval tv = {0, 0};
- int req = M_NONE;
- int e;
-
- errno = EINVAL;
- if (!ctx)
- return -1;
- if (ctx->type != MSG_CLUSTER)
- return -1;
- if (!(ctx->flags & (SKF_READ | SKF_LISTEN)))
- return -1;
-
- if (timeout > 0) {
- gettimeofday(&tv, NULL);
- ts.tv_sec = tv.tv_sec + timeout;
- ts.tv_nsec = tv.tv_usec * 1000;
- }
-
- pthread_mutex_lock(&ctx->u.cluster_info.mutex);
- while (1) {
-
- /* See if we dispatched any messages on to our queue */
- if (ctx->u.cluster_info.queue) {
- req = ctx->u.cluster_info.queue->message->msg_control;
- /*printf("Queue not empty CTX%d : %d\n",
- ctx->u.cluster_info.local_ctx, req);*/
- break;
- }
-
- /* Ok, someone else has the mutex on our FD. Go to
- sleep on a cond; maybe they'll wake us up */
- e = pthread_cond_timedwait(&ctx->u.cluster_info.cond,
- &ctx->u.cluster_info.mutex,
- &ts);
-
- if (timeout == 0) {
- break;
- }
-
- if (e == 0) {
- continue;
- }
-
- if (e == ETIMEDOUT) {
- break;
- }
- }
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
-
- return req;
-}
-
-
-static int
-cluster_msg_fd_set(msgctx_t *ctx, fd_set *fds, int *max)
-{
- int e;
- msg_q_t *n;
-
- errno = EINVAL;
- if (!ctx || !fds)
- return -1;
- if (ctx->type != MSG_CLUSTER)
- return -1;
-
- pthread_mutex_lock(&ctx->u.cluster_info.mutex);
- if (ctx->u.cluster_info.select_pipe[0] < 0) {
- if (pipe(ctx->u.cluster_info.select_pipe) < 0) {
- e = errno;
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
- errno = e;
- return -1;
- }
-
- /*
- printf("%s: Created cluster CTX select pipe "
- "rd=%d wr=%d\n", __FUNCTION__,
- ctx->u.cluster_info.select_pipe[0],
- ctx->u.cluster_info.select_pipe[1]);
- */
-
- /* Ok, we just created the pipe. Now, we need to write
- a char for every unprocessed event to the pipe, because
- events could be pending that would otherwise be unhandled
- by the caller because the caller is switching to select()
- semantics. (as opposed to msg_wait() ) */
- list_do(&ctx->u.cluster_info.queue, n) {
- if (write(ctx->u.cluster_info.select_pipe[1], "", 1) < 0) {
- e = errno;
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
- errno = e;
- return -1;
- }
- } while (!list_done(&ctx->u.cluster_info.queue, n));
- }
-
- e = ctx->u.cluster_info.select_pipe[0];
- //printf("%s: cluster %d\n", __FUNCTION__, e);
- FD_SET(e, fds);
-
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
-
- if (max && (e > *max))
- *max = e;
- return 0;
-}
-
-
-static int
-cluster_msg_fd_isset(msgctx_t *ctx, fd_set *fds)
-{
- errno = EINVAL;
-
- if (!fds || !ctx)
- return -1;
-
- if (ctx->type != MSG_CLUSTER)
- return -1;
-
- pthread_mutex_lock(&ctx->u.cluster_info.mutex);
- if (ctx->u.cluster_info.select_pipe[0] >= 0 &&
- FD_ISSET(ctx->u.cluster_info.select_pipe[0], fds)) {
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
- return 1;
- }
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
- return 0;
-}
-
-
-static int
-cluster_msg_fd_clr(msgctx_t *ctx, fd_set *fds)
-{
- errno = EINVAL;
-
- if (!fds || !ctx)
- return -1;
-
- if (ctx->type != MSG_CLUSTER)
- return -1;
-
- pthread_mutex_lock(&ctx->u.cluster_info.mutex);
- if (ctx->u.cluster_info.select_pipe[0] >= 0) {
- FD_CLR(ctx->u.cluster_info.select_pipe[0], fds);
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
- return 1;
- }
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
- return 0;
-}
-
-
-static int
-_cluster_msg_receive(msgctx_t *ctx, void **msg, size_t *len)
-{
- cluster_msg_hdr_t *m;
- msg_q_t *n;
- int ret = 0;
- char foo;
-
- if (msg)
- *msg = NULL;
- if (len)
- *len = 0;
-
- if (ctx->u.cluster_info.local_ctx == CTX_INVALID ||
- ctx->u.cluster_info.local_ctx >= MAX_CONTEXTS) {
- errno = EBADF;
- return -1;
- }
-
- /* trigger receive here */
- pthread_mutex_lock(&ctx->u.cluster_info.mutex);
-
- n = ctx->u.cluster_info.queue;
- if (n == NULL) {
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
- errno = EAGAIN;
- return -1;
- }
-
- list_remove(&ctx->u.cluster_info.queue, n);
-
- if (ctx->u.cluster_info.select_pipe[0] >= 0) {
- //printf("%s read\n", __FUNCTION__);
- if (read(ctx->u.cluster_info.select_pipe[0], &foo, 1) < 0) {
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
- return -1;
- }
- }
-
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
-
- m = n->message;
- switch(m->msg_control) {
- case M_CLOSE:
- ctx->u.cluster_info.remote_ctx = 0;
- break;
- case M_OPEN_ACK:
- /* Response to new connection */
- ctx->u.cluster_info.remote_ctx = m->src_ctx;
- break;
- case M_DATA:
- /* Kill the message control structure */
- memmove(m, &m[1], n->len - sizeof(*m));
- if (msg)
- *msg = (void *)m;
- else {
- printf("Warning: dropping data message\n");
- free(m);
- }
- if (len)
- *len = (n->len - sizeof(*m));
- ret = (n->len - sizeof(*m));
- free(n);
-
- //printf("Message received\n");
- return ret;
- case M_OPEN:
- /* Someone is trying to open a connection */
- default:
- /* ?!! */
- ret = -1;
- break;
- }
-
- free(m);
- free(n);
-
- return ret;
-}
-
-
-/**
- Receive a message from a cluster-context. This copies out the contents
- into the user-specified buffer, and does random other things.
- */
-static int
-cluster_msg_receive(msgctx_t *ctx, void *msg, size_t maxlen, int timeout)
-{
- int req;
- msg_q_t *n;
- void *priv_msg;
- size_t priv_len;
- char foo;
-
- errno = EINVAL;
- if (!ctx)
- return -1;
- if (!(ctx->flags & SKF_READ))
- return -1;
-
- req = cluster_msg_wait(ctx, timeout);
-
- switch (req) {
- case M_DATA:
- /* Copy out. */
- req = _cluster_msg_receive(ctx, &priv_msg, &priv_len);
- if (req < 0) {
- printf("Ruh roh!\n");
- return -1;
- }
-
- priv_len = (priv_len < maxlen ? priv_len : maxlen);
-
- if (msg && maxlen)
- memcpy(msg, priv_msg, priv_len);
- free(priv_msg);
- return req;
- case M_CLOSE:
- errno = ECONNRESET;
- return -1;
- case 0:
- //printf("Nothing on queue\n");
- return 0;
- case M_STATECHANGE:
- case M_PORTOPENED:
- case M_PORTCLOSED:
- case M_TRY_SHUTDOWN:
- case M_CONFIG_UPDATE:
- pthread_mutex_lock(&ctx->u.cluster_info.mutex);
-
- n = ctx->u.cluster_info.queue;
- if (n == NULL) {
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
- errno = EAGAIN;
- return -1;
- }
-
- list_remove(&ctx->u.cluster_info.queue, n);
-
- if (ctx->u.cluster_info.select_pipe[0] >= 0) {
- //printf("%s read\n", __FUNCTION__);
- if (read(ctx->u.cluster_info.select_pipe[0], &foo, 1) < 0) {
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
- return -1;
- }
- }
-
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
-
- if (n->message)
- free(n->message);
- free(n);
- return 0;
- default:
- break;
- }
-
- pthread_mutex_lock(&ctx->u.cluster_info.mutex);
- n = ctx->u.cluster_info.queue;
- list_remove(&ctx->u.cluster_info.queue, n);
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
-
- proto_error(ctx, n->message, "Illegal request on established pchannel");
- if (n->message)
- free(n->message);
- free(n);
- return -1;
-}
-
-
-/**
- Open a connection to the specified node ID.
- If the speficied node is 0, this connects via the socket in
- /var/run/cluster...
- */
-static int
-cluster_msg_open(int type, int nodeid, int port, msgctx_t *ctx, int timeout)
-{
- int t = 0, ret;
-
- errno = EINVAL;
- if (!ctx)
- return -1;
-
- if (type != MSG_CLUSTER)
- return -1;
-
- /*printf("Opening pseudo channel to node %d\n", nodeid);*/
-
- ctx->type = MSG_CLUSTER;
- ctx->ops = &cluster_msg_ops;
- ctx->flags = 0;
- ctx->u.cluster_info.nodeid = nodeid;
- ctx->u.cluster_info.port = port;
- ctx->u.cluster_info.local_ctx = CTX_INVALID;
- ctx->u.cluster_info.remote_ctx = 0;
- ctx->u.cluster_info.queue = NULL;
-
- pthread_mutex_init(&ctx->u.cluster_info.mutex, NULL);
- pthread_cond_init(&ctx->u.cluster_info.cond, NULL);
-
- /* Assign context index */
- if (assign_ctx(ctx) < 0) {
- errno = EAGAIN;
- return -1;
- }
- ctx->flags = SKF_READ | SKF_WRITE;
-
- if (nodeid == CMAN_NODEID_US) {
- /* Broadcast pseudo ctx; no handshake needed */
- ctx->flags |= SKF_MCAST;
- return 0;
- }
-
- //printf(" Local CTX: %d\n", ctx->u.cluster_info.local_ctx);
-
- /* Send open */
- //printf(" Sending control message M_OPEN\n");
- if (cluster_send_control_msg(ctx, M_OPEN) < 0) {
- printf("Error sending control message: %s\n", strerror(errno));
- cluster_msg_close(ctx);
- return -1;
- }
-
- /* Ok, wait for a response */
- while (!is_established(ctx)) {
- ++t;
- if (t > timeout) {
- cluster_msg_close(ctx);
- errno = ETIMEDOUT;
- return -1;
- }
-
- ret = cluster_msg_wait(ctx, 1);
- switch(ret) {
- case M_OPEN_ACK:
- _cluster_msg_receive(ctx, NULL, NULL);
- break;
- case M_NONE:
- continue;
- default:
- proto_error(ctx, NULL, "M_OPEN_ACK not received\n");
- }
- }
-
- /*
- printf(" Remote CTX: %d\n",
- ctx->u.cluster_info.remote_ctx);
- printf(" Pseudo channel established!\n");
- */
- return 0;
-}
-
-
-/**
- Close a connection context (cluster or socket; it doesn't matter)
- In the case of a cluster context, we need to clear out the
- receive queue and what-not. This isn't a big deal. Also, we
- need to tell the other end that we're done -- just in case it does
- not know yet ;)
-
- With a socket, the O/S cleans up the buffers for us.
- */
-int
-cluster_msg_close(msgctx_t *ctx)
-{
- msg_q_t *n = NULL;
-
- errno = EINVAL;
-
- if (!ctx)
- return -1;
- if (ctx->type != MSG_CLUSTER)
- return -1;
-
- if (ctx->u.cluster_info.local_ctx >= MAX_CONTEXTS) {
- printf("Context invalid during close\n");
- return -1;
- }
-
-
- pthread_mutex_lock(&context_lock);
- /* Other threads should not be able to see this again */
- if (contexts[ctx->u.cluster_info.local_ctx] &&
- (contexts[ctx->u.cluster_info.local_ctx]->u.cluster_info.local_ctx ==
- ctx->u.cluster_info.local_ctx)) {
- //printf("reclaimed context %d\n",
- //ctx->u.cluster_info.local_ctx);
- contexts[ctx->u.cluster_info.local_ctx] = NULL;
- }
- pthread_mutex_unlock(&context_lock);
-
- /* Clear receive queue */
- while ((n = ctx->u.cluster_info.queue) != NULL) {
- list_remove(&ctx->u.cluster_info.queue, n);
- free(n->message);
- free(n);
- }
- /* Send close message */
- if (ctx->u.cluster_info.remote_ctx != 0) {
- cluster_send_control_msg(ctx, M_CLOSE);
- }
-
- /* Close pipe if it's open */
- if (ctx->u.cluster_info.select_pipe[0] >= 0) {
- close(ctx->u.cluster_info.select_pipe[0]);
- ctx->u.cluster_info.select_pipe[0] = -1;
- }
- if (ctx->u.cluster_info.select_pipe[1] >= 0) {
- close(ctx->u.cluster_info.select_pipe[1]);
- ctx->u.cluster_info.select_pipe[1] = -1;
- }
- ctx->type = MSG_NONE;
- ctx->ops = NULL;
-
-
- return 0;
-}
-
-
-static void
-queue_for_context(msgctx_t *ctx, char *buf, int len)
-{
- msg_q_t *node;
-
- if (ctx->type != MSG_CLUSTER) {
- logt_print(LOG_WARNING, "%s called on invalid context %p\n",
- __FUNCTION__, ctx);
- return;
- }
-
- while ((node = malloc(sizeof(*node))) == NULL) {
- sleep(1);
- }
- memset(node, 0, sizeof(*node));
- while ((node->message = malloc(len)) == NULL) {
- sleep(1);
- }
- memcpy(node->message, buf, len);
- node->len = len;
-
- pthread_mutex_lock(&ctx->u.cluster_info.mutex);
- list_insert(&ctx->u.cluster_info.queue, node);
- /* If a select pipe was set up, wake it up */
- if (ctx->u.cluster_info.select_pipe[1] >= 0) {
- //printf("QUEUE_FOR_CONTEXT write\n");
- if (write(ctx->u.cluster_info.select_pipe[1], "", 1) < 0)
- perror("queue_for_context write");
- }
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
- pthread_cond_signal(&ctx->u.cluster_info.cond);
-}
-
-
-/**
- Called by cman_dispatch to deal with messages coming across the
- cluster socket. This function deals with fanning out the requests
- and putting them on the per-context queues. We don't have
- the benefits of pre-configured buffers, so we need this.
- */
-static void
-process_cman_msg(cman_handle_t h, void *priv, char *buf, int len,
- uint8_t port, int nodeid)
-{
- cluster_msg_hdr_t *m = (cluster_msg_hdr_t *)buf;
- int x;
-
- if (len < sizeof(*m)) {
- printf("Message too short.\n");
- return;
- }
-
- swab_cluster_msg_hdr_t(m);
-
-#ifdef DEBUG
- printf("Processing ");
- switch(m->msg_control) {
- case M_NONE:
- printf("M_NONE\n");
- break;
- case M_OPEN:
- printf("M_OPEN\n");
- break;
- case M_OPEN_ACK:
- printf("M_OPEN_ACK\n");
- break;
- case M_DATA:
- printf("M_DATA\n");
- break;
- case M_CLOSE:
- printf("M_CLOSE\n");
- break;
- }
-
- printf(" Node ID: %d %d\n", m->src_nodeid, nodeid);
- printf(" Remote CTX: %d Local CTX: %d\n", m->src_ctx, m->dest_ctx);
-#endif
-
- if (m->dest_ctx >= MAX_CONTEXTS || m->dest_ctx == CTX_INVALID) {
- printf("Context invalid; ignoring\n");
- return;
- }
-
- if (m->dest_nodeid != 0 && m->dest_nodeid != _me) {
-#ifdef DEBUG
- printf("Skipping message meant for node %d (I am %d)\n",
- m->dest_nodeid, _me);
-#endif
- return;
- }
-
- pthread_mutex_lock(&context_lock);
-
- if (m->dest_ctx == 0 && m->msg_control == M_DATA) {
- /* Copy & place on all broadcast queues if it's a broadcast
- M_DATA message... */
- for (x = 0; x < MAX_CONTEXTS; x++) {
- if (!contexts[x])
- continue;
- if (contexts[x]->type != MSG_CLUSTER)
- continue;
- if (!(contexts[x]->flags & SKF_MCAST))
- continue;
- if (!(contexts[x]->flags & SKF_READ))
- continue;
-
- queue_for_context(contexts[x], buf, len);
- }
- } else if (contexts[m->dest_ctx]) {
-
-#if 0
- if (m->msg_control == M_OPEN_ACK) {
- for (x = 0; x < MAX_CONTEXTS; x++) {
- if (contexts[x] &&
- contexts[x]->dest_ctx == m->src_ctx) {
- proto_error(contexts[x], m,
- "Duplicate M_OPEN_ACK");
- }
- }
- }
-#endif
- if (m->msg_control == M_CLOSE &&
- contexts[m->dest_ctx]->type != MSG_CLUSTER) {
- /* XXX Work around bug where M_CLOSE is called
- on a context which has been destroyed */
- logt_print(LOG_WARNING, "Ignoring M_CLOSE for destroyed "
- "context %d\n", m->dest_ctx);
- } else {
- queue_for_context(contexts[m->dest_ctx], buf, len);
- }
- }
- /* If none of the above, then we msg for something we've already
- detached from our list. No big deal, just ignore. */
-
- pthread_mutex_unlock(&context_lock);
- return;
-}
-
-
-/**
- Accept a new pseudo-private connection coming in over the
- cluster socket.
- */
-static int
-cluster_msg_accept(msgctx_t *listenctx, msgctx_t *acceptctx)
-{
- cluster_msg_hdr_t *m;
- msg_q_t *n;
- char foo;
- int err = 0;
-
- errno = EINVAL;
-
- if (!listenctx || !acceptctx)
- return -1;
- if (listenctx->u.cluster_info.local_ctx != 0)
- return -1;
- if (!(listenctx->flags & SKF_LISTEN))
- return -1;
-
- listenctx->ops->mo_init(acceptctx);
-
- pthread_mutex_lock(&listenctx->u.cluster_info.mutex);
-
- n = listenctx->u.cluster_info.queue;
- if (n == NULL) {
- pthread_mutex_unlock(&listenctx->u.cluster_info.mutex);
- errno = EAGAIN;
- return -1;
- }
-
- /* the OPEN should be the first thing on the list; this loop
- is probably not necessary */
- list_do(&listenctx->u.cluster_info.queue, n) {
-
- m = n->message;
- switch(m->msg_control) {
- case M_OPEN:
- /* XXX make this case statement its own function or at
- least make it not a big case block . */
- list_remove(&listenctx->u.cluster_info.queue, n);
- /*printf("Accepting connection from %d %d\n",
- m->src_nodeid, m->src_ctx);*/
-
- /* Release lock on listen context queue; we're done
- with it at this point */
- pthread_mutex_unlock(&listenctx->u.cluster_info.mutex);
-
- /* New connection: first, create + lock the mutex */
- pthread_mutex_init(&acceptctx->u.cluster_info.mutex,
- NULL);
- /* Lock this while we finish initializing */
- pthread_mutex_lock(&acceptctx->u.cluster_info.mutex);
-
- pthread_cond_init(&acceptctx->u.cluster_info.cond,
- NULL);
-
- acceptctx->u.cluster_info.queue = NULL;
- acceptctx->u.cluster_info.remote_ctx = m->src_ctx;
- acceptctx->u.cluster_info.nodeid = m->src_nodeid;
- acceptctx->u.cluster_info.port = m->msg_port;
- acceptctx->flags = (SKF_READ | SKF_WRITE);
-
- /* assign_ctx requires the context lock. We need to
- ensure we don't try to take the context lock w/ a local
- queue lock held on a context that's in progress (i.e.
- the global cluster context...) */
- if (assign_ctx(acceptctx) < 0)
- printf("FAILED TO ASSIGN CONTEXT\n");
-
- cluster_send_control_msg(acceptctx, M_OPEN_ACK);
-
- if (listenctx->u.cluster_info.select_pipe[0] >= 0) {
- //printf("%s read\n", __FUNCTION__);
- if (read(listenctx->u.cluster_info.select_pipe[0], &foo, 1) < 0)
- err = -1;
- }
-
- free(m);
- free(n);
-
- /* Let the new context go. */
- pthread_mutex_unlock(&acceptctx->u.cluster_info.mutex);
- return err;
- /* notreached */
-
- case M_DATA:
- /* Data messages (i.e. from broadcast msgs) are
- okay too!... but we don't handle them here */
- break;
- default:
- /* Other message?! */
- printf("Odd... %d\n", m->msg_control);
- break;
- }
-
- } while (!list_done(&listenctx->u.cluster_info.queue, n));
-
- pthread_mutex_unlock(&listenctx->u.cluster_info.mutex);
-
- return 0;
-}
-
-
-/**
- This waits for events on the cluster comms FD and
- dispatches them using cman_dispatch. Initially,
- the design had no permanent threads, but that model
- proved difficult to implement correctly.
- */
-static void *
-cluster_comms_thread(void *arg)
-{
- /* SIGUSR2 will cause select() to abort */
- while (thread_running) {
- poll_cluster_messages(2);
- }
-
- pthread_exit(NULL);
-}
-
-
-/*
- Transliterates a CMAN event to a control message
- */
-static void
-process_cman_event(cman_handle_t handle, void *private, int reason, int arg)
-{
- cluster_msg_hdr_t *msg;
- int *argp;
- msg_q_t *node;
- msgctx_t *ctx;
-
-#if 0
- printf("EVENT: %p %p %d %d\n", handle, private, reason, arg);
-#endif
-
- if (reason == CMAN_REASON_TRY_SHUTDOWN && !arg) {
- cman_replyto_shutdown(handle, 0);
- return;
- }
-
- /* Allocate queue node */
- while ((node = malloc(sizeof(*node))) == NULL) {
- sleep(1);
- }
- memset(node, 0, sizeof(*node));
-
- /* Allocate message: header + int (for arg) */
- while ((msg = malloc(sizeof(int)*2 +
- sizeof(cluster_msg_hdr_t))) == NULL) {
- sleep(1);
- }
- memset(msg, 0, sizeof(int)*2 +sizeof(cluster_msg_hdr_t));
-
- switch(reason) {
-#if defined(LIBCMAN_VERSION)
-#if LIBCMAN_VERSION >= 2
- case CMAN_REASON_PORTOPENED:
- msg->msg_control = M_PORTOPENED;
- break;
- case CMAN_REASON_TRY_SHUTDOWN:
- msg->msg_control = M_TRY_SHUTDOWN;
- break;
-#if LIBCMAN_VERSION >= 3
- case CMAN_REASON_CONFIG_UPDATE:
- msg->msg_control = M_CONFIG_UPDATE;
-#ifdef DEBUG
- printf("M_CONFIG_UPDATE received!\n");
-#endif
- break;
-#endif /* >= 3 */
-#endif /* >= 2 */
-#endif /* defined... */
- case CMAN_REASON_PORTCLOSED:
- msg->msg_control = M_PORTCLOSED;
- break;
- case CMAN_REASON_STATECHANGE:
- msg->msg_control = M_STATECHANGE;
- break;
- }
-
- argp = (int*)((char *)msg + sizeof(cluster_msg_hdr_t));
- *argp = arg;
-
- node->len = sizeof(cluster_msg_hdr_t) + sizeof(int);
- node->message = msg;
-
- pthread_mutex_lock(&context_lock);
- ctx = contexts[0]; /* This is the cluster context... */
- if (!ctx) {
- /* We received a close for something we've already
- detached from our list. No big deal, just
- ignore. */
- free(node->message);
- free(node);
- pthread_mutex_unlock(&context_lock);
- return;
- }
- pthread_mutex_unlock(&context_lock);
-
- pthread_mutex_lock(&ctx->u.cluster_info.mutex);
- list_insert(&ctx->u.cluster_info.queue, node);
- /* If a select pipe was set up, wake it up */
- if (ctx->u.cluster_info.select_pipe[1] >= 0) {
- //printf("PROCESS_CMAN_EVENT write\n");
- if (write(ctx->u.cluster_info.select_pipe[1], "", 1) < 0)
- perror("process_cman_event write");
- }
- pthread_mutex_unlock(&ctx->u.cluster_info.mutex);
- pthread_cond_signal(&ctx->u.cluster_info.cond);
-}
-
-
-/* */
-int
-cluster_msg_listen(int me, const void *portp, msgctx_t **cluster_ctx)
-{
- int e;
- pthread_attr_t attrs;
- cman_handle_t ch = NULL;
- msgctx_t *ctx;
- uint8_t port;
-
- errno = EINVAL;
- if (!portp)
- return -1;
- port = *(uint8_t *)portp;
- if (port < 10 || port > 254)
- return -1;
-
- ch = cman_lock(1, 0);
- _me = me;
-
- /* Set up cluster context */
- ctx = msg_new_ctx();
- if (!ctx) {
- cman_unlock(ch);
- errno = EINVAL;
- return -1;
- }
-
- memset(contexts, 0, sizeof(contexts));
-
- if (cman_start_recv_data(ch, process_cman_msg, port) != 0) {
- e = errno;
- cman_unlock(ch);
- msg_free_ctx((msgctx_t *)ctx);
-
- printf("Doom\n");
- errno = e;
- return -1;
- }
-
- if (cman_start_notification(ch, process_cman_event) != 0) {
- e = errno;
- cman_unlock(ch);
- msg_free_ctx((msgctx_t *)ctx);
- errno = e;
- return -1;
- }
-
- cman_unlock(ch);
- /* Done with CMAN bits */
-
- pthread_mutex_lock(&context_lock);
-
- memset(contexts, 0, sizeof(contexts));
- contexts[0] = ctx;
-
- ctx->type = MSG_CLUSTER;
- ctx->ops = &cluster_msg_ops;
- ctx->u.cluster_info.local_ctx = 0;
- ctx->u.cluster_info.remote_ctx = 0;
- ctx->u.cluster_info.port = port; /* port! */
- ctx->u.cluster_info.nodeid = 0; /* Broadcast! */
- ctx->u.cluster_info.select_pipe[0] = -1;
- ctx->u.cluster_info.select_pipe[1] = -1;
- ctx->u.cluster_info.queue = NULL;
- pthread_mutex_init(&ctx->u.cluster_info.mutex, NULL);
- pthread_cond_init(&ctx->u.cluster_info.cond, NULL);
- ctx->flags = SKF_LISTEN | SKF_READ | SKF_WRITE | SKF_MCAST;
- pthread_mutex_unlock(&context_lock);
-
- *cluster_ctx = ctx;
-
- pthread_attr_init(&attrs);
- pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED);
- /*pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);*/
-
- thread_running = 1;
- pthread_create(&comms_thread, &attrs, cluster_comms_thread, NULL);
-
- pthread_attr_destroy(&attrs);
-
- return 0;
-}
-
-
-static void
-cluster_msg_print(msgctx_t *ctx)
-{
- if (!ctx)
- return;
-
- printf("Cluster Message Context %p\n", ctx);
- printf(" Flags %08x\n", ctx->flags);
- printf(" Node ID %d\n", ctx->u.cluster_info.nodeid);
- printf(" Local CTX %d\n", ctx->u.cluster_info.local_ctx);
- printf(" Remote CTX %d\n", ctx->u.cluster_info.remote_ctx);
-}
-
-
-void
-dump_cluster_ctx(FILE *fp)
-{
- int x;
- msgctx_t *ctx;
-
- fprintf(fp, "CMAN/mux subsystem status\n");
- if (thread_running) {
- fprintf(fp, " Thread: %d\n", (unsigned)comms_thread);
- } else {
- fprintf(fp, " Thread Offline\n");
- }
-
- pthread_mutex_lock(&context_lock);
- for (x = 0; x < MAX_CONTEXTS; x++) {
- if (!contexts[x])
- continue;
- ctx = contexts[x];
-
- fprintf(fp, " Cluster Message Context %p\n", ctx);
- fprintf(fp, " Flags %08x ", ctx->flags);
- if (ctx->flags & SKF_READ)
- fprintf(fp, "SKF_READ ");
- if (ctx->flags & SKF_WRITE)
- fprintf(fp, "SKF_WRITE ");
- if (ctx->flags & SKF_LISTEN)
- fprintf(fp, "SKF_LISTEN ");
- if (ctx->flags & SKF_MCAST)
- fprintf(fp, "SKF_MCAST ");
- fprintf(fp, "\n");
- fprintf(fp, " Target node ID %d\n", ctx->u.cluster_info.nodeid);
- fprintf(fp, " Local Index %d\n", ctx->u.cluster_info.local_ctx);
- fprintf(fp, " Remote Index %d\n", ctx->u.cluster_info.remote_ctx);
- }
- pthread_mutex_unlock(&context_lock);
- fprintf(fp, "\n");
-}
-
-
-int
-cluster_msg_shutdown(void)
-{
- cman_handle_t ch;
- cluster_msg_hdr_t m;
- msgctx_t *ctx;
- int x;
-
- thread_running = 0;
- pthread_join(comms_thread, NULL);
-
- ch = cman_lock(1, SIGUSR2);
- cman_end_recv_data(ch);
- cman_unlock(ch);
-
- /* Send close message to all open contexts */
- memset(&m, 0, sizeof(m));
- m.msg_control = M_CLOSE;
-
- pthread_mutex_lock(&context_lock);
- for (x = 0; x < MAX_CONTEXTS; x++) {
- if (!contexts[x])
- continue;
-
- ctx = contexts[x];
-
- /* Kill remote side if it exists */
- if (is_established(ctx))
- cluster_send_control_msg(ctx, M_CLOSE);
-
- /* Queue close for local side */
- queue_for_context(ctx, (void *)&m, sizeof(m));
- }
- pthread_mutex_unlock(&context_lock);
-
-
- return 0;
-}
-
-
-int
-cluster_msg_init(msgctx_t *ctx)
-{
- errno = EINVAL;
- if (!ctx)
- return -1;
-
- memset(ctx, 0, sizeof(*ctx));
- ctx->type = MSG_CLUSTER;
- ctx->ops = &cluster_msg_ops;
- pthread_mutex_init(&ctx->u.cluster_info.mutex, NULL);
- pthread_cond_init(&ctx->u.cluster_info.cond, NULL);
- ctx->u.cluster_info.select_pipe[0] = -1;
- ctx->u.cluster_info.select_pipe[1] = -1;
-
- return 0;
-}
-
-
-static msg_ops_t cluster_msg_ops = {
- .mo_open = cluster_msg_open,
- .mo_close = cluster_msg_close,
- .mo_listen = cluster_msg_listen,
- .mo_accept = cluster_msg_accept,
- .mo_shutdown = cluster_msg_shutdown,
- .mo_wait = cluster_msg_wait,
- .mo_send = cluster_msg_send,
- .mo_receive = cluster_msg_receive,
- .mo_fd_set = cluster_msg_fd_set,
- .mo_fd_isset = cluster_msg_fd_isset,
- .mo_fd_clr = cluster_msg_fd_clr,
- .mo_print = cluster_msg_print,
- .mo_init = cluster_msg_init
-};
diff --git a/rgmanager/src/clulib/msg_socket.c b/rgmanager/src/clulib/msg_socket.c
deleted file mode 100644
index ae33922..0000000
--- a/rgmanager/src/clulib/msg_socket.c
+++ /dev/null
@@ -1,440 +0,0 @@
-#define _MESSAGE_BUILD
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <message.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <fdops.h>
-
-/* Ripped from ccsd's setup_local_socket */
-#define RGMGR_SOCK "/var/run/cluster/rgmanager.sk"
-
-static msg_ops_t sock_msg_ops;
-
-static void
-set_cloexec(int sock)
-{
- long sock_flags;
-
- sock_flags = fcntl(sock, F_GETFD);
- fcntl(sock, F_SETFD, sock_flags | FD_CLOEXEC);
-}
-
-static int
-sock_connect(void)
-{
- struct sockaddr_un sun;
- int sock = -1, error = 0;
-
- memset(&sun, 0, sizeof(sun));
- sun.sun_family = PF_LOCAL;
- snprintf(sun.sun_path, sizeof(sun.sun_path), "%s", RGMGR_SOCK);
-
- sock = socket(PF_LOCAL, SOCK_STREAM, 0);
- if (sock < 0) {
- error = errno;
- goto fail;
- }
-
- error = connect(sock, (struct sockaddr *)&sun, sizeof(sun));
- if (error < 0) {
- error = errno;
- close(sock);
- errno = error;
- sock = -1;
- goto fail;
- }
-
-fail:
-
- return sock;
-}
-
-
-/**
- Wrapper around write(2)
- */
-static int
-sock_msg_send(msgctx_t *ctx, void *msg, size_t len)
-{
- char buf[4096];
- int ret;
- local_msg_hdr_t *h = (local_msg_hdr_t *)buf;
- char *msgptr = (buf + sizeof(*h));
-
- if (!ctx)
- return -1;
- if (!(ctx->flags & SKF_WRITE))
- return -1;
-
- /* encapsulate ... ? */
- if ((len + sizeof(*h)) > sizeof(buf)) {
- errno = E2BIG;
- return -1;
- }
-
- h->msg_control = M_DATA;
- h->msg_len = len;
- memcpy(msgptr, msg, len);
-
- ret = _write_retry(ctx->u.local_info.sockfd, buf,
- len + sizeof(*h), NULL);
-
- if (ret >= sizeof(*h))
- return (ret - (sizeof(*h)));
-
- errno = EAGAIN;
- return -1;
-}
-
-
-static int
-peekypeeky(int fd)
-{
- local_msg_hdr_t h;
- int ret;
-
- while ((ret = recv(fd, (void *)&h, sizeof(h), MSG_PEEK)) < 0) {
- if (errno == EINTR)
- continue;
- return -1;
- }
-
- if (ret == sizeof(h))
- return h.msg_control;
-
- if (ret == 0)
- /* Socket closed? */
- return M_CLOSE;
-
- /* XXX */
- printf("PROTOCOL ERROR: Invalid message\n");
- return M_CLOSE;
-}
-
-
-static int
-sock_msg_wait(msgctx_t *ctx, int timeout)
-{
- fd_set rfds;
- struct timeval tv = {0, 0};
- struct timeval *p = NULL;
-
- if (timeout >= 0) {
- tv.tv_sec = timeout;
- p = &tv;
- }
-
- FD_ZERO(&rfds);
- FD_SET(ctx->u.local_info.sockfd, &rfds);
-
- if (_select_retry(ctx->u.local_info.sockfd + 1, &rfds,
- NULL, NULL, p) == 1) {
- return peekypeeky(ctx->u.local_info.sockfd);
- }
-
- return M_NONE;
-}
-
-
-static int
-sock_msg_fd_set(msgctx_t *ctx, fd_set *fds, int *max)
-{
- errno = EINVAL;
- if (ctx->type != MSG_SOCKET)
- return -1;
- if (!fds)
- return -1;
-
- if (ctx->u.local_info.sockfd >= 0) {
- FD_SET(ctx->u.local_info.sockfd, fds);
- if (ctx->u.local_info.sockfd > *max)
- *max = ctx->u.local_info.sockfd;
- return 0;
- }
-
- return -1;
-}
-
-
-static int
-sock_msg_fd_isset(msgctx_t *ctx, fd_set *fds)
-{
- errno = EINVAL;
- if (!fds || !ctx)
- return -1;
- if (ctx->type != MSG_SOCKET)
- return -1;
-
- if (ctx->u.local_info.sockfd >= 0 &&
- FD_ISSET(ctx->u.local_info.sockfd, fds)) {
- return 1;
- }
- return 0;
-}
-
-
-static int
-sock_msg_fd_clr(msgctx_t *ctx, fd_set *fds)
-{
- errno = EINVAL;
- if (!fds || !ctx)
- return -1;
- if (ctx->type != MSG_SOCKET)
- return -1;
-
- if (ctx->u.local_info.sockfd >= 0) {
- FD_CLR(ctx->u.local_info.sockfd, fds);
- return 1;
- }
- return 0;
-}
-
-
-static int
-_local_msg_receive(msgctx_t *ctx, void *msg, size_t maxlen, int timeout)
-{
- struct timeval tv = {0, 0};
- struct timeval *p = NULL;
- local_msg_hdr_t h;
-
- if (timeout > 0) {
- tv.tv_sec = timeout;
- p = &tv;
- }
-
- if (_read_retry(ctx->u.local_info.sockfd, &h, sizeof(h), p) < 0)
- return -1;
-
- if (maxlen < h.msg_len) {
- printf("WARNING: Buffer too small for message (%d vs %d)!\n",
- h.msg_len, (int)maxlen);
- h.msg_len = maxlen;
- }
-
- return _read_retry(ctx->u.local_info.sockfd, msg, h.msg_len, p);
-}
-
-
-/**
- Receive a message from a cluster-context. This copies out the contents
- into the user-specified buffer, and does random other things.
- */
-static int
-sock_msg_receive(msgctx_t *ctx, void *msg, size_t maxlen, int timeout)
-{
- int req;
- char priv_msg[4096];
- size_t priv_len = sizeof(priv_msg);
-
- errno = EINVAL;
- if (!msg || !maxlen)
- return -1;
- if (ctx->type != MSG_SOCKET)
- return -1;
- if (!(ctx->flags & SKF_READ))
- return -1;
-
- req = _local_msg_receive(ctx, priv_msg, priv_len, timeout);
-
- if (req == 0) {
- errno = ECONNRESET;
- return -1;
- }
-
- if (req < 0)
- return -1;
-
- /* Copy out. */
- priv_len = (priv_len < maxlen ? priv_len : maxlen);
-
- memcpy(msg, priv_msg, priv_len);
- return req;
-}
-
-
-/**
- Open a connection to the specified node ID.
- If the speficied node is 0, this connects via the socket in
- /var/run/cluster...
- */
-static int
-sock_msg_open(int type, int nodeid, int port, msgctx_t *ctx, int timeout)
-{
- errno = EINVAL;
- if (!ctx || ctx->type != MSG_SOCKET)
- return -1;
- if (type != MSG_SOCKET)
- return -1;
-
- if (nodeid != CMAN_NODEID_US)
- return -1;
- if ((ctx->u.local_info.sockfd = sock_connect()) < 0)
- return -1;
- ctx->flags = (SKF_READ | SKF_WRITE);
- return 0;
-}
-
-
-/**
- With a socket, the O/S cleans up the buffers for us.
- */
-static int
-sock_msg_close(msgctx_t *ctx)
-{
- errno = EINVAL;
- if (ctx->type != MSG_SOCKET)
- return -1;
-
- close(ctx->u.local_info.sockfd);
- ctx->u.local_info.sockfd = -1;
- ctx->flags = 0;
- ctx->type = MSG_NONE;
- return 0;
-}
-
-
-/**
- Accept a new pseudo-private connection coming in over the
- cluster socket.
- */
-static int
-sock_msg_accept(msgctx_t *listenctx, msgctx_t *acceptctx)
-{
- struct ucred cred;
- socklen_t credlen = sizeof(cred);
-
- errno = EINVAL;
-
- if (!listenctx || !acceptctx)
- return -1;
- if (listenctx->u.local_info.sockfd < 0)
- return -1;
- if (!(listenctx->flags & SKF_LISTEN))
- return -1;
-
- listenctx->ops->mo_init(acceptctx);
- acceptctx->u.local_info.sockfd =
- accept(listenctx->u.local_info.sockfd, NULL, NULL);
-
- if (acceptctx->u.local_info.sockfd < 0)
- return -1;
-
- memset(&cred, 0, sizeof(cred));
- if (getsockopt(acceptctx->u.local_info.sockfd, SOL_SOCKET,
- SO_PEERCRED, (void *)&cred, &credlen) < 0) {
- perror("getsockopt");
- cred.uid = (uid_t)-1;
- cred.gid = (gid_t)-1;
- cred.pid = (pid_t)-1;
- }
-
- memcpy(&acceptctx->u.local_info.cred, &cred,
- sizeof(cred));
-
- set_cloexec(acceptctx->u.local_info.sockfd);
-
- acceptctx->flags = (SKF_READ | SKF_WRITE);
- return 0;
-}
-
-
-int
-sock_msg_listen(int me, const void *portp, msgctx_t **listen_ctx)
-{
- int sock;
- struct sockaddr_un su;
- mode_t om;
- msgctx_t *ctx = NULL;
- char *path = (char *)portp;
-
- /* Set up cluster context */
- ctx = msg_new_ctx();
- if (!ctx)
- return -1;
-
- sock = socket(PF_LOCAL, SOCK_STREAM, 0);
- if (sock < 0) {
- msg_free_ctx(ctx);
- return -1;
- }
-
- set_cloexec(sock);
- unlink(RGMGR_SOCK);
- om = umask(0117);
- su.sun_family = PF_LOCAL;
- snprintf(su.sun_path, sizeof(su.sun_path), "%s", path);
-
- if (bind(sock, &su, sizeof(su)) < 0) {
- umask(om);
- goto fail;
- }
- umask(om);
-
- if (listen(sock, SOMAXCONN) < 0)
- goto fail;
-
- ctx->type = MSG_SOCKET;
- ctx->u.local_info.sockfd = sock;
- ctx->flags = SKF_LISTEN;
- ctx->ops = &sock_msg_ops;
- *listen_ctx = ctx;
- return 0;
-fail:
- if (ctx)
- free(ctx);
- if (sock >= 0)
- close(sock);
- return -1;
-}
-
-
-/* XXX INCOMPLETE - no local_ctx setup*/
-int
-sock_msg_init(msgctx_t *ctx)
-{
- memset(ctx,0,sizeof(*ctx));
- ctx->type = MSG_SOCKET;
- ctx->u.local_info.sockfd = -1;
- ctx->ops = &sock_msg_ops;
- return 0;
-}
-
-
-static void
-sock_msg_print(msgctx_t *ctx)
-{
- printf("Socket Message Context; fd = %d\n", ctx->u.local_info.sockfd);
-}
-
-
-/* XXX INCOMPLETE */
-int
-sock_msg_shutdown(void)
-{
- return 0;
-}
-
-
-static msg_ops_t sock_msg_ops = {
- .mo_open = sock_msg_open,
- .mo_close = sock_msg_close,
- .mo_listen = sock_msg_listen,
- .mo_accept = sock_msg_accept,
- .mo_shutdown = sock_msg_shutdown,
- .mo_wait = sock_msg_wait,
- .mo_send = sock_msg_send,
- .mo_receive = sock_msg_receive,
- .mo_fd_set = sock_msg_fd_set,
- .mo_fd_isset = sock_msg_fd_isset,
- .mo_fd_clr = sock_msg_fd_clr,
- .mo_print = sock_msg_print,
- .mo_init = sock_msg_init
-};
diff --git a/rgmanager/src/clulib/msgsimple.c b/rgmanager/src/clulib/msgsimple.c
deleted file mode 100644
index 0681619..0000000
--- a/rgmanager/src/clulib/msgsimple.c
+++ /dev/null
@@ -1,108 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/errno.h>
-#include <sys/socket.h>
-#include <malloc.h>
-#include <linux/limits.h>
-#include <sys/time.h>
-#include <sys/un.h>
-#include <dirent.h>
-#include <string.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <libgen.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <fcntl.h>
-#include <sys/syslog.h>
-#include <sys/ioctl.h>
-
-#include <message.h>
-#include <msgsimple.h>
-#include <platform.h>
-
-/*
- * msg_send_simple
- */
-int
-msg_send_simple(msgctx_t *ctx, int cmd, int arg1, int arg2)
-{
- generic_msg_hdr msg;
-
- msg.gh_magic = GENERIC_HDR_MAGIC;
- msg.gh_length = sizeof (msg);
- msg.gh_command = cmd;
- msg.gh_arg1 = arg1;
- msg.gh_arg2 = arg2;
- swab_generic_msg_hdr(&msg);
-
- return msg_send(ctx, (void *) &msg, sizeof (msg));
-}
-
-
-/*
- * receive_message
- *
- * Read a message and the corresponding buffer off of the file descriptor
- * indicated by fd. This allocates **buf; so the user must free it when
- * [s]he is done with it. Also returns the length of the full buffer in
- * *buf_size.
- *
- * Returns 0 on success or -1 on failure.
- */
-int
-msg_receive_simple(msgctx_t *ctx, generic_msg_hdr ** buf, int timeout)
-{
- int ret;
- char msgbuf[4096];
- generic_msg_hdr *peek_msg = (generic_msg_hdr *)msgbuf;
-
- /*
- * Peek at the header. We need the size of the inbound buffer!
- */
- errno = EAGAIN;
- ret = msg_wait(ctx, timeout);
- if (ret == M_CLOSE) {
- errno = ECONNRESET;
- return -1;
- }
-
- ret = msg_receive(ctx, peek_msg, sizeof(msgbuf), timeout);
-
- if (ret == -1) {
- fprintf(stderr, "msg_receive: %s\n", strerror(errno));
- return -1;
- }
-
- if (ret < sizeof(generic_msg_hdr)) {
- fprintf(stderr, "msg_receive_simple: invalid header\n");
- return -1;
- }
-
- /* Decode so we know how much to allocate */
- swab_generic_msg_hdr(peek_msg);
- if (peek_msg->gh_magic != GENERIC_HDR_MAGIC) {
- fprintf(stderr, "Invalid magic: Wanted 0x%08x, got 0x%08x\n",
- GENERIC_HDR_MAGIC, peek_msg->gh_magic);
- return -1;
- }
-
- /*
- * allocate enough memory to receive the header + diff buffer
- */
- *buf = malloc(peek_msg->gh_length);
- if (!*buf) {
- fprintf(stderr, "%s: malloc: %s", __FUNCTION__,
- strerror(errno));
- return -1;
- }
- memcpy(*buf, msgbuf, peek_msg->gh_length);
-
- /* Put it back into the original order... */
- swab_generic_msg_hdr((generic_msg_hdr *)(*buf));
-
- return ret;
-}
diff --git a/rgmanager/src/clulib/msgtest.c b/rgmanager/src/clulib/msgtest.c
deleted file mode 100644
index 4b46d6c..0000000
--- a/rgmanager/src/clulib/msgtest.c
+++ /dev/null
@@ -1,266 +0,0 @@
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/select.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <message.h>
-#include <signal.h>
-#include <cman-private.h>
-
-#define MYPORT 67
-
-int my_node_id = 0;
-int running = 1;
-
-
-static void *
-piggyback(void *arg)
-{
- msgctx_t ctx;
- char buf[4096];
-
- if (msg_open(MSG_CLUSTER, 0, MYPORT, &ctx, 0) != 0) {
- printf("Could not set up mcast socket!\n");
- pthread_exit(NULL);
- }
-
- printf("PIGGYBACK CONTEXT\n");
- msg_print(&ctx);
- printf("END PIGGYBACK CONTEXT\n");
-
- while (running) {
- if (msg_receive(&ctx, buf, sizeof(buf), 2) > 0) {
- printf("Piggyback received: %s\n", buf);
- }
- }
-
- msg_close(&ctx);
-
- printf("PIGGY flies...\n");
-
- pthread_exit(NULL);
-}
-
-
-static void *
-private(void *arg)
-{
- msgctx_t ctx;
- char buf[4096];
-
- while (running) {
- sleep(3);
-
- /* use pseudoprivate channel */
- if (msg_open(MSG_CLUSTER, my_node_id, MYPORT, &ctx, 1) != 0) {
- printf("Could not set up virtual-socket!\n");
- return NULL;
- }
-
- printf("=== pvt thread channel info ===\n");
- msg_print(&ctx);
- printf("=== end pvt thread channel info ===\n");
- fflush(stdout);
-
- snprintf(buf, sizeof(buf), "Hello!\n");
- msg_send(&ctx, buf, strlen(buf)+1);
-
- if (msg_receive(&ctx, buf, sizeof(buf), 10) > 0) {
- printf("PRIVATE: Received %s\n", buf);
- fflush(stdout);
- }
-
- msg_close(&ctx);
-
- if (msg_open(MSG_CLUSTER, 0, MYPORT, &ctx, 1) != 0) {
- printf("Could not set up mcast socket!\n");
- pthread_exit(NULL);
- }
-
- snprintf(buf, sizeof(buf), "Babble, babble\n");
- msg_send(&ctx, buf, strlen(buf)+1);
- if (msg_receive(&ctx, buf, sizeof(buf), 1) > 0) {
- printf("PRIVATE: Via MCAST %s\n", buf);
- fflush(stdout);
- }
- msg_close(&ctx);
- }
-
- printf("Private thread is outta here...\n");
-
- pthread_exit(NULL);
-}
-
-
-static void
-clu_initialize(cman_handle_t *ch)
-{
- if (!ch)
- exit(1);
-
- *ch = cman_init(NULL);
- if (!(*ch)) {
- printf("Waiting for CMAN to start\n");
-
- while (!(*ch = cman_init(NULL))) {
- sleep(1);
- }
- }
-
- if (!cman_is_quorate(*ch)) {
- /*
- There are two ways to do this; this happens to be the simpler
- of the two. The other method is to join with a NULL group
- and log in -- this will cause the plugin to not select any
- node group (if any exist).
- */
- printf("Waiting for quorum to form\n");
-
- while (cman_is_quorate(*ch) == 0) {
- sleep(1);
- }
- printf("Quorum formed, starting\n");
- }
-}
-
-
-static int
-side_message(msgctx_t *ctx)
-{
- msgctx_t actx;
- char buf[1024];
-
- if (msg_accept(ctx, &actx) < 0)
- return -1;
-
- printf("=== MAIN: Handling side message ===\n");
- msg_print(&actx);
- fflush(stdout);
-
- if (msg_receive(&actx, buf, sizeof(buf), 10) > 0) {
- printf("MAIN: Received %s\n", buf);
- snprintf(buf, sizeof(buf), "Goodbye!\n");
- msg_send(&actx, buf, strlen(buf)+1);
- }
-
- msg_close(&actx);
-
- printf("=== MAIN: end side message ===\n");
-
- return 0;
-}
-
-static void
-sigusr2_handler(int sig)
-{
-}
-
-int
-main(int argc, char **argv)
-{
- msgctx_t *cluster_ctx;
- char recvbuf[128];
- cman_node_t me;
- int ret;
- pthread_t piggy, priv;
- fd_set rfds;
- int max = 0;
- uint8_t ALIGNED port = MYPORT;
- cman_handle_t clu = NULL;
-
-
- clu_initialize(&clu);
-
- if (clu == NULL) {
- printf("Failed to connect to CMAN\n");
- }
-
- if (cman_init_subsys(clu) < 0) {
- perror("cman_init_subsys");
- return -1;
- }
-
- memset(&me, 0, sizeof(me));
-
- if (cman_get_node(clu, CMAN_NODEID_US, &me) < 0) {
- perror("cman_get_node");
- return -1;
- }
-
- my_node_id = me.cn_nodeid;
- printf("I am node ID %d\n", my_node_id);
-
- if (msg_listen(MSG_CLUSTER, (void *)&port, me.cn_nodeid, &cluster_ctx) < 0) {
- printf("Couldn't set up cluster message system: %s\n",
- strerror(errno));
- return -1;
- }
-
- signal(SIGTERM, sigusr2_handler);
- signal(SIGUSR2, sigusr2_handler);
-
- pthread_create(&piggy, NULL, piggyback, NULL);
- pthread_create(&priv, NULL, private, NULL);
-
- msg_print(cluster_ctx);
- while (running) {
- max = 0;
- FD_ZERO(&rfds);
- FD_SET(STDIN_FILENO, &rfds);
- msg_fd_set(cluster_ctx, &rfds, &max);
-
- select(max+1, &rfds, NULL, NULL, NULL);
-
- if (FD_ISSET(STDIN_FILENO, &rfds)) {
- if (!fgets(recvbuf, 128, stdin))
- break;
- if (recvbuf[0] == 'q' || recvbuf[0] == 'Q')
- break;
- if (msg_send(cluster_ctx, recvbuf,
- strlen(recvbuf)+1) < 0)
- perror("msg_send");
- FD_CLR(STDIN_FILENO, &rfds);
- }
-
- if (!msg_fd_isset(cluster_ctx, &rfds))
- continue;
-
- ret = msg_wait(cluster_ctx, 1);
-
- switch(ret) {
- case M_DATA:
- msg_receive(cluster_ctx, recvbuf, 128, 10);
- printf("MAIN: received %s\n", recvbuf);
- break;
- case M_OPEN:
- printf("MAIN: private connection detected\n");
- side_message(cluster_ctx);
- break;
- case 0:
- /* No data; probably a control msg */
- break;
- default:
- printf("Cluster EV: %d\n", ret);
- /* Cluster events, etc. */
- msg_receive(cluster_ctx, recvbuf, 128, 0);
- }
- }
-
- printf("Shutting down...\n");
-
- running = 0;
-
- pthread_join(piggy, NULL);
- pthread_join(priv, NULL);
-
- msg_close(cluster_ctx);
- msg_free_ctx(cluster_ctx);
- msg_shutdown();
-
- cman_finish(clu);
-
- exit(0);
-}
diff --git a/rgmanager/src/clulib/rg_strings.c b/rgmanager/src/clulib/rg_strings.c
deleted file mode 100644
index 868b91b..0000000
--- a/rgmanager/src/clulib/rg_strings.c
+++ /dev/null
@@ -1,219 +0,0 @@
-#include <res-ocf.h>
-#include <resgroup.h>
-
-struct string_val {
- int val;
- const char *str;
-};
-
-
-const struct string_val rg_error_strings[] = {
- { RG_EWARNING, "Warning; see system logs" },
- { RG_EPERM, "Permission denied" },
- { RG_ERELO, "Failed; service running on original owner" },
- { RG_EEXCL, "Service not runnable: cannot run exclusive" },
- { RG_EDOMAIN, "Service not runnable" },
- { RG_ESCRIPT, "S/Lang Script Error" },
- { RG_EFENCE, "Fencing operation pending; try again later" },
- { RG_ENODE, "Target node dead / nonexistent" },
- { RG_ERUN, "Service is already running" },
- { RG_EQUORUM, "Operation requires quorum" },
- { RG_EINVAL, "Invalid operation for resource" },
- { RG_EDEPEND, "Operation violates dependency rule" },
- { RG_EAGAIN, "Temporary failure; try again" },
- { RG_EDEADLCK, "Operation would cause a deadlock" },
- { RG_ENOSERVICE,"Service does not exist" },
- { RG_EFORWARD, "Service not mastered locally" },
- { RG_EABORT, "Aborted; service failed" },
- { RG_EFROZEN, "Failure: Service is frozen"},
- { RG_EFAIL, "Failure" },
- { RG_ESUCCESS, "Success" },
- { RG_YES, "Yes" },
- { RG_NO, "No" },
- { 0, NULL }
-};
-
-
-const struct string_val rg_req_strings[] = {
- {RG_SUCCESS, "success" },
- {RG_FAIL, "fail"},
- {RG_START, "start"},
- {RG_STOP, "stop"},
- {RG_STATUS, "status"},
- {RG_DISABLE, "disable"},
- {RG_STOP_RECOVER, "stop (recovery)"},
- {RG_START_RECOVER, "start (recovery)"},
- {RG_RESTART, "restart"},
- {RG_EXITING, "exiting"},
- {RG_INIT, "initialize"},
- {RG_ENABLE, "enable"},
- {RG_STATUS_NODE, "status inquiry"},
- {RG_RELOCATE, "relocate"},
- {RG_CONDSTOP, "conditional stop"},
- {RG_CONDSTART, "conditional start"},
- {RG_START_REMOTE,"remote start"},
- {RG_STOP_USER, "user stop"},
- {RG_STOP_EXITING, "stop (shutdown)"},
- {RG_LOCK, "locking"},
- {RG_UNLOCK, "unlocking"},
- {RG_QUERY_LOCK, "lock status inquiry"},
- {RG_MIGRATE, "migrate"},
- {RG_STATUS_INQUIRY, "out of band service status inquiry"},
- {RG_CONVALESCE, "convalesce"},
- {RG_NONE, "none"},
- {0, NULL}
-};
-
-
-const struct string_val rg_state_strings[] = {
- {RG_STATE_STOPPED, "stopped"},
- {RG_STATE_STARTING, "starting"},
- {RG_STATE_STARTED, "started"},
- {RG_STATE_STOPPING, "stopping"},
- {RG_STATE_FAILED, "failed"},
- {RG_STATE_UNINITIALIZED, "uninitialized"},
- {RG_STATE_CHECK, "checking"},
- {RG_STATE_ERROR, "recoverable"},
- {RG_STATE_RECOVER, "recovering"},
- {RG_STATE_DISABLED, "disabled"},
- {RG_STATE_MIGRATE, "migrating"},
- {0, NULL}
-};
-
-
-const struct string_val rg_flags_strings[] = {
- {RG_FLAG_FROZEN, "frozen"},
- {RG_FLAG_PARTIAL, "partial"},
- {0, NULL}
-};
-
-const struct string_val rg_flags_short[] = {
- {RG_FLAG_FROZEN, "Z"},
- {RG_FLAG_PARTIAL, "P"},
- {0, NULL}
-};
-
-const struct string_val agent_ops[] = {
- {RS_START, "start"},
- {RS_STOP, "stop"},
- {RS_STATUS, "status"},
- {RS_RESINFO, "resinfo"},
- {RS_RESTART, "restart"},
- {RS_RELOAD, "reload"},
- {RS_CONDRESTART, "condrestart"}, /* Unused */
- {RS_RECOVER, "recover"},
- {RS_CONDSTART, "condstart"},
- {RS_CONDSTOP, "condstop"},
- {RS_MONITOR, "monitor"},
- {RS_META_DATA, "meta-data"}, /* printenv */
- {RS_VALIDATE, "validate-all"},
- {RS_MIGRATE, "migrate"},
- {RS_RECONFIG, "reconfig"},
- {0 , NULL}
-};
-
-
-static inline const char *
-rg_search_table(const struct string_val *table, int val)
-{
- int x;
-
- for (x = 0; table[x].str != NULL; x++) {
- if (table[x].val == val) {
- return table[x].str;
- }
- }
-
- return "Unknown";
-}
-
-
-static inline const char *
-rg_flag_search_table(const struct string_val *table, int val)
-{
- int x;
-
- for (x = 0; table[x].str != NULL; x++) {
- if (table[x].val == val) {
- return table[x].str;
- }
- }
-
- return "Unknown";
-}
-
-static inline int
-rg_search_table_by_str(const struct string_val *table, const char *val)
-{
- int x;
-
- for (x = 0; table[x].str != NULL; x++) {
- if (!strcasecmp(table[x].str, val))
- return table[x].val;
- }
-
- return -1;
-}
-
-
-const char *
-rg_strerror(int val)
-{
- return rg_search_table(rg_error_strings, val);
-}
-
-
-const char *
-rg_state_str(int val)
-{
- return rg_search_table(rg_state_strings, val);
-}
-
-int
-rg_state_str_to_id(const char *val)
-{
- return rg_search_table_by_str(rg_state_strings, val);
-}
-
-
-const char *
-rg_req_str(int val)
-{
- return rg_search_table(rg_req_strings, val);
-}
-
-
-const char *
-rg_flag_str(int val)
-{
- return rg_search_table(rg_flags_strings, val);
-}
-
-
-const char *
-rg_flags_str(char *flags_string, size_t size, int val, char *separator)
-{
- const struct string_val *table = rg_flags_strings;
- int i;
- const char *string;
-
- if (!separator)
- table = rg_flags_short;
-
- for (i = 0; i < (sizeof(val) * 8); i++) {
- if ( val & (1 << i)) {
- if (strlen(flags_string) && separator)
- strncat(flags_string, separator, size - (strlen(flags_string) + strlen(separator) + 1));
- string = rg_search_table(table, (1 << i));
- strncat(flags_string, string, size - (strlen(flags_string) + strlen(string) + 1));
- }
- }
- return flags_string;
-}
-
-
-const char *
-agent_op_str(int val)
-{
- return rg_search_table(agent_ops, val);
-}
diff --git a/rgmanager/src/clulib/sets.c b/rgmanager/src/clulib/sets.c
deleted file mode 100644
index f4873c4..0000000
--- a/rgmanager/src/clulib/sets.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/**
- @file sets.c - Order-preserving set functions (union / intersection / delta)
- (designed for integer types; a la int, uint64_t, etc...)
- @author Lon Hohberger <lhh at redhat.com>
- */
-#include <stdio.h>
-#include <malloc.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sets.h>
-#include <sys/time.h>
-
-
-/**
- Add a value to a set. This function disregards an add if the value is already
- in the set. Note that the maximum length of set s must be preallocated; this
- function doesn't do error or bounds checking.
-
- @param s Set to modify
- @param curlen Current length (modified if added)
- @param val Value to add
- @return 0 if not added, 1 if added
- */
-int
-s_add(set_type_t *s, int *curlen, set_type_t val)
-{
- int idx=0;
-
- for (; idx < *curlen; idx++)
- if (s[idx] == val)
- return 0;
- s[*curlen] = val;
- ++(*curlen);
- return 1;
-}
-
-
-/**
- Union-set function. Allocates and returns a new set which is the union of
- the two given sets 'left' and 'right'. Also returns the new set length.
-
- @param left Left set - order is preserved on this set; that is,
- this is the set where the caller cares about ordering.
- @param ll Length of left set.
- @param right Right set - order is not preserved on this set during
- the union operation
- @param rl Length of right set
- @param ret Return set. Should * not * be preallocated.
- @param retl Return set length. Should be ready to accept 1 integer
- upon calling this function
- @return 0 on success, -1 on error
- */
-int
-s_union(set_type_t *left, int ll, set_type_t *right, int rl,
- set_type_t **ret, int *retl)
-{
- int l, r, cnt = 0, total;
-
- total = ll + rl; /* Union will never exceed both sets */
-
- *ret = malloc(sizeof(set_type_t)*total);
- if (!*ret) {
- return -1;
- }
- memset((void *)(*ret), 0, sizeof(set_type_t)*total);
-
- cnt = 0;
-
- /* Add all the ones on the left */
- for (l = 0; l < ll; l++)
- s_add(*ret, &cnt, left[l]);
-
- /* Add the ones on the left */
- for (r = 0; r < rl; r++)
- s_add(*ret, &cnt, right[r]);
-
- *retl = cnt;
-
- return 0;
-}
-
-
-/**
- Intersection-set function. Allocates and returns a new set which is the
- intersection of the two given sets 'left' and 'right'. Also returns the new
- set length.
-
- @param left Left set - order is preserved on this set; that is,
- this is the set where the caller cares about ordering.
- @param ll Length of left set.
- @param right Right set - order is not preserved on this set during
- the union operation
- @param rl Length of right set
- @param ret Return set. Should * not * be preallocated.
- @param retl Return set length. Should be ready to accept 1 integer
- upon calling this function
- @return 0 on success, -1 on error
- */
-int
-s_intersection(set_type_t *left, int ll, set_type_t *right, int rl,
- set_type_t **ret, int *retl)
-{
- int l, r, cnt = 0, total;
-
- total = ll; /* Intersection will never exceed one of the two set
- sizes */
-
- *ret = malloc(sizeof(set_type_t)*total);
- if (!*ret) {
- return -1;
- }
- memset((void *)(*ret), 0, sizeof(set_type_t)*total);
-
- cnt = 0;
- /* Find duplicates */
- for (l = 0; l < ll; l++) {
- for (r = 0; r < rl; r++) {
- if (left[l] != right[r])
- continue;
- if (s_add(*ret, &cnt, right[r]))
- break;
- }
- }
-
- *retl = cnt;
- return 0;
-}
-
-
-/**
- Delta-set function. Allocates and returns a new set which is the delta (i.e.
- numbers not in both sets) of the two given sets 'left' and 'right'. Also
- returns the new set length.
-
- @param left Left set - order is preserved on this set; that is,
- this is the set where the caller cares about ordering.
- @param ll Length of left set.
- @param right Right set - order is not preserved on this set during
- the union operation
- @param rl Length of right set
- @param ret Return set. Should * not * be preallocated.
- @param retl Return set length. Should be ready to accept 1 integer
- upon calling this function
- @return 0 on success, -1 on error
- */
-int
-s_delta(set_type_t *left, int ll, set_type_t *right, int rl,
- set_type_t **ret, int *retl)
-{
- int l, r, cnt = 0, total, found;
-
- total = ll + rl; /* Union will never exceed both sets */
-
- *ret = malloc(sizeof(set_type_t)*total);
- if (!*ret) {
- return -1;
- }
- memset((void *)(*ret), 0, sizeof(set_type_t)*total);
-
- cnt = 0;
-
- /* not efficient, but it works */
- /* Add all the ones on the left */
- for (l = 0; l < ll; l++) {
- found = 0;
- for (r = 0; r < rl; r++) {
- if (right[r] == left[l]) {
- found = 1;
- break;
- }
- }
-
- if (found)
- continue;
- s_add(*ret, &cnt, left[l]);
- }
-
-
- /* Add all the ones on the right*/
- for (r = 0; r < rl; r++) {
- found = 0;
- for (l = 0; l < ll; l++) {
- if (right[r] == left[l]) {
- found = 1;
- break;
- }
- }
-
- if (found)
- continue;
- s_add(*ret, &cnt, right[r]);
- }
-
- *retl = cnt;
-
- return 0;
-}
-
-
-/**
- Subtract-set function. Allocates and returns a new set which is the
- subtraction of the right set from the left set.
- Also returns the new set length.
-
- @param left Left set - order is preserved on this set; that is,
- this is the set where the caller cares about ordering.
- @param ll Length of left set.
- @param right Right set - order is not preserved on this set during
- the union operation
- @param rl Length of right set
- @param ret Return set. Should * not * be preallocated.
- @param retl Return set length. Should be ready to accept 1 integer
- upon calling this function
- @return 0 on success, -1 on error
- */
-int
-s_subtract(set_type_t *left, int ll, set_type_t *right, int rl,
- set_type_t **ret, int *retl)
-{
- int l, r, cnt = 0, total, found;
-
- total = ll; /* Union will never exceed left set length*/
-
- *ret = malloc(sizeof(set_type_t)*total);
- if (!*ret) {
- return -1;
- }
- memset((void *)(*ret), 0, sizeof(set_type_t)*total);
-
- cnt = 0;
-
- /* not efficient, but it works */
- for (l = 0; l < ll; l++) {
- found = 0;
- for (r = 0; r < rl; r++) {
- if (right[r] == left[l]) {
- found = 1;
- break;
- }
- }
-
- if (found)
- continue;
- s_add(*ret, &cnt, left[l]);
- }
-
- *retl = cnt;
-
- return 0;
-}
-
-
-/**
- Shuffle-set function. Weakly randomizes ordering of a set in-place.
-
- @param set Set to randomize
- @param sl Length of set
- @return 0
- */
-int
-s_shuffle(set_type_t *set, int sl)
-{
- int x, newidx;
- unsigned r_state = 0;
- set_type_t t;
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- r_state = (int)(tv.tv_usec);
-
- for (x = 0; x < sl; x++) {
- newidx = (rand_r(&r_state) % sl);
- if (newidx == x)
- continue;
- t = set[x];
- set[x] = set[newidx];
- set[newidx] = t;
- }
-
- return 0;
-}
-
-
-#ifdef STANDALONE
-/* Testbed */
-/*
- gcc -o sets sets.c -DSTANDALONE -ggdb -I../../include \
- -Wall -Werror -Wstrict-prototypes -Wextra
- */
-int
-main(int __attribute__ ((unused)) argc, char __attribute__ ((unused)) **argv)
-{
- set_type_t a[] = { 1, 2, 3, 3, 3, 2, 2, 3 };
- set_type_t b[] = { 2, 3, 4 };
- set_type_t *i;
- int ilen = 0, x;
-
- s_union(a, 8, b, 3, &i, &ilen);
-
- /* Should return length of 4 - { 1 2 3 4 } */
- printf("set_union [%d] = ", ilen);
- for ( x = 0; x < ilen; x++) {
- printf("%d ", (int)i[x]);
- }
- printf("\n");
-
- s_shuffle(i, ilen);
- printf("shuffled [%d] = ", ilen);
- for ( x = 0; x < ilen; x++) {
- printf("%d ", (int)i[x]);
- }
- printf("\n");
-
-
- free(i);
-
- /* Should return length of 2 - { 2 3 } */
- s_intersection(a, 8, b, 3, &i, &ilen);
-
- printf("set_intersection [%d] = ", ilen);
- for ( x = 0; x < ilen; x++) {
- printf("%d ", (int)i[x]);
- }
- printf("\n");
-
- free(i);
-
- /* Should return length of 2 - { 1 4 } */
- s_delta(a, 8, b, 3, &i, &ilen);
-
- printf("set_delta [%d] = ", ilen);
- for ( x = 0; x < ilen; x++) {
- printf("%d ", (int)i[x]);
- }
- printf("\n");
-
- free(i);
-
- /* Should return length of 1 - { 1 } */
- s_subtract(a, 8, b, 3, &i, &ilen);
-
- printf("set_subtract [%d] = ", ilen);
- for ( x = 0; x < ilen; x++) {
- printf("%d ", (int)i[x]);
- }
- printf("\n");
-
- free(i);
-
-
- return 0;
-}
-#endif
diff --git a/rgmanager/src/clulib/signals.c b/rgmanager/src/clulib/signals.c
deleted file mode 100644
index 1d49ee5..0000000
--- a/rgmanager/src/clulib/signals.c
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <resgroup.h>
-
-void *
-setup_signal(int sig, void (*handler)(int))
-{
- struct sigaction act;
- struct sigaction oldact;
-
- memset(&act, 0, sizeof(act));
- act.sa_handler = handler;
-
- unblock_signal(sig);
- if (sigaction(sig, &act, &oldact) == 0) {
- return oldact.sa_handler;
- }
-
- return NULL;
-}
-
-
-/**
- * Block the given signal.
- *
- * @param sig Signal to block.
- * @return See man sigprocmask.
- */
-int
-block_signal(int sig)
-{
- sigset_t set;
-
- sigemptyset(&set);
- sigaddset(&set, sig);
-
- return(sigprocmask(SIG_BLOCK, &set, NULL));
-}
-
-
-/**
- * Block the given signal.
- *
- * @param sig Signal to block.
- * @return See man sigprocmask.
- */
-int
-unblock_signal(int sig)
-{
- sigset_t set;
-
- sigemptyset(&set);
- sigaddset(&set, sig);
-
- return(sigprocmask(SIG_UNBLOCK, &set, NULL));
-}
-
-
-int
-block_all_signals(void)
-{
- sigset_t set;
-
- sigfillset(&set);
- sigdelset(&set, SIGSEGV);
- return(sigprocmask(SIG_BLOCK, &set, NULL));
-}
diff --git a/rgmanager/src/clulib/sock.c b/rgmanager/src/clulib/sock.c
deleted file mode 100644
index 3965a38..0000000
--- a/rgmanager/src/clulib/sock.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- Copyright Red Hat, Inc. 2002-2003, 2012
- Copyright Mission Critical Linux, 2000
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
- MA 02139, USA.
-*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/errno.h>
-#include <time.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <fcntl.h>
-
-#include "sock.h"
-
-void *
-do_alloc(size_t n)
-{
- void *p;
-
- do {
- p = malloc(n);
- if (!p) {
- usleep(10000);
- }
- } while(!p);
-
- memset(p, 0, n);
- return p;
-}
-
-
-/**
- * This is a wrapper around select which will retry in the case we receive
- * EINTR. This is necessary for read_retry, since it wouldn't make sense
- * to have read_retry terminate if and only if two EINTRs were received
- * in a row - one during the read() call, one during the select call...
- *
- * See select(2) for description of parameters.
- */
-int
-select_retry(int fdmax, fd_set * rfds, fd_set * wfds, fd_set * xfds,
- struct timeval *timeout)
-{
- int rv;
-
- while (1) {
- rv = select(fdmax, rfds, wfds, xfds, timeout);
- if ((rv == -1) && (errno == EINTR))
- /* return on EBADF/EINVAL/ENOMEM; continue on EINTR */
- continue;
- return rv;
- }
-}
-
-/**
- * Retries a write in the event of a non-blocked interrupt signal.
- *
- * @param fd File descriptor to which we are writing.
- * @param buf Data buffer to send.
- * @param count Number of bytes in buf to send.
- * @param timeout (struct timeval) telling us how long we should retry.
- * @return The number of bytes written to the file descriptor,
- * or -1 on error (with errno set appropriately).
- */
-ssize_t
-write_retry(int fd, void *buf, size_t count, struct timeval * timeout)
-{
- int n, rv = 0;
- ssize_t total = 0, remain = count;
- fd_set wfds, xfds;
-
- while (total < count) {
-
- /* Create the write FD set of 1... */
- FD_ZERO(&wfds);
- FD_SET(fd, &wfds);
- FD_ZERO(&xfds);
- FD_SET(fd, &xfds);
-
- /* wait for the fd to be available for writing */
- rv = select_retry(fd + 1, NULL, &wfds, &xfds, timeout);
- if (rv == -1)
- return -1;
- else if (rv == 0) {
- errno = ETIMEDOUT;
- return -1;
- }
-
- if (FD_ISSET(fd, &xfds)) {
- errno = EPIPE;
- return -1;
- }
-
- /*
- * Attempt to write to fd
- */
- n = write(fd, (char *)buf + (off_t) total, remain);
-
- /*
- * When we know our fd was select()ed and we receive 0 bytes
- * when we write, the fd was closed.
- */
- if ((n == 0) && (rv == 1)) {
- errno = EPIPE;
- return -1;
- }
-
- if (n == -1) {
- if ((errno == EAGAIN) || (errno == EINTR)) {
- /*
- * Not ready?
- */
- continue;
- }
-
- /* Other errors: EIO, EINVAL, etc */
- return -1;
- }
-
- total += n;
- remain -= n;
- }
-
- return total;
-}
-
-/**
- * Retry reads until we (a) time out or (b) get our data. Of course, if
- * timeout is NULL, it'll wait forever.
- *
- * @param sockfd File descriptor we want to read from.
- * @param buf Preallocated buffer into which we will read data.
- * @param count Number of bytes to read.
- * @param timeout (struct timeval) describing how long we should retry.
- * @return The number of bytes read on success, or -1 on failure.
- Note that we will always return (count) or (-1).
- */
-ssize_t
-read_retry(int sockfd, void *buf, size_t count, struct timeval * timeout)
-{
- int n, rv = 0;
- ssize_t total = 0, remain = count;
- fd_set rfds, xfds;
-
- memset(buf, 0, count);
-
- while (total < count) {
- FD_ZERO(&rfds);
- FD_SET(sockfd, &rfds);
- FD_ZERO(&xfds);
- FD_SET(sockfd, &xfds);
-
- /*
- * Select on the socket, in case it closes while we're not
- * looking...
- */
- rv = select_retry(sockfd + 1, &rfds, NULL, &xfds, timeout);
- if (rv == -1)
- return -1;
- else if (rv == 0) {
- errno = ETIMEDOUT;
- return -1;
- }
-
- if (FD_ISSET(sockfd, &xfds)) {
- errno = EPIPE;
- return -1;
- }
-
- /*
- * Attempt to read off the socket
- */
- n = read(sockfd, (char *)buf + (off_t) total, remain);
-
- /*
- * When we know our socket was select()ed and we receive 0 bytes
- * when we read, the socket was closed.
- */
- if ((n == 0) && (rv == 1)) {
- errno = EPIPE;
- return -1;
- }
-
- if (n == -1) {
- if ((errno == EAGAIN) || (errno == EINTR)) {
- /*
- * Not ready? Wait for data to become available
- */
- continue;
- }
-
- /* Other errors: EPIPE, EINVAL, etc */
- return -1;
- }
-
- total += n;
- remain -= n;
-
- //printf("read-retry %d/%d remain %d \n", total, count, remain);
- }
-
- return total;
-}
-
-
-int
-sock_listen(const char *sockpath)
-{
- int sock = -1;
- struct sockaddr_un su;
- mode_t om;
-
- sock = socket(PF_LOCAL, SOCK_STREAM, 0);
- if (sock < 0)
- goto fail;
-
- su.sun_family = PF_LOCAL;
- snprintf(su.sun_path, (sizeof(su.sun_path)), "%s", sockpath);
-
- unlink(su.sun_path);
- om = umask(077);
-
- if (bind(sock, (struct sockaddr *)&su, sizeof(su)) < 0) {
- umask(om);
- goto fail;
- }
- umask(om);
-
- if (listen(sock, SOMAXCONN) < 0)
- goto fail;
- return sock;
-fail:
- if (sock >= 0)
- close(sock);
- return -1;
-}
-
-
-int
-sock_connect(const char *sockpath, int tout)
-{
- struct timeval timeout = {tout, 0};
- int sock, flags, error, ret;
- socklen_t len;
- struct sockaddr_un sun;
- fd_set rfds, wfds;
-
- sock = socket(PF_LOCAL, SOCK_STREAM, 0);
- if (sock < 0)
- return -1;
-
- sun.sun_family = PF_LOCAL;
- snprintf(sun.sun_path, (sizeof(sun.sun_path)), "%s", sockpath);
-
- flags = fcntl(sock, F_GETFL, 0);
- fcntl(sock, F_SETFL, flags | O_NONBLOCK);
-
- ret = connect(sock, (struct sockaddr *) &sun, sizeof(sun));
-
- if (ret < 0 && (errno != EINPROGRESS)) {
- close(sock);
- return -1;
- }
-
- if (ret == 0)
- goto done;
-
- FD_ZERO(&rfds);
- FD_SET(sock, &rfds);
- wfds = rfds;
-
- ret = select(sock + 1, &rfds, &wfds, NULL, &timeout);
- if (ret == 0) {
- close(sock);
- errno = ETIMEDOUT;
- return -1;
- }
-
- if (FD_ISSET(sock, &rfds) || FD_ISSET(sock, &wfds)) {
- len = sizeof (error);
- if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
- close(sock);
- return -1;
- }
- } else {
- close(sock);
- return -1;
- }
-
-done:
-
- return sock;
-}
-
-
-int
-sock_accept(int sockfd)
-{
- int acceptfd;
-
- if (sockfd < 0) {
- errno = EBADF;
- return -1;
- }
-
- while ((acceptfd =
- accept(sockfd, (struct sockaddr *) NULL, NULL)) < 0) {
- if (errno == EINTR) {
- continue;
- }
-
- return -1;
- }
-
- return acceptfd;
-}
-
-
-void
-hexdump(const void *buf, size_t len)
-{
- size_t x;
-
- printf("%d bytes @ %p \n", (int)len, buf);
-
- for (x = 0; x < len; x++) {
- printf(" %02x", (((char *)buf)[x])&0xff);
- if (((x+1) % 16) == 0)
- printf("\n");
- }
-
- printf("\n");
-}
-
-
-
diff --git a/rgmanager/src/clulib/tmgr.c b/rgmanager/src/clulib/tmgr.c
deleted file mode 100644
index a86d258..0000000
--- a/rgmanager/src/clulib/tmgr.c
+++ /dev/null
@@ -1,150 +0,0 @@
-#ifdef WRAP_THREADS
-#include <stdio.h>
-#include <sys/types.h>
-#include <gettid.h>
-#include <pthread.h>
-#include <string.h>
-#include <errno.h>
-#include <malloc.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <pthread.h>
-#include <list.h>
-#include <execinfo.h>
-
-typedef struct _thr {
- list_head();
- void *(*fn)(void *arg);
- char **name;
- pthread_t th;
-} mthread_t;
-
-typedef struct _arglist {
- void *(*real_thread_fn)(void *arg);
- void *real_thread_arg;
-} thread_arg_t;
-
-static mthread_t *_tlist = NULL;
-static int _tcount = 0;
-static pthread_rwlock_t _tlock = PTHREAD_RWLOCK_INITIALIZER;
-
-void *
-setup_thread(void *thread_arg)
-{
- thread_arg_t *args = (thread_arg_t *)thread_arg;
- void *(*thread_func)(void *arg);
- sigset_t set;
-
- /* Block all non-fatal signals */
- sigemptyset(&set);
- sigaddset(&set, SIGUSR1);
- sigaddset(&set, SIGUSR2);
- sigaddset(&set, SIGINT);
- sigaddset(&set, SIGTERM);
- sigaddset(&set, SIGQUIT);
- sigaddset(&set, SIGHUP);
- sigprocmask(SIG_BLOCK, &set, NULL);
-
- thread_func = args->real_thread_fn;
- thread_arg = args->real_thread_arg;
- free(args);
- return thread_func(thread_arg);
-}
-
-void
-dump_thread_states(FILE *fp)
-{
- int x;
- mthread_t *curr;
- fprintf(fp, "Thread Information\n");
- pthread_rwlock_rdlock(&_tlock);
- list_for(&_tlist, curr, x) {
- fprintf(fp, " Thread #%d id: %d function: %s\n",
- x, (unsigned)curr->th, curr->name[0]);
- }
- pthread_rwlock_unlock(&_tlock);
- fprintf(fp, "\n\n");
-}
-
-
-int __real_pthread_create(pthread_t *, const pthread_attr_t *,
- void *(*)(void*), void *);
-int
-__wrap_pthread_create(pthread_t *th, const pthread_attr_t *attr,
- void *(*start_routine)(void*),
- void *arg)
-{
- void *fn = start_routine;
- mthread_t *newthread;
- thread_arg_t *targ;
- int ret;
-
- newthread = malloc(sizeof (*newthread));
- if (!newthread)
- return -1;
- targ = malloc(sizeof (*targ));
- if (!targ) {
- free(newthread)
- return -1;
- }
-
- targ->real_thread_fn = start_routine;
- targ->real_thread_arg = arg;
-
- ret = __real_pthread_create(th, attr, setup_thread, targ);
- if (ret) {
- if (newthread)
- free(newthread);
- if (targ)
- free(targ);
- return ret;
- }
-
- if (newthread) {
- newthread->th = *th;
- newthread->fn = start_routine;
- newthread->name = backtrace_symbols(&new->fn, 1);
- pthread_rwlock_wrlock(&_tlock);
- list_insert(&_tlist, newthread);
- ++_tcount;
- pthread_rwlock_unlock(&_tlock);
- }
-
- return ret;
-}
-
-
-void __real_pthread_exit(void *);
-void
-__wrap_pthread_exit(void *exitval)
-{
- mthread_t *old;
- int ret = 0, found = 0;
- pthread_t me = pthread_self();
-
- pthread_rwlock_rdlock(&_tlock);
- list_for(&_tlist, old, ret) {
- if (old->th == me) {
- found = 1;
- break;
- }
- }
- if (!found)
- old = NULL;
- pthread_rwlock_unlock(&_tlock);
-
- if (!old)
- __real_pthread_exit(exitval);
-
- pthread_rwlock_wrlock(&_tlock);
- list_remove(&_tlist, old);
- --_tcount;
- pthread_rwlock_unlock(&_tlock);
-
- if (old->name)
- free(old->name);
- free(old);
- __real_pthread_exit(exitval);
-}
-#endif
diff --git a/rgmanager/src/clulib/vft.c b/rgmanager/src/clulib/vft.c
deleted file mode 100644
index 8638cd4..0000000
--- a/rgmanager/src/clulib/vft.c
+++ /dev/null
@@ -1,1801 +0,0 @@
-//#define DEBUG
-/** @file
- * View-Formation Thread Library
- *
- * Similar to a two-phase commit. This code is not especially optimal
- * for the kind of work it's doing in rgmanager (e.g. distributing
- * resource group state). It's probably better to use a client/server
- * model like NFS and have clients restate their resource group states
- * after a server failure.
- */
-#include <platform.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/resource.h>
-#include <sys/wait.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <pthread.h>
-#include <vf.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <assert.h>
-#include <signals.h>
-#include <lock.h>
-
-static key_node_t *key_list = NULL; /** List of key nodes. */
-static int _node_id = (int)-1;/** Our node ID, set with vf_init. */
-static uint16_t _port = 0; /** Our daemon ID, set with vf_init. */
-static int _vf_timeout = 10;
-
-/*
- * TODO: We could make it thread safe, but this might be unnecessary work
- * Solution: Super-coarse-grained-bad-code-locking!
- */
-#ifdef WRAP_LOCKS
-static pthread_mutex_t key_list_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-static pthread_mutex_t vf_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-#else
-static pthread_mutex_t key_list_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t vf_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif /* WRAP_LOCKS */
-static pthread_t vf_thread = (pthread_t)-1;
-static int vf_thread_ready = 0;
-static vf_vote_cb_t default_vote_cb = NULL;
-static vf_vote_cb_t default_commit_cb = NULL;
-
-
-/*
- * Internal Functions
- */
-static int _send_simple(msgctx_t *ctx, int32_t command, int arg1, int arg2,
- int log_errors);
-static int vf_send_abort(msgctx_t *ctx, uint32_t trans);
-static int vf_send_commit(msgctx_t *ctx, uint32_t trans);
-static key_node_t * kn_find_key(const char *keyid);
-static key_node_t * kn_find_trans(uint32_t trans);
-static int vf_handle_join_view_msg(msgctx_t *ctx, int nodeid, vf_msg_t * hdrp);
-static int vf_resolve_views(key_node_t *key_node);
-static int vf_unanimous(msgctx_t *ctx, int trans, int remain, int timeout);
-static view_node_t * vn_new(uint32_t trans, uint32_t nodeid, int viewno,
- void *data, uint32_t datalen);
-static int vf_request_current(cluster_member_list_t *membership,
- const char *keyid, uint64_t *viewno,
- void **data, uint32_t *datalen);
-static int _vf_purge(key_node_t *key_node, uint32_t *trans);
-
-/* Join-view buffer list functions */
-static int vn_cmp(view_node_t *left, view_node_t *right);
-static int vn_insert_sorted(view_node_t **head, view_node_t *node);
-static view_node_t * vn_remove(view_node_t **head, uint32_t trans);
-static int vf_buffer_join_msg(vf_msg_t *hdr,
- struct timeval *timeout);
-
-/* Commits buffer list functions */
-static int vc_cmp(commit_node_t *left, commit_node_t *right);
-static int vc_insert_sorted(commit_node_t **head, commit_node_t *node);
-static commit_node_t * vc_remove(commit_node_t **head, uint32_t trans);
-static int vf_buffer_commit(uint32_t trans);
-
-/* Simple functions which client calls to vote/abort */
-static int vf_vote_yes(msgctx_t *ctx, uint32_t trans);
-static int vf_vote_no(msgctx_t *ctx, uint32_t trans);
-static int vf_abort(uint32_t trans);
-static int tv_cmp(struct timeval *left, struct timeval *right);
-
-/* Resolution */
-static uint32_t vf_try_commit(key_node_t *key_node);
-
-static int vf_key_init_nt(const char *keyid, int timeout,
- vf_vote_cb_t vote_cb, vf_commit_cb_t commit_cb);
-int vf_process_msg(msgctx_t *ctx, int nodeid, generic_msg_hdr *msgp, int nbytes);
-
-/* Reply to request for current data */
-static int vf_send_current(msgctx_t *, const char *);
-
-
-struct vf_args {
- msgctx_t *ctx;
- int local_node_id;
- uint16_t port;
-};
-
-
-static int
-_send_simple(msgctx_t *ctx, int32_t command, int arg1, int arg2, int log_errors)
-{
- generic_msg_hdr hdr;
-
- hdr.gh_magic = GENERIC_HDR_MAGIC;
- hdr.gh_length = sizeof(hdr);
- hdr.gh_command = command;
- hdr.gh_arg1 = arg1;
- hdr.gh_arg2 = arg2;
-
- swab_generic_msg_hdr(&hdr);
-
- return msg_send(ctx, &hdr, sizeof(hdr));
-}
-
-
-static int
-vf_send_abort(msgctx_t *ctx, uint32_t trans)
-{
-#ifdef DEBUG
- printf("VF: Broadcasting ABORT (X#%08x)\n", trans);
-#endif
- return _send_simple(ctx, VF_MESSAGE, VF_ABORT, trans, 0);
-}
-
-
-static int
-vf_send_commit(msgctx_t *ctx, uint32_t trans)
-{
-#ifdef DEBUG
- printf("VF: Broadcasting FORMED\n");
-#endif
- return _send_simple(ctx, VF_MESSAGE, VF_VIEW_FORMED, trans, 1);
-}
-
-
-static key_node_t *
-kn_find_key(const char *keyid)
-{
- key_node_t *cur;
-
- for (cur = key_list; cur; cur = cur->kn_next)
- if (!strcmp(cur->kn_keyid,keyid))
- return cur;
-
- return NULL;
-}
-
-
-static key_node_t *
-kn_find_trans(uint32_t trans)
-{
- key_node_t *cur;
- view_node_t *curvn;
-
- for (cur = key_list; cur; cur = cur->kn_next)
- for (curvn = cur->kn_jvlist; curvn; curvn = curvn->vn_next)
- if (curvn->vn_transaction == trans)
- return cur;
-
- return NULL;
-}
-
-
-static int
-vf_handle_join_view_msg(msgctx_t *ctx, int nodeid, vf_msg_t * hdrp)
-{
- struct timeval timeout;
- key_node_t *key_node;
- uint32_t trans;
-
- trans = hdrp->vm_msg.vf_transaction;
-#ifdef DEBUG
- printf("VF_JOIN_VIEW from member #%d! Key: %s #%d (X#%08x)\n",
- hdrp->vm_msg.vf_coordinator, hdrp->vm_msg.vf_keyid,
- (int) hdrp->vm_msg.vf_view, trans);
-#endif
-
- pthread_mutex_lock(&key_list_mutex);
- key_node = kn_find_key(hdrp->vm_msg.vf_keyid);
-
- /*
- * Call the voting callback function to see if we should continue.
- */
- if (!key_node) {
- if ((vf_key_init_nt(hdrp->vm_msg.vf_keyid,
- VF_COMMIT_TIMEOUT_MIN, NULL,
- NULL) < 0)) {
- pthread_mutex_unlock(&key_list_mutex);
- printf("VF: Error: Failed to initialize %s\n",
- hdrp->vm_msg.vf_keyid);
- vf_vote_no(ctx, trans);
- return VFR_ERROR;
- }
-
- key_node = kn_find_key(hdrp->vm_msg.vf_keyid);
- assert(key_node);
- }
-
- if (key_node->kn_vote_cb) {
- if ((key_node->kn_vote_cb)(hdrp->vm_msg.vf_keyid,
- hdrp->vm_msg.vf_view,
- hdrp->vm_msg.vf_data,
- hdrp->vm_msg.vf_datalen) == 0) {
- pthread_mutex_unlock(&key_list_mutex);
-#ifdef DEBUG
- printf("VF: Voting NO (via callback)\n");
-#endif
- vf_vote_no(ctx, trans);
- return VFR_OK;
- }
- }
-
- /*
- * Buffer the join-view message.
- */
- timeout.tv_sec = key_node->kn_tsec;
- timeout.tv_usec = 0;
-
- if (vf_buffer_join_msg((vf_msg_t *) hdrp, &timeout)) {
- pthread_mutex_unlock(&key_list_mutex);
-#ifdef DEBUG
- printf("VF: Voting YES (X#%08x)\n", trans);
-#endif
- vf_vote_yes(ctx, trans);
- return VFR_OK;
- }
-
- pthread_mutex_unlock(&key_list_mutex);
-#ifdef DEBUG
- printf("VF: Voting NO\n");
-#endif
- vf_vote_no(ctx, trans);
- return VFR_NO;
-}
-
-
-/*
- * Try to resolve (JOIN_VIEW, FORMED_VIEW) messages in the proper order.
- * Returns the number of commits.
- */
-static int
-vf_resolve_views(key_node_t *key_node)
-{
- int commits = 0;
- void *data;
- uint32_t datalen;
- uint32_t trans;
-
- if (!key_node)
- return 0;
-
- while ((trans = vf_try_commit(key_node)) != 0) {
- commits++;
- }
-
- if (key_node->kn_commit_cb) {
- data = malloc(key_node->kn_datalen);
- if (!data) {
- /* XXX */
- return commits;
- }
-
- datalen = key_node->kn_datalen;
- memcpy(data, key_node->kn_data, datalen);
-
- (key_node->kn_commit_cb)(key_node->kn_keyid,
- key_node->kn_viewno,
- data,
- datalen);
- }
-
- return commits;
-}
-
-
-static int
-vf_unanimous(msgctx_t *mcast_ctx, int trans, int remain,
- int timeout)
-{
- generic_msg_hdr response;
- int x;
-
- /*
- * Flag hosts which we received messages from so we don't
- * read a second message.
- */
- while (remain && timeout) {
-
- if (msg_wait(mcast_ctx, 1) <= 0) {
- --timeout;
- continue;
- }
-
- x = msg_receive(mcast_ctx, &response, sizeof(response), 1);
- if (x < sizeof(response))
- continue;
-
- /*
- * Decode & validate message
- */
- swab_generic_msg_hdr(&response);
- if ((response.gh_magic != GENERIC_HDR_MAGIC) ||
- (response.gh_command != VF_MESSAGE)) {
- /* Don't process anything but votes */
- continue;
- }
-
- if (vf_command(response.gh_arg1) != VF_VOTE)
- /* Don't process anything but votes */
- continue;
-
- if (response.gh_arg2 != trans)
- continue;
-
- /*
- * If we get a 'NO', we are done.
- */
- if (!(vf_flags(response.gh_arg1) & VFMF_AFFIRM)) {
- /*
- * XXX ok, it might be a mangled message;
- * treat it as no anyway!
- */
-#ifdef DEBUG
- printf("VF: Abort: someone voted NO\n");
-#endif
- return VFR_ABORT;
- }
-
-#ifdef DEBUG
- printf("VF: YES\n");
-#endif
- --remain;
- }
-
- if (remain) {
-#ifdef DEBUG
- printf("VF: Timed out waiting for %d responses\n", remain);
-#endif
- return VFR_TIMEOUT;
- }
-
-
- /*
- * Whohoooooooo!
- */
- return VFR_OK;
-}
-
-
-/*
- * ...
- */
-static view_node_t *
-vn_new(uint32_t trans, uint32_t nodeid, int viewno, void *data,
- uint32_t datalen)
-{
- view_node_t *new;
- size_t totallen;
-
- totallen = sizeof(*new) + datalen;
- new = malloc(totallen);
- if (!new)
- return NULL;
-
- memset(new,0,totallen);
-
- new->vn_transaction = trans;
- new->vn_nodeid = nodeid;
- new->vn_viewno = viewno;
- new->vn_datalen = datalen;
- memcpy(new->vn_data, data, datalen);
-
- return new;
-}
-
-
-static int
-vn_cmp(view_node_t *left, view_node_t *right)
-{
- if ((left->vn_viewno < right->vn_viewno) ||
- ((left->vn_viewno == right->vn_viewno) &&
- (left->vn_nodeid < right->vn_nodeid)))
- return -1;
-
- /* Equal? ERROR!!! */
- if ((left->vn_viewno == right->vn_viewno) &&
- (left->vn_nodeid == right->vn_nodeid))
- return 0;
-
- return 1;
-}
-
-
-static int
-vn_insert_sorted(view_node_t **head, view_node_t *node)
-{
- view_node_t *cur = *head, *back = NULL;
-
- /* only entry */
- if (!cur) {
- *head = node;
- return 1;
- }
-
- while (cur) {
- switch (vn_cmp(node, cur)) {
- case 0:
- /* duplicate */
- return 0;
- case -1:
- if (back) {
- /* middle */
- node->vn_next = cur;
- back->vn_next = node;
- return 1;
- }
-
- node->vn_next = *head;
- *head = node;
- return 1;
- }
-
- back = cur;
- cur = cur->vn_next;
- }
-
- /* end */
- back->vn_next = node;
- node->vn_next = NULL;
-
- return 1;
-}
-
-
-static view_node_t *
-vn_remove(view_node_t **head, uint32_t trans)
-{
- view_node_t *cur = *head, *back = NULL;
-
- if (!cur)
- return NULL;
-
- do {
- if (cur->vn_transaction == trans) {
- if (back) {
- back->vn_next = cur->vn_next;
- cur->vn_next = NULL;
- return cur;
- }
-
- *head = cur->vn_next;
- cur->vn_next = NULL;
- return cur;
- }
-
- back = cur;
- cur = cur->vn_next;
- } while (cur);
-
- return NULL;
-}
-
-
-/*
- * Buffer a join-view message. We attempt to resolve the buffered join-view
- * messages whenever:
- * (a) we receive a commit message
- * (b) we don't receive any messages.
- */
-static int
-vf_buffer_join_msg(vf_msg_t *hdr, struct timeval *timeout)
-{
- key_node_t *key_node;
- view_node_t *newp;
- int rv = 0;
-
- key_node = kn_find_key(hdr->vm_msg.vf_keyid);
- if (!key_node) {
- printf("Key %s not initialized\n",
- hdr->vm_msg.vf_keyid);
- return 0;
- }
-
- /*
- * Store if the view < viewno.
- */
- if (hdr->vm_msg.vf_view < key_node->kn_viewno) {
- return 0;
- }
-
- newp = vn_new(hdr->vm_msg.vf_transaction, hdr->vm_msg.vf_coordinator,
- hdr->vm_msg.vf_view,
- hdr->vm_msg.vf_data, hdr->vm_msg.vf_datalen);
-
- if (!newp)
- return 0;
-
- if (timeout && (timeout->tv_sec || timeout->tv_usec)) {
- if (getuptime(&newp->vn_timeout) == -1) {
- /* XXX What do we do here? */
- free(newp);
- return 0;
- }
-
- newp->vn_timeout.tv_sec += timeout->tv_sec;
- newp->vn_timeout.tv_usec += timeout->tv_usec;
- }
-
- rv = vn_insert_sorted(&key_node->kn_jvlist, newp);
- if (!rv)
- free(newp);
-
- return rv;
-}
-
-
-/*
- * XXX...
- */
-static int
-vc_cmp(commit_node_t *left, commit_node_t *right)
-{
- if (left->vc_transaction < right->vc_transaction)
- return -1;
-
- if (left->vc_transaction == right->vc_transaction)
- return 0;
-
- return 1;
-}
-
-
-static int
-vc_insert_sorted(commit_node_t **head, commit_node_t *node)
-{
- commit_node_t *cur = *head, *back = NULL;
-
- /* only entry */
- if (!cur) {
- *head = node;
- return 1;
- }
-
- while (cur) {
- switch (vc_cmp(node, cur)) {
- case 0:
- /* duplicate */
- return 0;
- case -1:
- if (back) {
- /* middle */
- node->vc_next = cur;
- back->vc_next = node;
- return 1;
- }
-
- node->vc_next = *head;
- *head = node;
- return 1;
- }
-
- back = cur;
- cur = cur->vc_next;
- }
-
- /* end */
- back->vc_next = node;
- node->vc_next = NULL;
-
- return 1;
-}
-
-
-static commit_node_t *
-vc_remove(commit_node_t **head, uint32_t trans)
-{
- commit_node_t *cur = *head, *back = NULL;
-
- if (!cur)
- return NULL;
-
- do {
- if (cur->vc_transaction == trans) {
- if (back) {
- back->vc_next = cur->vc_next;
- cur->vc_next = NULL;
- return cur;
- }
-
- *head = cur->vc_next;
- cur->vc_next = NULL;
- return cur;
- }
-
- back = cur;
- cur = cur->vc_next;
- } while (cur);
-
- return NULL;
-}
-
-
-/*
- * Buffer a commit message received on a file descriptor. We don't need
- * to know the node id; since the file descriptor will still be open from
- * the last 'join-view' message.
- */
-static int
-vf_buffer_commit(uint32_t trans)
-{
- key_node_t *key_node;
- commit_node_t *newp;
- int rv;
-
- key_node = kn_find_trans(trans);
- if (!key_node)
- return 0;
-
- newp = malloc(sizeof(*newp));
- if (!newp)
- return 0;
-
- newp->vc_next = NULL;
- newp->vc_transaction = trans;
-
- rv = vc_insert_sorted(&key_node->kn_clist, newp);
- if (!rv)
- free(newp);
-
- return rv;
-}
-
-
-static int
-vf_vote_yes(msgctx_t *ctx, uint32_t trans)
-{
- /* XXX */
- return _send_simple(ctx, VF_MESSAGE, VF_VOTE | VFMF_AFFIRM, trans, 0);
-}
-
-
-static int
-vf_vote_no(msgctx_t *ctx, uint32_t trans)
-{
- /* XXX */
- return _send_simple(ctx, VF_MESSAGE, VF_VOTE, trans, 0);
-}
-
-
-static int
-vf_abort(uint32_t trans)
-{
- key_node_t *key_node;
- view_node_t *cur;
-
- key_node = kn_find_trans(trans);
- if (!key_node)
- return -1;
-
- cur = vn_remove(&key_node->kn_jvlist, trans);
- if (!cur)
- return -1;
-
- free(cur);
- return 0;
-}
-
-
-static int
-tv_cmp(struct timeval *left, struct timeval *right)
-{
- if (left->tv_sec > right->tv_sec)
- return 1;
-
- if (left->tv_sec < right->tv_sec)
- return -1;
-
- if (left->tv_usec > right->tv_usec)
- return 1;
-
- if (left->tv_usec < right->tv_usec)
- return -1;
-
- return 0;
-}
-
-
-/**
- * Grab the uptime from /proc/uptime.
- *
- * @param tv Timeval struct to store time in. The sec
- * field contains seconds, the usec field
- * contains the hundredths-of-seconds (converted
- * to micro-seconds)
- * @return -1 on failure, 0 on success.
- */
-int
-getuptime(struct timeval *tv)
-{
- FILE *fp;
- struct timeval junk;
- int rv;
-
- fp = fopen("/proc/uptime","r");
-
- if (!fp)
- return -1;
-
-#if defined(__sparc__)
- rv = fscanf(fp,"%ld.%d %ld.%d\n", &tv->tv_sec, &tv->tv_usec,
- &junk.tv_sec, &junk.tv_usec);
-#else
- rv = fscanf(fp,"%ld.%ld %ld.%ld\n", &tv->tv_sec, &tv->tv_usec,
- &junk.tv_sec, &junk.tv_usec);
-#endif
- fclose(fp);
-
- if (rv != 4) {
- return -1;
- }
-
- tv->tv_usec *= 10000;
-
- return 0;
-}
-
-
-/**
- * Try to commit views in a given key_node.
- */
-static uint32_t
-vf_try_commit(key_node_t *key_node)
-{
- view_node_t *vnp;
- commit_node_t *cmp;
- uint32_t trans = 0;
-
- if (!key_node)
- return 0;
-
- if (!key_node->kn_jvlist)
- return 0;
-
- trans = key_node->kn_jvlist->vn_transaction;
-
- cmp = vc_remove(&key_node->kn_clist, trans);
- if (!cmp) {
- /*printf("VF: Commit for fd%d not received yet!", fd);*/
- return 0;
- }
-
- free(cmp); /* no need for it any longer */
-
- vnp = vn_remove(&key_node->kn_jvlist, trans);
-
-#ifdef DEBUG
- printf("VF: Commit Key %s #%d from member #%d\n",
- key_node->kn_keyid, (int)vnp->vn_viewno, vnp->vn_nodeid);
-#endif
-
- /*
- * Store the current view of everything in our key node
- */
- key_node->kn_viewno = vnp->vn_viewno;
- if (key_node->kn_data)
- free(key_node->kn_data);
- key_node->kn_datalen = vnp->vn_datalen;
- key_node->kn_data = malloc(vnp->vn_datalen);
-
- /*
- * Need to check return of malloc always
- */
- if (key_node->kn_data == NULL) {
- fprintf (stderr, "malloc fail err=%d\n", errno);
- key_node->kn_datalen = 0;
- return -1;
- }
-
- memcpy(key_node->kn_data, vnp->vn_data, vnp->vn_datalen);
-
- free(vnp);
- return trans;
-}
-
-
-static void
-vf_event_loop(msgctx_t *ctx, int my_node_id)
-{
- int n;
- generic_msg_hdr *hdrp = NULL;
-
- if (msg_wait(ctx, 3) != 0) {
-
- n = msg_receive_simple(ctx, &hdrp, 2);
-
- if (n <= 0 || !hdrp) {
- return;
- }
-
- swab_generic_msg_hdr(hdrp);
- if (hdrp->gh_command == VF_MESSAGE &&
- hdrp->gh_arg1 != VF_CURRENT) {
- if (vf_process_msg(ctx, 0, hdrp, n) == VFR_COMMIT) {
-#ifdef DEBUG
- printf("VFT: View committed\n");
-#endif
- }
- }
-
- if (hdrp) {
- free(hdrp);
- hdrp = NULL;
- }
- }
-}
-
-
-static void
-vf_wait_ready(void)
-{
- pthread_mutex_lock(&vf_mutex);
- while (!vf_thread_ready) {
- pthread_mutex_unlock(&vf_mutex);
- usleep(50000);
- pthread_mutex_lock(&vf_mutex);
- }
- pthread_mutex_unlock(&vf_mutex);
-}
-
-
-static void *
-vf_server(void *arg)
-{
- int my_node_id;
- uint16_t port;
- key_node_t *cur;
- uint32_t trans;
- msgctx_t *ctx;
-
- block_all_signals();
-
- port = ((struct vf_args *)arg)->port;
- my_node_id = ((struct vf_args *)arg)->local_node_id;
- ctx = ((struct vf_args *)arg)->ctx;
- free(arg);
-
-#ifdef DEBUG
- printf("VFT: Thread id %ld starting\n", (long)pthread_self());
-#endif
-
- pthread_mutex_lock(&vf_mutex);
- vf_thread_ready = 1;
- pthread_mutex_unlock(&vf_mutex);
-
- while (vf_thread_ready) {
- pthread_mutex_lock(&key_list_mutex);
- for (cur = key_list; cur; cur = cur->kn_next) {
- /* Destroy timed-out join views */
- while (_vf_purge(cur, &trans) != VFR_NO);
- }
- pthread_mutex_unlock(&key_list_mutex);
- vf_event_loop(ctx, my_node_id);
- }
-
- msg_close(ctx);
- msg_free_ctx(ctx);
- pthread_exit(NULL);
-}
-
-
-
-/**
- * Initialize VF. Initializes the View Formation sub system.
- * @param my_node_id The node ID of the caller.
- * @return 0 on success, -1 on failure.
- */
-int
-vf_init(int my_node_id, uint16_t my_port, vf_vote_cb_t vcb,
- vf_commit_cb_t ccb, int _cluster_timeout)
-{
- struct vf_args *args;
- msgctx_t *ctx;
- if (my_node_id == (int)-1)
- return -1;
-
- while((ctx = msg_new_ctx()) == NULL)
- sleep(1);
-
- while((args = malloc(sizeof(*args))) == NULL)
- sleep(1);
-
- if (msg_open(MSG_CLUSTER, 0, my_port, ctx, 1) < 0) {
- msg_free_ctx(ctx);
- free(args);
- return -1;
- }
-
- args->port = my_port;
- args->local_node_id = my_node_id;
- args->ctx = ctx;
-
-
- pthread_mutex_lock(&vf_mutex);
- _port = my_port;
- _node_id = my_node_id;
- if (_cluster_timeout)
- _vf_timeout = _cluster_timeout;
- default_vote_cb = vcb;
- default_commit_cb = ccb;
- pthread_mutex_unlock(&vf_mutex);
-
- pthread_create(&vf_thread, NULL, vf_server, args);
-
- vf_wait_ready();
-
- return 0;
-}
-
-
-int
-vf_invalidate(void)
-{
- key_node_t *c_key;
- view_node_t *c_jv;
- commit_node_t *c_cn;
-
- pthread_mutex_lock(&key_list_mutex);
-
- while ((c_key = key_list) != NULL) {
-
- while ((c_jv = c_key->kn_jvlist) != NULL) {
- c_key->kn_jvlist = c_jv->vn_next;
- free(c_jv);
- }
-
- while ((c_cn = c_key->kn_clist) != NULL) {
- c_key->kn_clist = c_cn->vc_next;
- free(c_cn);
- }
-
- key_list = c_key->kn_next;
-
- if (c_key->kn_data)
- free(c_key->kn_data);
- free(c_key->kn_keyid);
- free(c_key);
- }
-
- pthread_mutex_unlock(&key_list_mutex);
- return 0;
-}
-
-
-/**
- Shut down VF
- */
-int
-vf_shutdown(void)
-{
- pthread_mutex_lock(&vf_mutex);
- vf_thread_ready = 0;
- pthread_cancel(vf_thread);
- pthread_join(vf_thread, NULL);
- _port = 0;
- _node_id = (int)-1;
-
- vf_invalidate();
-
- pthread_mutex_unlock(&vf_mutex);
-
- return 0;
-}
-
-
-/**
- * Adds a key to key node list and sets up callback functions.
- *
- * @param keyid The ID of the key to add.
- * @param timeout Amount of time to wait before purging a JOIN_VIEW
- * message from our buffers.
- * @param vote_cb Function to call on a given data set/view number
- * to help decide whether to vote yes or no. This is
- * optional, and DOES NOT obviate the need for VF's
- * decision-making (version/node ID based). Also,
- * the data from the view-node is passed UNCOPIED to
- * the callback function!
- * @param commit_cb Function to call when a key has had one or more
- * commits. Same info applies: the data passed to the
- * callback function is UNCOPIED.
- * @return 0 (always)
- */
-static int
-vf_key_init_nt(const char *keyid, int timeout, vf_vote_cb_t vote_cb,
- vf_commit_cb_t commit_cb)
-{
- key_node_t *newnode = NULL;
-
- newnode = kn_find_key(keyid);
- if (newnode) {
- printf("Key %s already initialized\n", keyid);
- return -1;
- }
-
- newnode = malloc(sizeof(*newnode));
-
- if (newnode == NULL) {
- fprintf(stderr, "malloc fail3 err=%d\n", errno);
- return -1;
- }
-
- newnode->kn_data = NULL;
- memset(newnode,0,sizeof(*newnode));
- newnode->kn_keyid = strdup(keyid);
-
- /* Set up callbacks */
- if (vote_cb)
- newnode->kn_vote_cb = vote_cb;
- else
- newnode->kn_vote_cb = default_vote_cb;
-
- if (commit_cb)
- newnode->kn_commit_cb = commit_cb;
- else
- newnode->kn_commit_cb = default_commit_cb;
-
- if (timeout < VF_COMMIT_TIMEOUT_MIN) {
- /* Join View message timeout must exceed the
- coordinator timeout */
- timeout = VF_COMMIT_TIMEOUT_MIN;
- }
- newnode->kn_tsec = timeout;
-
- newnode->kn_next = key_list;
- key_list = newnode;
-
- return 0;
-}
-
-
-int
-vf_key_init(const char *keyid, int timeout, vf_vote_cb_t vote_cb,
- vf_commit_cb_t commit_cb)
-{
- int rv;
-
- pthread_mutex_lock(&key_list_mutex);
- rv = vf_key_init_nt(keyid, timeout, vote_cb, commit_cb);
- pthread_mutex_unlock(&key_list_mutex);
-
- return 0;
-}
-
-
-static vf_msg_t *
-build_vf_data_message(int cmd, const char *keyid, const void *data,
- uint32_t datalen, int viewno, int trans,
- uint32_t *retlen)
-{
- uint32_t totallen;
- vf_msg_t *msg;
- /*
- * build the message
- */
- totallen = sizeof(vf_msg_t) + datalen;
- msg = malloc(totallen);
- *retlen = 0;
- if (!msg)
- return NULL;
- memset(msg, 0, totallen);
-
- /* header */
- msg->vm_hdr.gh_magic = GENERIC_HDR_MAGIC;
- msg->vm_hdr.gh_length = totallen;
- msg->vm_hdr.gh_command = VF_MESSAGE;
- msg->vm_hdr.gh_arg1 = cmd;
-
- /* Data */
- strncpy(msg->vm_msg.vf_keyid,keyid,sizeof(msg->vm_msg.vf_keyid));
- msg->vm_msg.vf_transaction = trans;
- msg->vm_msg.vf_datalen = datalen;
- msg->vm_msg.vf_coordinator = _node_id;
- msg->vm_msg.vf_view = viewno;
- memcpy(msg->vm_msg.vf_data, data, datalen);
-
- *retlen = totallen;
- return msg;
-}
-
-
-/**
- * Begin VF. Begins View-Formation for agiven set of data.
- *
- * @param membership Current membership.
- * @param flags Operational flags.
- * @param keyid Key ID of the data to distribute.
- * @param data The actual data to distribute.
- * @param datalen The length of the data.
- * @param viewno The current view number of the data.
- * @param block Block until completion?
- * @return -1 on failure, or 0 on success. The parent will
- * either get a SIGCHLD or can randomly call vf_end()
- * on keyid to cause the VF child to be cleaned up.
- * @see vf_end
- */
-int
-vf_write(cluster_member_list_t *membership, uint32_t flags,
- const char *keyid, const void *data, uint32_t datalen)
-{
- msgctx_t everyone;
- key_node_t *key_node;
- vf_msg_t *join_view;
- int remain = 0, x, y, rv = VFR_ERROR;
- uint32_t totallen;
-#ifdef DEBUG
- struct timeval start, end, dif;
-#endif
- struct dlm_lksb lockp;
- int l;
- char lock_name[256];
- static uint32_t trans = 0;
-
- if (!data || !datalen || !keyid || !strlen(keyid) || !membership)
- return -1;
-
- pthread_mutex_lock(&vf_mutex);
- if (!trans) {
- trans = _node_id << 16;
- }
- ++trans;
-
- /* Obtain cluster lock on it. */
- snprintf(lock_name, sizeof(lock_name), "usrm::vf");
- l = clu_lock(LKM_EXMODE, &lockp, 0, lock_name);
- if (l < 0) {
- pthread_mutex_unlock(&vf_mutex);
- return l;
- }
-
-#ifdef DEBUG
- getuptime(&start);
-#endif
-
- remain = 0;
- for (x = 0, y = 0; x < membership->cml_count; x++) {
- if (membership->cml_members[x].cn_member) {
- remain++;
- }
- }
-
-#ifdef DEBUG
- printf("Allright, need responses from %d members\n", remain);
-#endif
-
- pthread_mutex_lock(&key_list_mutex);
- key_node = kn_find_key(keyid);
- if (!key_node) {
-
- if ((vf_key_init_nt(keyid, 10, NULL, NULL) < 0)) {
- pthread_mutex_unlock(&key_list_mutex);
- clu_unlock(&lockp);
- pthread_mutex_unlock(&vf_mutex);
- return -1;
- }
- key_node = kn_find_key(keyid);
- assert(key_node);
- }
-
- join_view = build_vf_data_message(VF_JOIN_VIEW, keyid, data, datalen,
- key_node->kn_viewno+1, trans, &totallen);
-
- pthread_mutex_unlock(&key_list_mutex);
-
- if (!join_view) {
- clu_unlock(&lockp);
- pthread_mutex_unlock(&vf_mutex);
- return -1;
- }
-
-#ifdef DEBUG
- printf("VF: Push %d.%d #%d (X#%08x)\n", (int)_node_id, getpid(),
- (int)join_view->vm_msg.vf_view, trans);
-#endif
- /*
- * Encode the package.
- */
- swab_vf_msg_t(join_view);
-
- /*
- * Send our message to everyone
- */
- if (msg_open(MSG_CLUSTER, 0, _port, &everyone, 0) < 0) {
- printf("msg_open: fail: %s\n", strerror(errno));
- free(join_view);
- clu_unlock(&lockp);
- pthread_mutex_unlock(&vf_mutex);
- return -1;
- }
-
- x = msg_send(&everyone, join_view, totallen);
- if (x < totallen) {
- vf_send_abort(&everyone, trans);
-#ifdef DEBUG
- printf("VF: Aborted: Send failed (%d/%d)\n", x, totallen);
-#endif
- msg_close(&everyone);
- free(join_view);
- clu_unlock(&lockp);
- pthread_mutex_unlock(&vf_mutex);
- return -1;
- }
-
-#ifdef DEBUG
- printf("VF: Checking for consensus...\n");
-#endif
- /*
- * See if we have a consensus =)
- */
- if ((rv = (vf_unanimous(&everyone, trans, remain,
- _vf_timeout))) == VFR_OK) {
- vf_send_commit(&everyone, trans);
-#ifdef DEBUG
- printf("VF: Consensus reached!\n");
-#endif
- } else {
- vf_send_abort(&everyone, trans);
-#ifdef DEBUG
- printf("VF: Aborted!\n");
-#endif
- }
-
- /*
- * unanimous returns 1 for true; 0 for false, so negate it and
- * return our value...
- */
- msg_close(&everyone);
- free(join_view);
- clu_unlock(&lockp);
- pthread_mutex_unlock(&vf_mutex);
-
-#ifdef DEBUG
- if (rv == VFR_OK) {
- getuptime(&end);
-
- dif.tv_usec = end.tv_usec - start.tv_usec;
- dif.tv_sec = end.tv_sec - start.tv_sec;
-
- if (dif.tv_usec < 0) {
- dif.tv_usec += 1000000;
- dif.tv_sec--;
- }
-
- printf("VF: Converge Time: %d.%06d\n", (int)dif.tv_sec,
- (int)dif.tv_usec);
- }
-#endif
-
- return rv;
-}
-
-
-/**
- * Purge an unresolved JOIN-VIEW message if it has expired. This only
- * purges a single message; if used, it should be called in a while()
- * loop. The function returns a file descriptor which can be closed and
- * cleaned up by the caller if a request has indeed timed out. Also,
- * if a request has timed out, the function calls vf_resolve_views to try
- * to resolve any outstanding views which were opened up by the timed-out
- * request.
- *
- * @param keyid Key ID on which to purge timeouts.
- * @param fd Pointer which, upon return, will either contain -1
- * whenever VFR_NO is the return value, or the file
- * descriptor which was resolved.
- * @return VFR_ERROR on error. VFR_NO if there are no timed-out
- * requests, or if there are no requests at all, or if
- * keyid isn't valid. VFR_OK if there are timed-out
- * requests and the virtue of removing the timed-out
- * requests did not cause commit-resolution, or
- * VFR_COMMIT if new views were committed.
- */
-static int
-_vf_purge(key_node_t *key_node, uint32_t *trans)
-{
- view_node_t *cur, *dead = NULL;
- struct timeval tv;
-
- *trans = 0;
-
- if (!key_node)
- return VFR_NO;
-
- cur = key_node->kn_jvlist;
- if (!cur)
- return VFR_NO;
-
- if (getuptime(&tv) == -1) {
- fprintf(stderr,"VF: getuptime(): %s\n", strerror(errno));
- return VFR_ERROR;
- }
-
- for (; cur; cur = cur->vn_next) {
- if (tv_cmp(&tv, &cur->vn_timeout) < 0)
- continue;
-
- *trans = cur->vn_transaction;
- dead = vn_remove(&key_node->kn_jvlist, *trans);
- free(dead);
-
- printf("VF: Killed transaction %08x\n", *trans);
- /*
- * returns the removed associated file descriptor
- * so that we can close it and get on with life
- */
- break;
- }
-
- if (*trans == 0)
- return VFR_NO;
-
- if (vf_resolve_views(key_node))
- return VFR_COMMIT;
- return VFR_OK;
-}
-
-
-/**
- * Process a VF message.
- *
- * @param nodeid Node id from which msgp was received.
- * @param msgp Pointer to already-received message.
- * @param nbytes Length of msgp.
- * @return -1 on failure, 0 on success.
- */
-int
-vf_process_msg(msgctx_t *ctx, int nodeid, generic_msg_hdr *msgp, int nbytes)
-{
- vf_msg_t *hdrp;
- int ret;
- key_node_t *kn;
-
- if ((nbytes <= 0) || (nbytes < sizeof(generic_msg_hdr)) ||
- (msgp->gh_command != VF_MESSAGE))
- return VFR_ERROR;
-
- switch(vf_command(msgp->gh_arg1)) {
- case VF_CURRENT:
-#ifdef DEBUG
- printf("VF: Received request for current data\n");
-#endif
-
- /* Validate size... */
- if (nbytes < sizeof(*hdrp)) {
- fprintf(stderr, "VF: JOIN_VIEW message too short!\n");
- return VFR_ERROR;
- }
-
- hdrp = (vf_msg_t *)msgp;
- swab_vf_msg_info_t(&hdrp->vm_msg);
-
- return vf_send_current(ctx, hdrp->vm_msg.vf_keyid);
-
- case VF_JOIN_VIEW:
- /* Validate size... */
- if (nbytes < sizeof(*hdrp)) {
- fprintf(stderr, "VF: JOIN_VIEW message too short!\n");
- return VFR_ERROR;
- }
-
- /* Unswap so we can swab the whole message */
- hdrp = (vf_msg_t *)msgp;
- swab_vf_msg_info_t(&hdrp->vm_msg);
-
- if ((hdrp->vm_msg.vf_datalen + sizeof(*hdrp)) != nbytes) {
- fprintf(stderr, "VF: JOIN_VIEW: Invalid size %d/%d\n",
- nbytes, hdrp->vm_msg.vf_datalen +
- (uint32_t)sizeof(*hdrp));
-
- return VFR_ERROR;
- }
- return vf_handle_join_view_msg(ctx, nodeid, hdrp);
-
- case VF_ABORT:
- printf("VF: Received VF_ABORT (X#%08x)\n", msgp->gh_arg2);
- vf_abort(msgp->gh_arg2);
- return VFR_ABORT;
-
- case VF_VIEW_FORMED:
-#ifdef DEBUG
- printf("VF: Received VF_VIEW_FORMED, %d\n",
- nodeid);
-#endif
- pthread_mutex_lock(&key_list_mutex);
- vf_buffer_commit(msgp->gh_arg2);
- kn = kn_find_trans(msgp->gh_arg2);
- if (!kn) {
- pthread_mutex_unlock(&key_list_mutex);
- return VFR_OK;
- }
-
- ret = (vf_resolve_views(kn) ? VFR_COMMIT : VFR_OK);
- pthread_mutex_unlock(&key_list_mutex);
- return ret;
-
- default:
- /* Ignore votes and the like from this part */
- break;
- }
-
- return VFR_OK;
-}
-
-
-/**
- * Retrieves the current dataset for a given key ID.
- *
- * @param keyid Key ID of data set to retrieve.
- * @param view Pointer which will be filled with the current data
- * set's view number.
- * @param data Pointer-to-pointer which will be allocated and
- * filled with the current data set. Caller must free.
- * @param datalen Pointer which will be filled with the current data
- * set's size.
- * @return -1 on failure, 0 on success.
- */
-int
-vf_read(cluster_member_list_t *membership, const char *keyid, uint64_t *view,
- void **data, uint32_t *datalen)
-{
- key_node_t *key_node;
- char lock_name[256];
- struct dlm_lksb lockp;
- int l;
-
- /* Obtain cluster lock on it. */
- pthread_mutex_lock(&vf_mutex);
- snprintf(lock_name, sizeof(lock_name), "usrm::vf");
- l = clu_lock(LKM_EXMODE, &lockp, 0, lock_name);
- if (l < 0) {
- pthread_mutex_unlock(&vf_mutex);
- return l;
- }
-
- do {
- pthread_mutex_lock(&key_list_mutex);
-
- key_node = kn_find_key(keyid);
- if (!key_node) {
- if ((vf_key_init_nt(keyid, 10, NULL, NULL) < 0)) {
- pthread_mutex_unlock(&key_list_mutex);
- clu_unlock(&lockp);
- pthread_mutex_unlock(&vf_mutex);
- printf("Couldn't locate %s\n", keyid);
- return VFR_ERROR;
- }
-
- key_node = kn_find_key(keyid);
- assert(key_node);
- }
-
- /* XXX Don't allow reads during commits. */
- if (key_node->kn_jvlist || key_node->kn_clist) {
- pthread_mutex_unlock(&key_list_mutex);
- usleep(10000);
- continue;
- }
- } while (0);
-
- if (!key_node->kn_data || !key_node->kn_datalen) {
- pthread_mutex_unlock(&key_list_mutex);
-
- if (!membership) {
- clu_unlock(&lockp);
- //printf("Membership NULL, can't find %s\n", keyid);
- pthread_mutex_unlock(&vf_mutex);
- return VFR_ERROR;
- }
-
- l = vf_request_current(membership, keyid, view, data,
- datalen);
- if (l == VFR_NODATA || l == VFR_ERROR) {
- clu_unlock(&lockp);
- //printf("Requesting current failed %s %d\n", keyid, l);
- pthread_mutex_unlock(&vf_mutex);
- return l;
- }
-
- pthread_mutex_lock(&key_list_mutex);
- }
-
- if (key_node->kn_datalen && key_node->kn_data) {
- *data = malloc(key_node->kn_datalen);
- if (! *data) {
- pthread_mutex_unlock(&key_list_mutex);
- clu_unlock(&lockp);
- pthread_mutex_unlock(&vf_mutex);
- printf("Couldn't malloc %s\n", keyid);
- return VFR_ERROR;
- }
-
- memcpy(*data, key_node->kn_data, key_node->kn_datalen);
- } else {
- *data = NULL;
- }
- *datalen = key_node->kn_datalen;
- *view = key_node->kn_viewno;
-
- pthread_mutex_unlock(&key_list_mutex);
- clu_unlock(&lockp);
- pthread_mutex_unlock(&vf_mutex);
-
- return VFR_OK;
-}
-
-
-int
-vf_read_local(const char *keyid, uint64_t *view, void **data, uint32_t *datalen)
-{
- key_node_t *key_node = NULL;
-
- pthread_mutex_lock(&vf_mutex);
- pthread_mutex_lock(&key_list_mutex);
-
- key_node = kn_find_key(keyid);
- if (!key_node) {
- pthread_mutex_unlock(&key_list_mutex);
- pthread_mutex_unlock(&vf_mutex);
- printf("no key for %s\n", keyid);
- return VFR_NODATA;
- }
-
- if (!key_node->kn_data || !key_node->kn_datalen) {
- pthread_mutex_unlock(&key_list_mutex);
- pthread_mutex_unlock(&vf_mutex);
- return VFR_NODATA;
- }
-
- *data = malloc(key_node->kn_datalen);
- if (! *data) {
- pthread_mutex_unlock(&key_list_mutex);
- pthread_mutex_unlock(&vf_mutex);
- printf("Couldn't malloc %s\n", keyid);
- return VFR_ERROR;
- }
-
- memcpy(*data, key_node->kn_data, key_node->kn_datalen);
- *datalen = key_node->kn_datalen;
- *view = key_node->kn_viewno;
-
- pthread_mutex_unlock(&key_list_mutex);
- pthread_mutex_unlock(&vf_mutex);
-
- return VFR_OK;
-}
-
-
-static int
-vf_send_current(msgctx_t *ctx, const char *keyid)
-{
- key_node_t *key_node;
- vf_msg_t *msg;
- int ret;
- uint32_t totallen;
-
- if (!ctx || ctx->type == -1)
- return VFR_ERROR;
-
- pthread_mutex_lock(&key_list_mutex);
-
- key_node = kn_find_key(keyid);
- if (!key_node || !key_node->kn_data || !key_node->kn_datalen) {
- pthread_mutex_unlock(&key_list_mutex);
- printf("VFT: No data for keyid %s\n", keyid);
- return (_send_simple(ctx, VF_NACK, 0, 0, 0) != -1)?
- VFR_OK : VFR_ERROR;
- }
-
- /*
- * XXX check for presence of nodes on the commit lists; send
- * VF_AGAIN if there is any.
- */
- msg = build_vf_data_message(VF_ACK, keyid, key_node->kn_data,
- key_node->kn_datalen,
- key_node->kn_viewno,
- 0,
- &totallen);
-
- pthread_mutex_unlock(&key_list_mutex);
- if (!msg)
- return (_send_simple(ctx, VFR_ERROR, 0, 0, 0) != -1)?
- VFR_OK : VFR_ERROR;
-
- swab_vf_msg_t(msg);
- ret = (msg_send(ctx, msg, totallen) >= 0)?VFR_OK:VFR_ERROR;
- free(msg);
- return ret;
-}
-
-
-static int
-vf_set_current(const char *keyid, int view, void *data, uint32_t datalen)
-{
- key_node_t *key_node;
- void *datatmp;
-
- pthread_mutex_lock(&key_list_mutex);
-
- key_node = kn_find_key(keyid);
- if (!key_node) {
- pthread_mutex_unlock(&key_list_mutex);
- return VFR_ERROR;
- }
-
- datatmp = malloc(datalen);
- if (! datatmp) {
- pthread_mutex_unlock(&key_list_mutex);
- return VFR_ERROR;
- }
-
- if (key_node->kn_data) {
- free(key_node->kn_data);
- key_node->kn_data = NULL;
- }
-
- key_node->kn_data = datatmp;
- memcpy(key_node->kn_data, data, datalen);
- key_node->kn_datalen = datalen;
- key_node->kn_viewno = view;
-
- pthread_mutex_unlock(&key_list_mutex);
-
- return VFR_OK;
-}
-
-
-/**
- * Request the current state of a keyid from the membership.
- * XXX This doesn't wait for outstanding transactions to complete.
- * Perhaps it should.
- *
- * @param membership Membership mask.
- * @param keyid VF key id (application-defined).
- * @param viewno Return view number. Passed in pre-allocated.
- * @param data Return data pointer. Allocated within.
- * @param datalen Size of data returned.
- */
-static int
-vf_request_current(cluster_member_list_t *membership, const char *keyid,
- uint64_t *viewno, void **data, uint32_t *datalen)
-{
- int x, n, rv = VFR_OK, port;
- msgctx_t ctx;
- vf_msg_t rmsg;
- vf_msg_t *msg = &rmsg;
- generic_msg_hdr * gh;
- int me;
-
- if (_port == 0) {
- return -1;
- }
-
- port = _port;
- me = _node_id;
-
- memset(msg, 0, sizeof(*msg));
- msg->vm_hdr.gh_magic = GENERIC_HDR_MAGIC;
- msg->vm_hdr.gh_length = sizeof(*msg);
- msg->vm_hdr.gh_command = VF_MESSAGE;
- msg->vm_hdr.gh_arg1 = VF_CURRENT;
- strncpy(msg->vm_msg.vf_keyid, keyid,
- sizeof(msg->vm_msg.vf_keyid));
-
- swab_generic_msg_hdr(&(msg->vm_hdr));
- swab_vf_msg_info_t(&(msg->vm_msg));
-
- for (x = 0; x < membership->cml_count; x++) {
- if (!membership->cml_members[x].cn_member)
- continue;
-
- /* Can't request from self. */
- if (membership->cml_members[x].cn_nodeid == me)
- continue;
-
- rv = VFR_ERROR;
- if (msg_open(MSG_CLUSTER,
- membership->cml_members[x].cn_nodeid,
- port, &ctx, 15) < 0) {
- continue;
- }
-
- msg = &rmsg;
- //printf("VF: Requesting current value of %s from %d\n",
- //msg->vm_msg.vf_keyid,
- //(int)membership->cml_members[x].cn_nodeid);
-
- if (msg_send(&ctx, msg, sizeof(*msg)) < sizeof(*msg)) {
- printf("Couldn't send entire message\n");
- msg_close(&ctx);
- continue;
- }
-
- gh = NULL;
- if ((n = msg_receive_simple(&ctx, (generic_msg_hdr **)&gh, 10))
- < 0) {
- if (gh)
- free(gh);
- msg_close(&ctx);
- continue;
- }
- msg_close(&ctx);
- msg = (vf_msg_t *)gh;
-
- /* Uh oh */
- if (!msg || (msg == &rmsg)) {
- printf("VF: No valid message\n");
- return VFR_ERROR;
- }
- swab_generic_msg_hdr(&(msg->vm_hdr));
- if (msg->vm_hdr.gh_command == VF_NACK) {
- free(msg);
- continue;
- }
- if (msg->vm_hdr.gh_length < sizeof(vf_msg_t)) {
- fprintf(stderr, "VF: Short reply from %d\n", x);
- free(msg);
- continue;
- }
- if (msg->vm_hdr.gh_length > n) {
- fprintf(stderr,
- "VF: Size mismatch during decode (%d > %d)\n",
- msg->vm_hdr.gh_length, n);
- free(msg);
- continue;
- }
-
- swab_vf_msg_info_t(&(msg->vm_msg));
-
- if (msg->vm_msg.vf_datalen != (n - sizeof(*msg))) {
- fprintf(stderr,"VF: Size mismatch during decode (\n");
- free(msg);
- continue;
- }
-
- /* Ok... we've got data! */
- if (vf_set_current(keyid, msg->vm_msg.vf_view,
- msg->vm_msg.vf_data,
- msg->vm_msg.vf_datalen) == VFR_ERROR) {
- free(msg);
- return VFR_ERROR;
- }
-
- free(msg);
-
- return VFR_OK;
- }
-
- return VFR_NODATA;
-}
-
-
-void
-dump_vf_states(FILE *fp)
-{
- key_node_t *cur;
-
- fprintf(fp, "View-Formation States:\n");
- fprintf(fp, " Thread: %d\n", (unsigned)vf_thread);
- fprintf(fp, " Default callbacks:\n Vote: %p\n Commit: %p\n",
- default_vote_cb, default_commit_cb);
- fprintf(fp, " Distributed key metadata:\n");
-
- pthread_mutex_lock(&key_list_mutex);
-
- for (cur = key_list; cur; cur = cur->kn_next) {
- fprintf(fp, " %s, View: %d, Size: %d, Address: %p\n",
- cur->kn_keyid,
- (int)cur->kn_viewno,
- cur->kn_datalen,
- cur->kn_data);
- if (cur->kn_vote_cb != default_vote_cb)
- fprintf(fp, " Vote callback: %p\n", cur->kn_vote_cb);
- if (cur->kn_commit_cb != default_commit_cb)
- fprintf(fp, " Commit callback: %p\n", cur->kn_commit_cb);
-
- if (cur->kn_jvlist)
- fprintf(fp, " This key has unresolved "
- "new views pending\n");
- if (cur->kn_clist)
- fprintf(fp, " This key has unresolved "
- "commits pending\n");
-
- }
-
- pthread_mutex_unlock(&key_list_mutex);
- fprintf(fp, "\n");
-}
diff --git a/rgmanager/src/clulib/wrap_lock.c b/rgmanager/src/clulib/wrap_lock.c
deleted file mode 100644
index 0bd47e6..0000000
--- a/rgmanager/src/clulib/wrap_lock.c
+++ /dev/null
@@ -1,205 +0,0 @@
-#ifdef WRAP_LOCKS
-#include <stdio.h>
-#include <sys/types.h>
-#include <gettid.h>
-#include <pthread.h>
-#include <string.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-
-int __real_pthread_mutex_lock(pthread_mutex_t *lock);
-int
-__wrap_pthread_mutex_lock(pthread_mutex_t *lock)
-{
- int status;
- struct timespec delay;
-
- while (1) {
- status = __real_pthread_mutex_lock(lock);
-
- switch(status) {
- case EDEADLK:
- /* Already own it: Note the error, but continue */
- fprintf(stderr, "[%d] %s(%p): %s; continuing\n",
- gettid(),
- __FUNCTION__, lock, strerror(status));
- /* deliberate fallthrough */
- case 0:
- return 0;
- case EBUSY:
- /* Try again */
- break;
- default:
- /* Other return codes */
- fprintf(stderr, "[%d] %s(%p): %s\n", gettid(),
- __FUNCTION__, lock, strerror(status));
- raise(SIGSEGV);
- /* EINVAL? */
- return 0;
- }
-
- delay.tv_sec = 0;
- delay.tv_nsec = 100000;
- nanosleep(&delay, NULL);
- }
-
- /* Not reached */
- return 0;
-}
-
-
-int __real_pthread_mutex_unlock(pthread_mutex_t *lock);
-int
-__wrap_pthread_mutex_unlock(pthread_mutex_t *lock)
-{
- int status;
- struct timespec delay;
-
- while (1) {
- status = __real_pthread_mutex_unlock(lock);
-
- switch(status) {
- case EPERM:
- /* Don't own it: Note the error, but continue */
- fprintf(stderr, "[%d] %s(%p): %s; continuing\n",
- gettid(),
- __FUNCTION__, lock, strerror(status));
- /* deliberate fallthrough */
- case 0:
- return 0;
- default:
- fprintf(stderr, "[%d] %s(%p): %s\n", gettid(),
- __FUNCTION__, lock, strerror(status));
- raise(SIGSEGV);
- return 0;
- }
-
- delay.tv_sec = 0;
- delay.tv_nsec = 100000;
- nanosleep(&delay, NULL);
- }
-
- /* Not reached */
- return 0;
-}
-
-
-int __real_pthread_rwlock_rdlock(pthread_rwlock_t *lock);
-int
-__wrap_pthread_rwlock_rdlock(pthread_rwlock_t *lock)
-{
- int status;
- struct timespec delay;
-
- while (1) {
- status = __real_pthread_rwlock_rdlock(lock);
-
- switch(status) {
- case EDEADLK:
- /* Already own it: Note the error, but continue */
- fprintf(stderr, "[%d] %s(%p): %s; continuing\n",
- gettid(),
- __FUNCTION__, lock, strerror(status));
- /* deliberate fallthrough */
- case 0:
- return 0;
- case EBUSY:
- /* Try again */
- break;
- default:
- /* Other return codes */
- fprintf(stderr, "[%d] %s(%p): %s\n", gettid(),
- __FUNCTION__, lock, strerror(status));
- raise(SIGSEGV);
- /* EINVAL? */
- return 0;
- }
-
- delay.tv_sec = 0;
- delay.tv_nsec = 100000;
- nanosleep(&delay, NULL);
- }
-
- /* Not reached */
- return 0;
-}
-
-
-int __real_pthread_rwlock_wrlock(pthread_rwlock_t *lock);
-int
-__wrap_pthread_rwlock_wrlock(pthread_rwlock_t *lock)
-{
- int status;
- struct timespec delay;
-
- while (1) {
- status = __real_pthread_rwlock_wrlock(lock);
-
- switch(status) {
- case EDEADLK:
- /* Already own it: Note the error, but continue */
- fprintf(stderr, "[%d] %s(%p): %s; continuing\n",
- gettid(),
- __FUNCTION__, lock, strerror(status));
- /* deliberate fallthrough */
- case 0:
- return 0;
- case EBUSY:
- /* Try again */
- break;
- default:
- /* Other return codes */
- fprintf(stderr, "[%d] %s(%p): %s\n", gettid(),
- __FUNCTION__, lock, strerror(status));
- raise(SIGSEGV);
- /* EINVAL? */
- return 0;
- }
-
- delay.tv_sec = 0;
- delay.tv_nsec = 100000;
- nanosleep(&delay, NULL);
- }
-
- /* Not reached */
- return 0;
-}
-
-
-int __real_pthread_rwlock_unlock(pthread_rwlock_t *lock);
-int
-__wrap_pthread_rwlock_unlock(pthread_rwlock_t *lock)
-{
- int status;
- struct timespec delay;
-
- while (1) {
- status = __real_pthread_rwlock_unlock(lock);
-
- switch(status) {
- case EPERM:
- /* Don't own it: Note the error, but continue */
- fprintf(stderr, "[%d] %s(%p): %s; continuing\n",
- gettid(),
- __FUNCTION__, lock, strerror(status));
- /* deliberate fallthrough */
- case 0:
- return 0;
- default:
- fprintf(stderr, "[%d] %s(%p): %s\n", gettid(),
- __FUNCTION__, lock, strerror(status));
- raise(SIGSEGV);
- return 0;
- }
-
- delay.tv_sec = 0;
- delay.tv_nsec = 100000;
- nanosleep(&delay, NULL);
- }
-
- /* Not reached */
- return 0;
-}
-#endif
-
diff --git a/rgmanager/src/daemons/Makefile b/rgmanager/src/daemons/Makefile
deleted file mode 100644
index 83bdf93..0000000
--- a/rgmanager/src/daemons/Makefile
+++ /dev/null
@@ -1,137 +0,0 @@
-TARGET1= rgmanager
-TARGET2= rg_test
-TARGET3= clurgmgrd
-TARGET4= cpglockd
-TARGET5= cpglockdump
-TARGET6= test-expand-time
-
-SBINDIRT=$(TARGET1) $(TARGET2) $(TARGET4) $(TARGET5)
-SBINSYMT=$(TARGET3)
-
-all: depends ${TARGET1} ${TARGET2} ${TARGET3} $(TARGET4) $(TARGET5)
-
-include ../../../make/defines.mk
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-OBJS1= fo_domain.o \
- groups.o \
- main.o \
- reslist.o \
- resrules.o \
- restree.o \
- restart_counter.o \
- rg_event.o \
- rg_forward.o \
- rg_locks.o \
- rg_queue.o \
- rg_state.o \
- rg_thread.o \
- service_op.o \
- slang_event.o \
- event_config.o \
- update-dbus.o \
- watchdog.o
-
-OBJS2= test-noccs.o \
- fo_domain-noccs.o \
- restart_counter.o \
- reslist-noccs.o \
- resrules-noccs.o \
- restree-noccs.o \
- rg_locks-noccs.o \
- event_config-noccs.o
-
-OBJS4= cpglockd.o
-
-OBJS5= cpglockdump.o
-
-OBJS6= test-expand-time.o \
- reslist.o \
- resrules.o \
- rg_locks.o
-
-CFLAGS += -DSHAREDIR=\"${sharedir}\" -D_GNU_SOURCE
-CFLAGS += -fPIC
-CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${corosyncincdir}
-CFLAGS += -I${dlmincdir} -I${fencedincdir} -I${logtincdir}
-CFLAGS += `xml2-config --cflags` -I${slangincdir}
-CFLAGS += -I$(S)/../../include
-CFLAGS += -I${incdir}
-
-NOCCS_CFLAGS += -DNO_CCS
-
-LDFLAGS += -L../clulib -lclulib
-LDFLAGS += -L${libdir}
-
-CCS_LDFLAGS += -L${ccslibdir} -lccs
-CMAN_LDFLAGS += -L${cmanlibdir} -lcman
-LOGSYS_LDFLAGS += -L${logtlibdir} -llogthread
-DLM_LDFLAGS += -L${dlmlibdir} -ldlm
-CPG_LDFLAGS += -L${corosynclibdir} -lcpg
-FENCED_LDFLAGS += -L${fencedlibdir} -lfenced
-XML2_LDFLAGS += `xml2-config --libs`
-SLANG_LDFLAGS += -L${slanglibdir} -lslang
-EXTRA_LDFLAGS += -lpthread
-
-# dbus support for notifications
-ifndef disable_dbus
-CFLAGS += -DDBUS `pkg-config --cflags dbus-1`
-DBUS_LDFLAGS += `pkg-config --libs dbus-1`
-endif
-
-LDDEPS += ../clulib/libclulib.a
-
-${TARGET1}: ${OBJS1} ${LDDEPS}
- $(CC) -o $@ $^ $(CCS_LDFLAGS) $(CMAN_LDFLAGS) \
- $(DLM_LDFLAGS) $(XML2_LDFLAGS) \
- $(SLANG_LDFLAGS) $(EXTRA_LDFLAGS) \
- $(LOGSYS_LDFLAGS) $(LD_FLAGS) $(DBUS_LDFLAGS)
-
-#
-# Our test program links against the local allocator so that
-# we can see if our program is leaking memory during XML parsing, tree
-# delta calculations, building/teardown of resource lists, etc.
-# If it's leaking memory, the 'make check' will fail. Also, we can
-# use it to test known-good configurations for regressions.
-#
-# The data in the 'tests' directory is hand-crafted; so running 'gentests.sh'
-# will require that the developer hand-verify the correctness of the
-# resulting output prior to committing back to VCS.
-#
-# This is NOT meant to be an installed binary. Rather, RPMs and/or other
-# packages should run 'make check' as part of the build process.
-#
-${TARGET2}: ${OBJS2} ${LDDEPS}
- $(CC) -o $@ $^ $(CMAN_LDFLAGS) $(EXTRA_LDFLAGS) \
- $(XML2_LDFLAGS) $(LOGSYS_LDFLAGS) $(LDFLAGS)
-
-${TARGET3}: ${TARGET1}
- ln -sf ${TARGET1} ${TARGET3}
-
-${TARGET4}: ${OBJS4} ${LDDEPS}
- $(CC) -o $@ $^ $(CPG_LDFLAGS) $(CMAN_LDFLAGS) $(CCS_LDFLAGS) \
- $(FENCED_LDFLAGS) $(LOGSYS_LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS)
-
-${TARGET5}: ${OBJS5} ${LDDEPS}
- $(CC) -o $@ $^ $(CPG_LDFLAGS)
-
-# This is a test of a specific parsing function; after top-level "configure",
-# compile it locally as "CFLAGS=-DNO_CCS make test-expand-time disable_dbus=1".
-${TARGET6}: ${OBJS6}
- $(CC) -o $@ $^ $(XML2_LDFLAGS)
-
-check: rg_test
- cd tests && ./runtests.sh
-
-depends:
- $(MAKE) -C ../clulib all
-
-clean: generalclean
- rm -f tests/*.out*
-
--include $(OBJS1:.o=.Tpo)
--include $(OBJS2:.o=.Tpo)
--include $(OBJS3:.o=.Tpo)
diff --git a/rgmanager/src/daemons/cpglockd.c b/rgmanager/src/daemons/cpglockd.c
deleted file mode 100644
index 95cb371..0000000
--- a/rgmanager/src/daemons/cpglockd.c
+++ /dev/null
@@ -1,1814 +0,0 @@
-#include <stdio.h>
-#include <signal.h>
-#include <signals.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/select.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <string.h>
-#include <time.h>
-#include <assert.h>
-#include <sys/uio.h>
-
-#include <corosync/cpg.h>
-
-#include <ccs.h>
-#include <libcman.h>
-#include <libfenced.h>
-#include <liblogthread.h>
-
-#include "daemon_init.h"
-#include "sock.h"
-#include "cpglock.h"
-#include "cpglock-internal.h"
-#include "list.h"
-#include "platform.h"
-
-struct request_node {
- list_head();
- struct cpg_lock l;
-};
-
-struct lock_node {
- list_head();
- struct cpg_lock l;
-};
-
-struct pending_fence_node {
- list_head();
- int nodeid;
- int force_wait;
- uint64_t fail_time;
-};
-
-struct client_node {
- list_head();
- int fd;
- int pid;
-};
-
-struct member_node {
- list_head();
- int nodeid;
- uint32_t pid;
-};
-
-struct msg_node {
- list_head();
- struct cpg_lock_msg m;
-};
-
-/* Local vars */
-static cpg_handle_t cpg;
-static uint32_t my_node_id = 0;
-static struct pending_fence_node *pending_fencing = NULL;
-static struct request_node *requests = NULL;
-static struct lock_node *locks = NULL;
-static struct client_node *clients = NULL;
-static struct member_node *group_members = NULL;
-static struct msg_node *messages = NULL;
-static int total_members = 0;
-static int local_lockid = 0;
-static int message_count = 0;
-static int joined = 0;
-static int cluster_quorate = 0;
-static int cman_shutdown_requested = 0;
-static int shutdown_pending = 0;
-static int nofork = 0;
-
-static cman_node_t cman_nodes[CPG_MEMBERS_MAX];
-static int cman_node_count;
-
-static cman_node_t old_cman_nodes[CPG_MEMBERS_MAX];
-static int old_cman_node_count;
-
-static void init_logging(int reconf);
-
-static void
-flag_shutdown(int __attribute__ ((unused)) sig)
-{
- if (clients) {
- logt_print(LOG_INFO, "Clients are connected to cpglockd. Refusing to shutdown\n");
- return;
- }
- shutdown_pending = 1;
-}
-
-
-static int
-is_member(uint32_t nodeid)
-{
- struct member_node *n;
- int x;
-
- list_for(&group_members, n, x) {
- if (n->nodeid == nodeid)
- return 1;
- }
-
- return 0;
-}
-
-
-static int
-cman_nodes_lost(cman_node_t *old_nodes,
- size_t old_node_len,
- cman_node_t *new_nodes,
- size_t new_node_len,
- cman_node_t *lost_nodes,
- size_t lost_nodes_size)
-{
- int i;
- size_t lost_nodes_len = 0;
-
- if (lost_nodes_size < old_node_len) {
- logt_print(LOG_DEBUG, "Lost nodes array smaller than old nodes array");
- return -1;
- }
-
- for (i = 0 ; i < old_node_len ; i++) {
- if (old_nodes[i].cn_member) {
- int present_in_new_list = 0;
- int j;
-
- for (j = 0 ; j < new_node_len ; j++) {
- if (new_nodes[j].cn_nodeid == old_nodes[i].cn_nodeid) {
- present_in_new_list = 1;
- if (!new_nodes[j].cn_member) {
- memcpy(&lost_nodes[lost_nodes_len++],
- &old_nodes[i], sizeof(*lost_nodes));
- break;
- }
- }
- }
-
- if (!present_in_new_list) {
- memcpy(&lost_nodes[lost_nodes_len++],
- &old_nodes[i], sizeof(*lost_nodes));
- }
- }
- }
-
- return lost_nodes_len;
-}
-
-static int
-node_has_fencing(int nodeid)
-{
- int ccs_desc;
- char *val = NULL;
- char buf[1024];
- int ret = 1;
-
- ccs_desc = ccs_connect();
- if (ccs_desc < 0) {
- logt_print(LOG_DEBUG, "Unable to connect to ccsd\n");
- /* Assume node has fencing */
- return 1;
- }
-
- snprintf(buf, sizeof(buf),
- "/cluster/clusternodes/clusternode[@nodeid=\"%d\"]"
- "/fence/method/device/@name", nodeid);
-
- if (ccs_get(ccs_desc, buf, &val) != 0)
- ret = 0;
- if (val)
- free(val);
- ccs_disconnect(ccs_desc);
- return ret;
-}
-
-static int
-fence_domain_joined(void) {
- int ret;
- struct fenced_node fn;
-
- ret = fenced_node_info(FENCED_NODEID_US, &fn);
- if (ret < 0) {
- logt_print(LOG_DEBUG, "Unable to determine fence domain membership\n");
- return 0;
- }
-
- return fn.member;
-}
-
-static void
-cman_callback(cman_handle_t ch, void *privdata, int reason, int arg)
-{
- if (reason == CMAN_REASON_STATECHANGE) {
- int i;
- int ret;
- int nl;
- time_t cur_time = time(NULL);
- size_t nodes_elem = sizeof(cman_nodes) / sizeof(cman_nodes[0]);
- cman_node_t lost_nodes[nodes_elem];
-
- cluster_quorate = arg;
-
- memcpy(&old_cman_nodes, &cman_nodes, sizeof(old_cman_nodes));
- old_cman_node_count = cman_node_count;
-
- memset(&cman_nodes, 0, sizeof(cman_nodes));
- cman_node_count = 0;
-
- ret = cman_get_nodes(ch, nodes_elem, &cman_node_count, cman_nodes);
- if (ret < 0) {
- logt_print(LOG_DEBUG, "Unable to get cman nodes list\n");
- return;
- }
-
- nl = cman_nodes_lost(old_cman_nodes, old_cman_node_count,
- cman_nodes, cman_node_count, lost_nodes, nodes_elem);
- if (nl < 0) {
- logt_print(LOG_DEBUG, "Unable to get list of lost nodes");
- return;
- }
-
- for (i = 0 ; i < nl ; i++) {
- int cur_nodeid = lost_nodes[i].cn_nodeid;
-
- if (node_has_fencing(cur_nodeid)) {
- struct pending_fence_node *pf;
-
- logt_print(LOG_DEBUG, "Lost node %d\n", cur_nodeid);
- pf = do_alloc(sizeof(*pf));
- pf->nodeid = cur_nodeid;
- pf->fail_time = cur_time;
- /*
- ** If the node is also a member of the cpglock group, wait
- ** for positive confirmation from fenced that it was fenced.
- ** It cannot have shut down cleanly if we did not process a
- ** DELETE for it yet.
- */
- if (is_member(cur_nodeid))
- pf->force_wait = 1;
- list_append(&pending_fencing, pf);
- } else {
- logt_print(LOG_DEBUG, "Lost node %d but fencing not configured\n",
- cur_nodeid);
- }
- }
- } else if (reason == CMAN_REASON_TRY_SHUTDOWN) {
- cman_shutdown_requested = 1;
- } else if (reason == CMAN_REASON_CONFIG_UPDATE) {
- init_logging(1);
- }
-}
-
-static void
-wait_for_fencing_join(int nodeid)
-{
- if (node_has_fencing(nodeid)) {
- logt_print(LOG_DEBUG, "Waiting for fence domain join operation to complete\n");
- while (!shutdown_pending && !fence_domain_joined())
- sleep(1);
- logt_print(LOG_DEBUG, "Fence domain joined\n");
- } else
- logt_print(LOG_DEBUG, "No fencing is configured, not waiting\n");
-}
-
-static void
-wait_for_quorum_formation(cman_handle_t ch) {
- while (!shutdown_pending && !(cluster_quorate = cman_is_quorate(ch))) {
- logt_print(LOG_DEBUG, "Waiting for quorum to form\n");
- sleep(1);
- }
- logt_print(LOG_DEBUG, "Quorum formed\n");
-}
-
-static int
-cman_connect(cman_handle_t *ch)
-{
- assert(ch != NULL);
-
- *ch = cman_init(NULL);
- if (!*ch) {
- logt_print(LOG_DEBUG, "Waiting for CMAN to start\n");
- while (!shutdown_pending && !(*ch = cman_init(NULL)))
- sleep(1);
- logt_print(LOG_DEBUG, "CMAN started\n");
- }
-
- return 0;
-}
-
-static const char *
-ls2str(int x)
-{
- switch(x){
- case LOCK_FREE: return "FREE";
- case LOCK_HELD: return "HELD";
- case LOCK_PENDING: return "PENDING";
- }
- return "unknown";
-}
-
-
-static const char *
-rq2str(int x)
-{
- switch(x){
- case MSG_LOCK: return "LOCK";
- case MSG_UNLOCK: return "UNLOCK";
- case MSG_GRANT: return "GRANT";
- case MSG_NAK: return "NAK";
- case MSG_PURGE: return "PURGE";
- case MSG_CONFCHG: return "CONFCHG";
- case MSG_JOIN: return "JOIN";
- case MSG_HALT: return "HALT";
- }
- return "unknown";
-}
-
-
-static void
-dump_state(FILE *fp)
-{
- struct request_node *r = NULL;
- struct lock_node *l = NULL;
- struct client_node *c = NULL;
- struct member_node *m = NULL;
- struct msg_node *s = NULL;
- int x;
-
- fprintf(fp, "cpglockd state\n");
- fprintf(fp, "======== =====\n");
-
- fprintf(fp, "Node ID: %d\n", my_node_id);
-
- if (group_members) {
- fprintf(fp, "Participants:");
- list_for(&group_members, m, x) {
- fprintf(fp, " %d.%u", m->nodeid, m->pid);
- }
- fprintf(fp, "\n");
- }
- if (clients) {
- fprintf(fp, "Clients:");
- list_for(&clients, c, x) {
- fprintf(fp, " %d.%d", c->pid, c->fd );
- }
- fprintf(fp, "\n");
- }
- fprintf(fp, "\n");
-
- if (locks) {
- fprintf(fp, "Locks\n");
- fprintf(fp, "=====\n");
- list_for(&locks, l, x) {
- fprintf(fp, " %s: %s", l->l.resource, ls2str(l->l.state));
- if (l->l.owner_nodeid) {
- fprintf(fp, ", owner %d:%d:%d", l->l.owner_nodeid,l->l.owner_pid, l->l.owner_tid);
- if (l->l.owner_nodeid == my_node_id &&
- l->l.state == LOCK_HELD)
- fprintf(fp, ", Local ID %d", l->l.local_id);
- }
- fprintf(fp, "\n");
- }
- fprintf(fp, "\n");
- }
- if (requests) {
- fprintf(fp, "Requests\n");
- fprintf(fp, "========\n");
- list_for(&requests, r, x) {
- fprintf(fp, " %s: %s", r->l.resource, rq2str(r->l.state));
- if (r->l.owner_nodeid) {
- fprintf(fp, ", from %d:%d:%d", r->l.owner_nodeid,r->l.owner_pid, r->l.owner_tid);
- }
- fprintf(fp, "\n");
- }
- fprintf(fp, "\n");
- }
- if (messages) {
- fprintf(fp, "Message History\n");
- fprintf(fp, "======= =======\n");
- list_for(&messages, s, x) {
- switch(s->m.request) {
- case MSG_CONFCHG:
- fprintf(fp, " CONFIG CHANGE\n");
- break;
- case MSG_PURGE:
- fprintf(fp, " PURGE for %d:%d\n", s->m.owner_nodeid, s->m.owner_pid);
- break;
- case MSG_JOIN:
- fprintf(fp, " JOIN %d\n", s->m.owner_nodeid);
- break;
- default:
- fprintf(fp, " %s: %s %d:%d:%d\n", rq2str(s->m.request), s->m.resource, s->m.owner_nodeid, s->m.owner_pid, s->m.owner_tid);
- break;
- }
- }
- fprintf(fp, "\n");
- }
-}
-
-
-static void
-old_msg(struct cpg_lock_msg *m)
-{
- struct msg_node *n;
-
- n = do_alloc(sizeof(*n));
- memcpy(&n->m, m, sizeof(n->m));
- list_append(&messages, n);
- if (message_count < 20) {
- ++message_count;
- } else {
- n = messages;
- list_remove(&messages, n);
- free(n);
- }
-}
-
-
-static void
-insert_client(int fd)
-{
- struct client_node *n = NULL;
-
- n = do_alloc(sizeof(*n));
- n->fd = fd;
- list_append(&clients, n);
-}
-
-static void
-swab_cpg_lock_msg(struct cpg_lock_msg *m)
-{
- swab32(m->request);
- swab32(m->owner_nodeid);
- swab32(m->owner_pid);
- swab32(m->flags);
- swab32(m->lockid);
- swab32(m->owner_tid);
-}
-
-/* forward request from client */
-static int
-send_lock_msg(struct cpg_lock_msg *m)
-{
- struct iovec iov;
- int ret;
- struct cpg_lock_msg out_msg;
-
- memcpy(&out_msg, m, sizeof(out_msg));
- swab_cpg_lock_msg(&out_msg);
-
- iov.iov_base = &out_msg;
- iov.iov_len = sizeof(out_msg);
-
- do {
- ret = cpg_mcast_joined(cpg, CPG_TYPE_AGREED, &iov, 1);
- if (ret != CPG_OK) {
- logt_print(LOG_DEBUG, "send_lock_msg() failed %d: %s\n",
- ret, strerror(errno));
- usleep(250000);
- }
- } while (ret != CPG_OK && !shutdown_pending);
-
- return 0;
-}
-
-
-/* forward request from client */
-static int
-send_lock(struct cpg_lock_msg *m)
-{
- m->owner_nodeid = my_node_id;
-
- return send_lock_msg(m);
-}
-
-
-static int
-send_grant(struct request_node *n)
-{
- struct cpg_lock_msg m;
-
- logt_print(LOG_DEBUG, "-> sending grant %s to %d:%d:%d\n",
- n->l.resource, n->l.owner_nodeid, n->l.owner_pid, n->l.owner_tid);
-
- memset(&m, 0, sizeof(m));
- strncpy(m.resource, n->l.resource, sizeof(m.resource));
- m.request = MSG_GRANT;
- m.owner_nodeid = n->l.owner_nodeid;
- m.owner_pid = n->l.owner_pid;
- m.owner_tid = n->l.owner_tid;
-
- return send_lock_msg(&m);
-}
-
-
-static int
-send_nak(struct cpg_lock_msg *m)
-{
- logt_print(LOG_DEBUG, "-> sending NAK %s to %d:%d:%d\n",
- m->resource, m->owner_nodeid, m->owner_pid, m->owner_tid);
- m->request = MSG_NAK;
-
- return send_lock_msg(m);
-}
-
-
-static int
-send_join(void)
-{
- struct cpg_lock_msg m;
-
- m.request = MSG_JOIN;
- m.owner_nodeid = my_node_id;
- return send_lock_msg(&m);
-}
-
-
-
-static int
-send_unlock(struct cpg_lock_msg *m)
-{
- m->request = MSG_UNLOCK;
- return send_lock_msg(m);
-}
-
-
-/*
- * Grant the lock in this request node to the next
- * waiting client.
- */
-static int
-grant_next(struct cpg_lock_msg *m)
-{
- struct request_node *r;
- int x;
-
- list_for(&requests, r, x) {
- if (strcmp(m->resource, r->l.resource))
- continue;
-
- /* Send grant */
- if (r->l.state == LOCK_PENDING) {
- logt_print(LOG_DEBUG, "LOCK %s: grant to %d:%d:%d\n", m->resource,
- r->l.owner_nodeid, r->l.owner_pid, r->l.owner_tid);
- /* don't send dup grants */
- r->l.state = LOCK_HELD;
- send_grant(r);
- }
- return 1;
- }
-
- return 0;
-}
-
-
-static void
-purge_requests(uint32_t nodeid, uint32_t pid)
-{
- struct request_node *r;
- int found = 0, count = 0, x = 0;
-
- do {
- found = 0;
- list_for(&requests, r, x) {
- if (r->l.owner_nodeid != nodeid ||
- (pid &&
- r->l.owner_pid != pid))
- continue;
-
- list_remove(&requests, r);
- free(r);
- found = 1;
- ++count;
- break;
- }
- } while (found);
-
- if (count) {
- if (pid) {
- logt_print(LOG_DEBUG, "RECOVERY: purged %d requests from %d:%d\n", count, nodeid, pid);
- } else {
- logt_print(LOG_DEBUG, "RECOVERY: purged %d requests from node %d\n", count, nodeid);
- }
- }
-}
-
-
-
-static void
-del_client(int fd)
-{
- struct cpg_lock_msg m;
- struct client_node *n;
- struct lock_node *l;
- int x, pid = 0, recovered = 0;
-
- list_for(&clients, n, x) {
- if (n->fd == fd) {
- list_remove(&clients, n);
- close(n->fd);
- pid = n->pid;
- free(n);
- break;
- }
- }
-
- if (!pid)
- return;
-
- logt_print(LOG_DEBUG, "RECOVERY: Looking for locks held by PID %d\n", pid);
-
- if (cluster_quorate) {
- /* This may not be needed */
- purge_requests(my_node_id, pid);
-
- memset(&m, 0, sizeof(m));
- m.request = MSG_PURGE;
- m.owner_nodeid = my_node_id;
- m.owner_pid = pid;
-
- send_lock_msg(&m);
- }
-
- if (!cluster_quorate && locks != NULL)
- logt_print(LOG_DEBUG, "RECOVERY: not quorate but locks exist\n");
-
- list_for(&locks, l, x) {
- if (l->l.owner_nodeid != my_node_id ||
- l->l.owner_pid != pid ||
- l->l.state != LOCK_HELD)
- continue;
-
- logt_print(LOG_DEBUG, "RECOVERY: Releasing %s \n", l->l.resource);
-
- l->l.state = LOCK_FREE;
- strncpy(m.resource, l->l.resource, sizeof(m.resource));
- ++recovered;
- if (grant_next(&m) == 0)
- send_unlock(&m);
- }
-
- if (recovered) {
- logt_print(LOG_DEBUG, "RECOVERY: %d locks from local PID %d\n", recovered, pid);
- }
- logt_print(LOG_DEBUG, "RECOVERY: Complete\n");
-}
-
-
-static void
-del_node(uint32_t nodeid)
-{
- struct cpg_lock_msg m;
- struct lock_node *l;
- int x, recovered = 0, granted = 0;
-
- if (group_members->nodeid != my_node_id) {
- /*
- ** Update the owner and pid of any locks owned by the deleted
- ** node to those of the oldest node in the group.
- */
- list_for(&locks, l, x) {
- if (l->l.owner_nodeid == nodeid) {
- logt_print(LOG_DEBUG, "RECOVERY: LOCK UPDATED: %s [%d:%d]=>[%d:%d]\n",
- l->l.resource,
- l->l.owner_nodeid, l->l.owner_pid,
- group_members->nodeid, group_members->pid);
- l->l.owner_nodeid = group_members->nodeid;
- l->l.owner_pid = group_members->pid;
- }
- }
- return;
- }
-
- logt_print(LOG_DEBUG, "RECOVERY: I am oldest node in the group, recovering locks\n");
-
- /* pass 1: purge outstanding requests from this node. */
-
- /* This may not be needed */
- purge_requests(nodeid, 0);
-
- memset(&m, 0, sizeof(m));
- m.request = MSG_PURGE;
- m.owner_nodeid = nodeid;
- m.owner_pid = 0;
-
- send_lock_msg(&m);
-
- list_for(&locks, l, x) {
- if (l->l.owner_nodeid == nodeid && l->l.state == LOCK_HELD) {
- logt_print(LOG_DEBUG, "RECOVERY: Releasing %s held by dead node %d\n",
- l->l.resource, nodeid);
-
- l->l.state = LOCK_FREE;
- strncpy(m.resource, l->l.resource, sizeof(m.resource));
- if (grant_next(&m) == 0) {
- logt_print(LOG_DEBUG, "RECOVERY: HELD LOCK UPDATED: %s [%d:%d]=>[%d:%d]\n",
- l->l.resource,
- l->l.owner_nodeid, l->l.owner_pid,
- my_node_id, getpid());
- l->l.owner_nodeid = my_node_id;
- l->l.owner_pid = getpid();
- m.owner_nodeid = my_node_id;
- m.owner_pid = getpid();
- send_unlock(&m);
- }
- ++recovered;
- } else if (l->l.owner_nodeid == nodeid && l->l.state == LOCK_FREE) {
- strncpy(m.resource, l->l.resource, sizeof(m.resource));
- if (grant_next(&m) == 0) {
- logt_print(LOG_DEBUG, "RECOVERY: FREE LOCK UPDATED: %s [%d:%d]=>[%d:%d]\n",
- l->l.resource,
- l->l.owner_nodeid, l->l.owner_pid,
- my_node_id, getpid());
- l->l.owner_nodeid = my_node_id;
- l->l.owner_pid = getpid();
- }
- ++granted;
- }
- }
-
- if (recovered) {
- logt_print(LOG_DEBUG, "RECOVERY: %d locks from node %d\n", recovered, nodeid);
- }
- if (granted) {
- logt_print(LOG_DEBUG, "RECOVERY: %d pending locks granted\n", granted);
- }
-
- logt_print(LOG_DEBUG, "RECOVERY: Complete\n");
-}
-
-
-static int
-client_fdset(fd_set *set)
-{
- int max = -1, x = 0;
- struct client_node *n;
-
- FD_ZERO(set);
-
- list_for(&clients, n, x) {
- FD_SET(n->fd, set);
- if (n->fd > max)
- max = n->fd;
- }
-
- if (!x)
- return 0;
-
- return max;
-}
-
-
-static struct client_node *
-find_client(int pid)
-{
- int x;
- struct client_node *n;
-
- list_for(&clients, n, x) {
- if (n->pid == pid)
- return n;
- }
-
- return NULL;
-}
-
-
-#if 0
-static void
-send_fault(const char *resource)
-{
- struct cpg_lock_msg m;
-
- strncpy(m.resource, resource, sizeof(m.resource));
- m.request = MSG_HALT;
- m.owner_pid = 0;
- m.owner_nodeid = my_node_id;
-
- send_lock_msg(&m);
-}
-#endif
-
-
-static int
-grant_client(struct lock_node *l)
-{
- struct client_node *c;
- struct cpg_lock_msg m;
-
- memset(&m, 0, sizeof(m));
- strncpy(m.resource, l->l.resource, sizeof(m.resource));
- m.request = MSG_GRANT;
- m.owner_pid = l->l.owner_pid;
- m.owner_tid = l->l.owner_tid;
- l->l.local_id = ++local_lockid;
- m.lockid = l->l.local_id;
- m.owner_nodeid = my_node_id;
-
- c = find_client(l->l.owner_pid);
- if (!c) {
- logt_print(LOG_DEBUG, "can't find client for pid %d\n", l->l.owner_pid);
- return 1;
- }
-
- if (c->fd < 0) {
- logt_print(LOG_DEBUG, " Client has bad fd\n");
- return -1;
- }
-
- if (write_retry(c->fd, &m, sizeof(m), NULL) < 0) {
- /* no client anymore; drop and send to next guy XXX */
- /* This should be handled by our main loop */
- //logt_print(LOG_DEBUG, "Failed to notify client!\n");
- }
-
- return 0;
-}
-
-
-static int
-nak_client(struct request_node *l)
-{
- struct client_node *c;
- struct cpg_lock_msg m;
-
- memset(&m, 0, sizeof(m));
- strncpy(m.resource, l->l.resource, sizeof(m.resource));
- m.request = MSG_NAK;
- m.owner_pid = l->l.owner_pid;
- m.owner_tid = l->l.owner_tid;
- m.owner_nodeid = my_node_id;
-
- c = find_client(l->l.owner_pid);
- if (!c) {
- logt_print(LOG_DEBUG, "can't find client for pid %d\n", l->l.owner_pid);
- return 1;
- }
-
- if (c->fd < 0) {
- logt_print(LOG_DEBUG, " Client has bad fd\n");
- return -1;
- }
-
- if (write_retry(c->fd, &m, sizeof(m), NULL) < 0) {
- /* no client anymore; drop and send to next guy XXX */
- /* This should be handled by our main loop */
- //logt_print(LOG_DEBUG, "Failed to notify client!\n");
- }
-
- return 0;
-}
-
-static int
-queue_request(struct cpg_lock_msg *m)
-{
- struct request_node *r;
-
- r = do_alloc(sizeof(*r));
- strncpy(r->l.resource, m->resource, sizeof(r->l.resource));
- r->l.owner_nodeid = m->owner_nodeid;
- r->l.owner_pid = m->owner_pid;
- r->l.owner_tid = m->owner_tid;
- r->l.state = LOCK_PENDING;
-
- list_insert(&requests, r);
- return 0;
-}
-
-
-static int
-process_lock(struct cpg_lock_msg *m)
-{
- struct lock_node *l;
- int x;
-
- if (!joined)
- return 0;
-
- logt_print(LOG_DEBUG, "LOCK %s: queue for %d:%d:%d\n", m->resource,
- m->owner_nodeid, m->owner_pid, m->owner_tid);
- queue_request(m);
-
- list_for(&locks, l, x) {
- if (strcmp(m->resource, l->l.resource))
- continue;
-
- /* if it's owned locally, we need send a
- GRANT to the first node on the request queue */
- if (l->l.owner_nodeid == my_node_id) {
- if (l->l.state == LOCK_FREE) {
- /* Set local state to PENDING to avoid double-grants */
- l->l.state = LOCK_PENDING;
- grant_next(m);
- } else {
- /* state is PENDING or HELD */
- if (m->flags & FL_TRY) {
- /* nack to client if needed */
- send_nak(m);
- }
- }
- }
-
-
- return 0;
- }
-
- l = do_alloc(sizeof(*l));
- strncpy(l->l.resource, m->resource, sizeof(l->l.resource));
- l->l.state = LOCK_FREE;
- list_insert(&locks, l);
-
- if (group_members->nodeid == my_node_id) {
- /* Allocate a lock structure and immediately grant */
- l->l.state = LOCK_PENDING;
- if (grant_next(m) == 0)
- l->l.state = LOCK_FREE;
- }
-
- return 0;
-}
-
-
-static int
-process_grant(struct cpg_lock_msg *m, uint32_t nodeid)
-{
- struct lock_node *l;
- struct request_node *r;
- int x, y;
-
- if (!joined)
- return 0;
-
- list_for(&locks, l, x) {
- if (strcmp(m->resource, l->l.resource))
- continue;
-
- if (l->l.state == LOCK_HELD) {
- if (m->owner_pid == 0 ||
- m->owner_nodeid == 0) {
- logt_print(LOG_DEBUG, "GRANT averted\n");
- return 0;
- }
- } else {
- l->l.state = LOCK_HELD;
- }
-
- logt_print(LOG_DEBUG, "GRANT %s: to %d:%d:%d\n",
- m->resource, m->owner_nodeid,
- m->owner_pid, m->owner_tid);
-
- l->l.owner_nodeid = m->owner_nodeid;
- l->l.owner_pid = m->owner_pid;
- l->l.owner_tid = m->owner_tid;
-
- list_for(&requests, r, y) {
- if (strcmp(r->l.resource, m->resource))
- continue;
-
- if (r->l.owner_nodeid == m->owner_nodeid &&
- r->l.owner_pid == m->owner_pid &&
- r->l.owner_tid == m->owner_tid) {
- list_remove(&requests, r);
- free(r);
- break;
- }
- }
-
- /* granted lock */
- if (l->l.owner_nodeid == my_node_id) {
- if (grant_client(l) != 0) {
- /* Grant to a nonexistent PID can
- happen because we may have a pending
- request after a fd was closed.
- since we process on delivery, we
- now simply make an unlock request
- and move on */
- purge_requests(my_node_id, l->l.owner_pid);
- if (grant_next(m) == 0)
- send_unlock(m);
- return 0;
- }
- }
-
- /* What if node has died with a GRANT in flight? */
- if (group_members->nodeid == my_node_id &&
- !is_member(l->l.owner_nodeid)) {
-
- logt_print(LOG_DEBUG, "GRANT to non-member %d; giving to next requestor\n",
- l->l.owner_nodeid);
-
- l->l.state = LOCK_FREE;
- if (grant_next(m) == 0)
- send_unlock(m);
- return 0;
- }
- return 0;
- }
-
- /* Record lock state since we now know it */
- /* Allocate a lock structure */
- l = do_alloc(sizeof(*l));
- strncpy(l->l.resource, m->resource, sizeof(l->l.resource));
- l->l.state = LOCK_HELD;
- l->l.owner_nodeid = m->owner_nodeid;
- l->l.owner_pid = m->owner_pid;
- l->l.owner_tid = m->owner_tid;
- list_insert(&locks, l);
-
- return 0;
-}
-
-
-static int
-process_nak(struct cpg_lock_msg *m, uint32_t nodeid)
-{
- struct request_node *r = NULL;
- int y;
-
- if (!joined)
- return 0;
-
- logt_print(LOG_DEBUG, "NAK %s for %d:%d:%d\n", m->resource,
- m->owner_nodeid, m->owner_pid, m->owner_tid);
-
- list_for(&requests, r, y) {
- if (strcmp(r->l.resource, m->resource))
- continue;
-
- if (r->l.owner_nodeid == m->owner_nodeid &&
- r->l.owner_pid == m->owner_pid &&
- r->l.owner_tid == m->owner_tid) {
- list_remove(&requests, r);
- if (r->l.owner_nodeid == my_node_id) {
- if (nak_client(r) != 0) {
- purge_requests(my_node_id, r->l.owner_pid);
- }
- }
- free(r);
- break;
- }
- }
-
- return 0;
-}
-
-
-static int
-process_unlock(struct cpg_lock_msg *m, uint32_t nodeid)
-{
- struct lock_node *l;
- int x;
-
- if (!joined)
- return 0;
-
- list_for(&locks, l, x) {
- if (l->l.state != LOCK_HELD)
- continue;
- if (strcmp(m->resource, l->l.resource))
- continue;
-
- /* Held lock... if it's local, we need send a
- GRANT to the first node on the request queue */
- if (l->l.owner_nodeid == m->owner_nodeid &&
- l->l.owner_pid == m->owner_pid) {
- logt_print(LOG_DEBUG, "UNLOCK %s: %d:%d:%d\n",
- m->resource, m->owner_nodeid, m->owner_pid, m->owner_tid);
- l->l.state = LOCK_FREE;
- if (l->l.owner_nodeid == my_node_id) {
- if (grant_next(m) != 0)
- l->l.state = LOCK_PENDING;
- }
- }
- }
-
- return 0;
-}
-
-
-static int
-find_lock(struct cpg_lock_msg *m)
-{
- struct lock_node *l;
- int x;
-
- if (m->resource[0] != 0)
- return 0;
-
- list_for(&locks, l, x) {
- if (m->lockid == l->l.local_id) {
- strncpy(m->resource, l->l.resource, sizeof(m->resource));
- logt_print(LOG_DEBUG, "LOCK %d -> %s\n", m->lockid, m->resource);
- m->owner_nodeid = l->l.owner_nodeid;
- m->owner_pid = l->l.owner_pid;
- m->owner_tid = l->l.owner_tid;
- m->lockid = 0;
- return 0;
- }
- }
-
- return 1;
-}
-
-
-static int
-process_join(struct cpg_lock_msg *m, uint32_t nodeid, uint32_t pid)
-{
- struct member_node *n;
- int x;
-
- list_for(&group_members, n, x) {
- if (n->nodeid == nodeid) {
- if (n->pid == pid) {
- logt_print(LOG_DEBUG, "Saw JOIN from self (%d.%d)\n",
- nodeid, pid);
- list_remove(&group_members, n);
- list_append(&group_members, n);
- } else {
- logt_print(LOG_DEBUG,
- "IGNORING JOIN from existing member %d.%d (%d.%d)\n",
- nodeid, pid, nodeid, n->pid);
- }
- return 0;
- }
- }
-
- n = do_alloc(sizeof(*n));
- n->nodeid = nodeid;
- n->pid = pid;
- logt_print(LOG_DEBUG, "JOIN: node %d.%u", n->nodeid, n->pid);
- if (nodeid == my_node_id) {
- logt_print(LOG_DEBUG, " (self)");
- joined = 1;
- }
- total_members++;
- logt_print(LOG_DEBUG, "\n");
- list_insert(&group_members, n);
-
- return 0;
-}
-
-
-static int
-process_request(struct cpg_lock_msg *m, uint32_t nodeid, uint32_t pid)
-{
- swab_cpg_lock_msg(m);
-
- if (m->request == MSG_HALT) {
- logt_print(LOG_DEBUG, "FAULT: Halting operations; see node %d\n", m->owner_nodeid);
- while (1)
- sleep(30);
- }
-
- old_msg(m);
-
- switch (m->request) {
- case MSG_LOCK:
- process_lock(m);
- break;
- case MSG_NAK:
- process_nak(m, nodeid);
- break;
- case MSG_GRANT:
- process_grant(m, nodeid);
- break;
- case MSG_UNLOCK:
- process_unlock(m, nodeid);
- break;
- case MSG_PURGE:
- purge_requests(m->owner_nodeid, m->owner_pid);
- break;
- case MSG_JOIN:
- process_join(m, nodeid, pid);
- break;
- }
-
- return 0;
-}
-
-
-static void
-cpg_deliver_func(cpg_handle_t h,
- const struct cpg_name *group_name,
- uint32_t nodeid,
- uint32_t pid,
- void *msg,
- size_t msglen)
-{
-
- if (msglen != sizeof(struct cpg_lock_msg)) {
- logt_print(LOG_DEBUG, "Invalid message size %d\n", (int)msglen);
- }
-
- process_request((struct cpg_lock_msg *)msg, nodeid, pid);
-}
-
-
-static void
-cpg_config_change(cpg_handle_t h,
- const struct cpg_name *group_name,
- const struct cpg_address *members, size_t memberlen,
- const struct cpg_address *left, size_t leftlen,
- const struct cpg_address *join, size_t joinlen)
-{
- struct member_node *n;
- size_t x, y;
- struct cpg_lock_msg m;
- int cpglock_members_removed = 0;
-
- memset(&m, 0, sizeof(m));
- strncpy(m.resource, "(none)", sizeof(m.resource));
- m.request = MSG_CONFCHG;
-
- old_msg(&m);
-
- if (total_members == 0) {
- logt_print(LOG_DEBUG, "JOIN: Setting up initial node list\n");
- for (x = 0; x < memberlen; x++) {
- for (y = 0; y < joinlen; y++) {
- if (join[y].nodeid == members[x].nodeid)
- continue;
- if (members[x].nodeid == my_node_id)
- continue;
-
- n = do_alloc(sizeof(*n));
- n->nodeid = members[x].nodeid;
- n->pid = members[x].pid;
- logt_print(LOG_DEBUG, "JOIN: node %d.%u\n", n->nodeid, n->pid);
- list_insert(&group_members, n);
- }
- }
- logt_print(LOG_DEBUG, "JOIN: Done\n");
-
- total_members = memberlen;
- }
-
- //logt_print(LOG_DEBUG, "members %d now, %d joined, %d left\n", memberlen, joinlen, leftlen);
-#if 0
-
- /* XXX process join on receipt of JOIN message rather than here
- since ordered delivery is agreed, this prevents >1 member from
- believing it is the oldest host */
- for (x = 0; x < joinlen; x++) {
- n = do_alloc(sizeof(*n));
- n->nodeid = join[x].nodeid;
- logt_print(LOG_DEBUG, "ADD: node %d\n", n->nodeid);
- list_insert(&group_members, n);
- }
-#endif
-
- for (x = 0; x < leftlen; x++) {
- list_for(&group_members, n, y) {
- if (n->nodeid == left[x].nodeid) {
- if (n->pid == left[x].pid) {
- if (n->nodeid == my_node_id) {
- logt_print(LOG_DEBUG, "Received DELETE message for self. Exiting.");
- exit(0);
- }
- list_remove(&group_members, n);
- logt_print(LOG_DEBUG, "DELETE: node %d.%u\n", n->nodeid, n->pid);
- del_node(n->nodeid);
- cpglock_members_removed++;
- free(n);
- break;
- } else {
- logt_print(LOG_DEBUG, "DUPE NODE %d LEFT (%u != %u)\n",
- n->nodeid, n->pid, left[x].pid);
- }
- }
- }
- }
-
- total_members -= cpglock_members_removed;
- if (total_members < 0)
- total_members = 0;
-
-#if 0
- logt_print(LOG_DEBUG, "MEMBERS:");
- list_for(&group_members, n, y) {
- logt_print(LOG_DEBUG, " %d.%u", n->nodeid, n->pid);
- }
- logt_print(LOG_DEBUG, "\n");
-#endif
-
- return;
-}
-
-
-static cpg_callbacks_t my_callbacks = {
- .cpg_deliver_fn = cpg_deliver_func,
- .cpg_confchg_fn = cpg_config_change
-};
-
-static int
-cpg_fin(void)
-{
- struct cpg_name gname;
-
- errno = EINVAL;
-
- gname.length = snprintf(gname.value,
- sizeof(gname.value),
- CPG_LOCKD_NAME);
- if (gname.length >= sizeof(gname.value)) {
- errno = ENAMETOOLONG;
- return -1;
- }
-
- if (gname.length <= 0)
- return -1;
-
- cpg_leave(cpg, &gname);
- cpg_finalize(cpg);
-
- return 0;
-}
-
-static int
-cpg_init(void)
-{
- struct cpg_name gname;
- struct cpg_address member_list[64];
- int cpg_member_list_len = 0;
- int i, ret;
-
- errno = EINVAL;
-
- gname.length = snprintf(gname.value,
- sizeof(gname.value),
- CPG_LOCKD_NAME);
- if (gname.length >= sizeof(gname.value)) {
- errno = ENAMETOOLONG;
- return -1;
- }
-
- if (gname.length <= 0)
- return -1;
-
- memset(&cpg, 0, sizeof(cpg));
- if (cpg_initialize(&cpg, &my_callbacks) != CPG_OK) {
- logt_print(LOG_DEBUG, "cpg_initialize failed");
- return -1;
- }
-
- if (cpg_join(cpg, &gname) != CPG_OK) {
- logt_print(LOG_DEBUG, "cpg_join failed");
- return -1;
- }
-
- cpg_local_get(cpg, &my_node_id);
-
- ret = cpg_membership_get(cpg, &gname, member_list, &cpg_member_list_len);
- if (ret != CPG_OK) {
- logt_print(LOG_DEBUG,
- "cpg_membership_get() failed: %s", strerror(errno));
- cpg_fin();
- return -1;
- }
-
- for (i = 0 ; i < cpg_member_list_len ; i++) {
- if (member_list[i].nodeid == my_node_id) {
- if (member_list[i].pid != getpid()) {
- logt_print(LOG_DEBUG, "nodeid %d already in group with PID %u %u\n",
- member_list[i].nodeid, member_list[i].pid, getpid());
- cpg_fin();
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-static void init_logging(int reconf)
-{
- int ccs_handle;
- int mode = LOG_MODE_OUTPUT_FILE | LOG_MODE_OUTPUT_SYSLOG;
- int syslog_facility = SYSLOGFACILITY;
- int syslog_priority = SYSLOGLEVEL;
- char logfile[PATH_MAX];
- int logfile_priority = SYSLOGLEVEL;
- int debug = 0;
-
- memset(logfile, 0, PATH_MAX);
- snprintf(logfile, sizeof(logfile) - 1, LOGDIR "/cpglockd.log");
-
- ccs_handle = ccs_connect();
- if (ccs_handle > 0) {
- ccs_read_logging(ccs_handle, "cpglockd", &debug, &mode,
- &syslog_facility, &syslog_priority, &logfile_priority, logfile);
- ccs_disconnect(ccs_handle);
- }
-
- if (nofork)
- mode |= LOG_MODE_OUTPUT_STDERR;
-
- if (!reconf)
- logt_init("cpglockd", mode, syslog_facility, syslog_priority, logfile_priority, logfile);
- else
- logt_conf("cpglockd", mode, syslog_facility, syslog_priority, logfile_priority, logfile);
-}
-
-static void
-clear_local_state(void)
-{
- struct request_node *cur_req = NULL;
- struct lock_node *cur_lock = NULL;
-
- while ((cur_lock = locks) != NULL) {
- logt_print(LOG_DEBUG,
- "CLEAR STATE: Dropping lock %s [%d:%d]\n",
- cur_lock->l.resource,
- cur_lock->l.owner_nodeid, cur_lock->l.owner_pid);
- list_remove(&locks, cur_lock);
- free(cur_lock);
- }
-
- while ((cur_req = requests) != NULL) {
- if (cur_req->l.owner_nodeid == my_node_id) {
- nak_client(cur_req);
- logt_print(LOG_DEBUG, "CLEAR STATE: sent NAK %s [%d:%d:%d]\n",
- cur_req->l.resource, cur_req->l.owner_nodeid,
- cur_req->l.owner_pid, cur_req->l.owner_tid);
- }
- logt_print(LOG_DEBUG, "CLEAR STATE: Dropping request %s [%d:%d:%d]\n",
- cur_req->l.resource, cur_req->l.owner_nodeid,
- cur_req->l.owner_pid, cur_req->l.owner_tid);
- list_remove(&requests, cur_req);
- free(cur_req);
- }
-}
-
-int
-main(int argc, char **argv)
-{
- fd_set rfds;
- int fd;
- int cpgfd;
- int afd = -1;
- int cman_fd;
- int n,x;
- int quorate_last = 0;
- int wait_for_quorum = 1;
- int wait_for_fencing = 1;
- int opt;
- int ret;
- int exit_status = 0;
- struct cpg_lock_msg m;
- struct client_node *client;
- cman_handle_t cman_handle = NULL;
- cman_node_t my_node;
-
- while ((opt = getopt(argc, argv, "FQfh")) != EOF) {
- switch (opt) {
- case 'F':
- wait_for_fencing = 0;
- break;
- case 'Q':
- wait_for_quorum = 0;
- break;
- case 'f':
- nofork = 1;
- break;
- case 'h':
- printf("Usage: %s [options]\n\
- -F Don't wait for the current node to join the fencing domain at startup\n\
- -Q Don't wait for quorum formation at startup\n\
- -f Don't daemonize\n\
- -h Print this help message\n",
- argv[0]);
- return 0;
- default:
- return -1;
- }
- }
-
- if (!nofork) {
- daemon_init((char *) "cpglockd");
- } else {
- pid_t pid;
- if (check_process_running((char *) "cpglockd", &pid) && (pid != getpid())) {
- fprintf(stderr,
- "cpglockd is already running\n");
- return -1;
- }
- update_pidfile((char *) "cpglockd");
- }
- init_logging(0);
-
- setup_signal(SIGPIPE, SIG_IGN);
- setup_signal(SIGTERM, flag_shutdown);
- setup_signal(SIGINT, flag_shutdown);
-
- cman_connect(&cman_handle);
- if (cman_handle == NULL) {
- logt_print(LOG_ERR, "Unable to connect to cman\n");
- exit_status = -1;
- goto out4;
- }
-
- if (shutdown_pending)
- goto out3;
-
- if (wait_for_quorum)
- wait_for_quorum_formation(cman_handle);
-
- if (shutdown_pending)
- goto out3;
-
- memset(&my_node, 0, sizeof(my_node));
- cman_get_node(cman_handle, CMAN_NODEID_US, &my_node);
-
- if (my_node.cn_nodeid == 0) {
- logt_print(LOG_ERR, "Unable to get our cluster node ID\n");
- exit_status = -1;
- goto out3;
- }
-
- if (wait_for_fencing)
- wait_for_fencing_join(my_node.cn_nodeid);
-
- if (shutdown_pending)
- goto out3;
-
- memset(&cman_nodes, 0, sizeof(cman_nodes));
- cman_node_count = 0;
-
- ret = cman_get_nodes(cman_handle,
- sizeof(cman_nodes) / sizeof(cman_nodes[0]),
- &cman_node_count, cman_nodes);
- if (ret < 0) {
- logt_print(LOG_ERR, "Unable to get cman nodes list\n");
- exit_status = -1;
- goto out3;
- }
-
- cman_fd = cman_get_fd(cman_handle);
- if (cman_fd < 0) {
- logt_print(LOG_ERR, "Error: cman fd is %d\n", cman_fd);
- exit_status = -1;
- goto out3;
- }
-
- cman_start_notification(cman_handle, cman_callback);
-
- if (cpg_init() < 0) {
- logt_print(LOG_ERR, "Unable to join CPG group\n");
- exit_status = -1;
- goto out2;
- }
-
- if (my_node.cn_nodeid != my_node_id) {
- logt_print(LOG_ERR, "cman nodeid and CPG node id differ: %d != %d\n",
- my_node.cn_nodeid, my_node_id);
- exit_status = -1;
- goto out1;
- }
-
- fd = sock_listen(CPG_LOCKD_SOCK);
- if (fd < 0) {
- logt_print(LOG_ERR, "Error connecting to %s: %s\n",
- CPG_LOCKD_SOCK, strerror(errno));
- exit_status = -1;
- goto out1;
- }
-
- cpg_fd_get(cpg, &cpgfd);
- if (cpgfd < 0 || send_join() < 0) {
- logt_print(LOG_ERR, "Unable to complete join to CPG group\n");
- exit_status = -1;
- goto out;
- }
-
- if (wait_for_quorum)
- wait_for_quorum_formation(cman_handle);
- quorate_last = cluster_quorate;
-
- logt_print(LOG_INFO, "cpglockd entering normal operation\n");
- while (!shutdown_pending) {
- struct timeval tv;
- struct pending_fence_node *pf_node;
-
- FD_ZERO(&rfds);
- x = client_fdset(&rfds);
- FD_SET(fd, &rfds);
- if (fd > x)
- x = fd;
- FD_SET(cpgfd, &rfds);
- if (cpgfd > x)
- x = cpgfd;
- cman_fd = cman_get_fd(cman_handle);
- FD_SET(cman_fd, &rfds);
- if (cman_fd > x)
- x = cman_fd;
-
- tv.tv_sec = 0;
- tv.tv_usec = 500000;
-
- n = select_retry(x+1, &rfds, NULL, NULL, &tv);
- if (n < 0) {
- logt_print(LOG_ERR, "Error: select: %s\n", strerror(errno));
- exit_status = -1;
- goto out;
- }
-
- if (FD_ISSET(cman_fd, &rfds)) {
- if (cman_dispatch(cman_handle, CMAN_DISPATCH_ALL) < 0) {
- logt_print(LOG_ERR, "Fatal: cman_dispatch() failed: %s\n",
- strerror(errno));
- exit_status = -1;
- goto out;
- }
- --n;
- }
-
- if (cman_shutdown_requested) {
- logt_print(LOG_INFO, "cman requested shutdown. Exiting.\n");
- cman_replyto_shutdown(cman_handle, 1);
- goto out;
- }
-
- if (!quorate_last && cluster_quorate)
- logt_print(LOG_INFO, "Cluster quorum regained\n");
-
- if (quorate_last && !cluster_quorate) {
- logt_print(LOG_INFO,
- "Cluster lost quorum. Clearing local state.\n");
- clear_local_state();
- }
- quorate_last = cluster_quorate;
-
- fence_check:
- list_for(&pending_fencing, pf_node, x) {
- int victim;
- uint64_t lft;
- struct fenced_node fn;
-
- ret = fenced_node_info(pf_node->nodeid, &fn);
- if (ret < 0) {
- logt_print(LOG_DEBUG, "Unable to get last fenced time for node %d\n",
- pf_node->nodeid);
- victim = 1;
- lft = 0;
- } else {
- victim = fn.victim;
- lft = fn.last_fenced_time;
- }
-
- if (lft >= pf_node->fail_time) {
- logt_print(LOG_DEBUG,
- "Fencing for node %d finished at %ld (lost at %ld)\n",
- pf_node->nodeid, lft, pf_node->fail_time);
- list_remove(&pending_fencing, pf_node);
- free(pf_node);
- goto fence_check;
- }
-
- /*
- ** If node A either fails or leaves the cluster cleanly while
- ** fencing is outstanding on another node (or nodes), we aren't
- ** able to determine whether A has failed or left cleanly until
- ** fencing has completed for the nodes that have left or failed
- ** prior to A while any fencing is outstanding. The first entry
- ** in this list will be the node that has left or failed longer
- ** ago than any others in the list. If fenced has not set
- ** victim to 1 by now, we can deduce it has left cleanly, and we
- ** don't need to wait for it.
- */
- if (!victim && !x && !pf_node->force_wait) {
- /* Wait up to 1s for fenced to set victim */
- sleep(1);
- if (fenced_node_info(pf_node->nodeid, &fn) < 0) {
- logt_print(LOG_DEBUG,
- "Unable to get fenced data for node %d\n",
- pf_node->nodeid);
- } else
- victim = fn.victim;
-
- if (!victim) {
- logt_print(LOG_DEBUG, "First entry in list and victim == 0, removing %d from pending fencing\n", pf_node->nodeid);
- list_remove(&pending_fencing, pf_node);
- free(pf_node);
- } else {
- logt_print(LOG_DEBUG, "fenced_node.victim flipped to 1 for %d\n",
- pf_node->nodeid);
- }
- goto fence_check;
- }
- if (!victim && !x && pf_node->force_wait) {
- logt_print(LOG_DEBUG, "Would have removed %d but now waiting\n",
- pf_node->nodeid);
- }
-
- }
-
- if (shutdown_pending)
- goto out;
-
- /* While fencing is pending for any nodes pause lock activity. */
- if (pending_fencing != NULL) {
- usleep(500000);
- continue;
- }
-
- if (FD_ISSET(fd, &rfds)) {
- afd = accept(fd, NULL, NULL);
- if (afd < 0) {
- logt_print(LOG_DEBUG, "Error accepting new client: %s\n",
- strerror(errno));
- } else {
- insert_client(afd);
- }
- --n;
- }
-
- if (FD_ISSET(cpgfd, &rfds)) {
- --n;
- if (cluster_quorate &&
- cpg_dispatch(cpg, CPG_DISPATCH_ALL) != CPG_OK)
- {
- logt_print(LOG_ERR, "Fatal: Lost CPG connection.\n");
- return -1;
- }
- }
-
- if (n <= 0)
- continue;
-
- do {
- list_for(&clients, client, x) {
- if (!FD_ISSET(client->fd, &rfds))
- continue;
- --n;
-
- if (read_retry(client->fd, &m, sizeof(m), NULL) < 0) {
- logt_print(LOG_DEBUG, "Closing client fd %d pid %d: %d\n",
- client->fd, client->pid, errno);
-
- del_client(client->fd);
- break;
- }
-
- /* send lock request */
- /* XXX check for dup connection */
- if (m.request == MSG_LOCK) {
- if (!cluster_quorate) {
- m.request = MSG_NAK;
- m.owner_nodeid = my_node_id;
-
- logt_print(LOG_DEBUG, "Sending NAK for new lock request while not quorate (%s [%d:%d:%d])\n",
- m.resource, m.owner_nodeid,
- m.owner_pid, m.owner_tid);
-
- if (write_retry(client->fd, &m, sizeof(m), NULL) < 0) {
- logt_print(LOG_DEBUG,
- "Error sending NAK for %s [%d:%d:%d]: %s\n",
- m.resource, m.owner_nodeid,
- m.owner_pid, m.owner_tid, strerror(errno));
- }
- } else {
- client->pid = m.owner_pid;
- send_lock(&m);
- }
- }
-
- if (m.request == MSG_UNLOCK) {
- //logt_print(LOG_DEBUG, "Unlock from fd %d\n", client->fd);
- /*
- ** When not quorate, all locks and requests have already
- ** been dropped.
- */
- if (cluster_quorate) {
- find_lock(&m);
- if (grant_next(&m) == 0)
- send_unlock(&m);
- }
- }
-
- if (m.request == MSG_DUMP) {
- FILE *fp = fdopen(client->fd, "w");
-
- list_remove(&clients, client);
- dump_state(fp);
- fclose(fp);
- close(client->fd);
- free(client);
- break;
- }
- }
- } while (n);
- }
-
-out:
- close(fd);
- unlink(CPG_LOCKD_SOCK);
-out1:
- cpg_fin();
-out2:
- cman_stop_notification(cman_handle);
-out3:
- cman_finish(cman_handle);
-out4:
- daemon_cleanup();
- return exit_status;
-}
diff --git a/rgmanager/src/daemons/cpglockdump.c b/rgmanager/src/daemons/cpglockdump.c
deleted file mode 100644
index 2750e4a..0000000
--- a/rgmanager/src/daemons/cpglockdump.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <stdio.h>
-#include <cpglock.h>
-
-int
-main(int argc, char **argv)
-{
- return cpg_lock_dump(stdout);
-}
diff --git a/rgmanager/src/daemons/event_config.c b/rgmanager/src/daemons/event_config.c
deleted file mode 100644
index 9c4b8b3..0000000
--- a/rgmanager/src/daemons/event_config.c
+++ /dev/null
@@ -1,514 +0,0 @@
-/** @file
- * CCS event parsing, based on failover domain parsing
- */
-#include <string.h>
-#include <list.h>
-#include <logging.h>
-#include <resgroup.h>
-#include <restart_counter.h>
-#include <reslist.h>
-#include <ccs.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <members.h>
-#include <reslist.h>
-#include <ctype.h>
-#include <event.h>
-
-#define CONFIG_NODE_ID_TO_NAME \
- "/cluster/clusternodes/clusternode[@nodeid=\"%d\"]/@name"
-#define CONFIG_NODE_NAME_TO_ID \
- "/cluster/clusternodes/clusternode[@name=\"%s\"]/@nodeid"
-
-void deconstruct_events(event_table_t **);
-void print_event(FILE *fp, event_t *ev);
-
-//#define DEBUG
-
-#ifdef NO_CCS
-#define ccs_get(fd, query, ret) conf_get(query, ret)
-#endif
-
-/*
- <events>
- <event name="helpful_name_here" class="node"
- node="nodeid|nodename" nodestate="up|down">
- slang_script_stuff();
- start_service();
- </event>
- </events>
- */
-int
-event_match(event_t *pattern, event_t *actual)
-{
- if (pattern->ev_type != EVENT_NONE &&
- actual->ev_type != pattern->ev_type)
- return 0;
-
- /* If there's no event class specified, the rest is
- irrelevant */
- if (pattern->ev_type == EVENT_NONE)
- return 1;
-
- switch(pattern->ev_type) {
- case EVENT_NODE:
- if (pattern->ev.node.ne_nodeid >= 0 &&
- actual->ev.node.ne_nodeid !=
- pattern->ev.node.ne_nodeid) {
- return 0;
- }
- if (pattern->ev.node.ne_local >= 0 &&
- actual->ev.node.ne_local !=
- pattern->ev.node.ne_local) {
- return 0;
- }
- if (pattern->ev.node.ne_state >= 0 &&
- actual->ev.node.ne_state !=
- pattern->ev.node.ne_state) {
- return 0;
- }
- if (pattern->ev.node.ne_clean >= 0 &&
- actual->ev.node.ne_clean !=
- pattern->ev.node.ne_clean) {
- return 0;
- }
- return 1; /* All specified params match */
- case EVENT_RG:
- if (pattern->ev.group.rg_name[0] &&
- strcasecmp(actual->ev.group.rg_name,
- pattern->ev.group.rg_name)) {
- return 0;
- }
- if (pattern->ev.group.rg_state != (uint32_t)-1 &&
- actual->ev.group.rg_state !=
- pattern->ev.group.rg_state) {
- return 0;
- }
- if (pattern->ev.group.rg_owner >= 0 &&
- actual->ev.group.rg_owner !=
- pattern->ev.group.rg_owner) {
- return 0;
- }
- return 1;
- case EVENT_CONFIG:
- if (pattern->ev.config.cfg_version >= 0 &&
- actual->ev.config.cfg_version !=
- pattern->ev.config.cfg_version) {
- return 0;
- }
- if (pattern->ev.config.cfg_oldversion >= 0 &&
- actual->ev.config.cfg_oldversion !=
- pattern->ev.config.cfg_oldversion) {
- return 0;
- }
- return 1;
- case EVENT_USER:
- if (pattern->ev.user.u_name[0] &&
- strcasecmp(actual->ev.user.u_name,
- pattern->ev.user.u_name)) {
- return 0;
- }
- if (pattern->ev.user.u_request != 0 &&
- actual->ev.user.u_request !=
- pattern->ev.user.u_request) {
- return 0;
- }
- if (pattern->ev.user.u_target != 0 &&
- actual->ev.user.u_target !=
- pattern->ev.user.u_target) {
- return 0;
- }
- return 1;
- default:
- break;
- }
-
- return 0;
-}
-
-
-static int
-#ifndef NO_CCS
-ccs_node_name_to_id(int ccsfd, char *name)
-#else
-ccs_node_name_to_id(int __attribute__((unused)) ccsfd, char *name)
-#endif
-{
- char xpath[256], *ret = 0;
- int rv = 0;
-
- snprintf(xpath, sizeof(xpath), CONFIG_NODE_NAME_TO_ID,
- name);
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- rv = atoi(ret);
- free(ret);
- return rv;
- }
- return 0;
-}
-
-
-static void
-deconstruct_event(event_t *ev)
-{
- if (ev->ev_script)
- free(ev->ev_script);
- if (ev->ev_script_file)
- free(ev->ev_script_file);
- if (ev->ev_name)
- free(ev->ev_name);
- free(ev);
-}
-
-
-static int
-get_node_event(int ccsfd, char *base, event_t *ev)
-{
- char xpath[256], *ret = NULL;
-
- /* Clear out the possibilitiies */
- ev->ev.node.ne_nodeid = -1;
- ev->ev.node.ne_local = -1;
- ev->ev.node.ne_state = -1;
- ev->ev.node.ne_clean = -1;
-
- snprintf(xpath, sizeof(xpath), "%s/@node_id", base);
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- ev->ev.node.ne_nodeid = atoi(ret);
- free(ret);
- if (ev->ev.node.ne_nodeid <= 0)
- return -1;
- } else {
- /* See if there's a node name */
- snprintf(xpath, sizeof(xpath), "%s/@node", base);
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- ev->ev.node.ne_nodeid =
- ccs_node_name_to_id(ccsfd, ret);
- free(ret);
- if (ev->ev.node.ne_nodeid <= 0)
- return -1;
- }
- }
-
- snprintf(xpath, sizeof(xpath), "%s/@node_state", base);
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- if (!strcasecmp(ret, "up")) {
- ev->ev.node.ne_state = 1;
- } else if (!strcasecmp(ret, "down")) {
- ev->ev.node.ne_state = 0;
- } else {
- ev->ev.node.ne_state = !!atoi(ret);
- }
- free(ret);
- }
-
- snprintf(xpath, sizeof(xpath), "%s/@node_clean", base);
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- ev->ev.node.ne_clean = !!atoi(ret);
- free(ret);
- }
-
- snprintf(xpath, sizeof(xpath), "%s/@node_local", base);
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- ev->ev.node.ne_local = !!atoi(ret);
- free(ret);
- }
-
- return 0;
-}
-
-
-static int
-get_rg_event(int ccsfd, char *base, event_t *ev)
-{
- char xpath[256], *ret = NULL;
-
- /* Clear out the possibilitiies */
- ev->ev.group.rg_name[0] = 0;
- ev->ev.group.rg_state = (uint32_t)-1;
- ev->ev.group.rg_owner = -1;
-
- snprintf(xpath, sizeof(xpath), "%s/@service", base);
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- strncpy(ev->ev.group.rg_name, ret,
- sizeof(ev->ev.group.rg_name));
- free(ret);
- if (!strlen(ev->ev.group.rg_name)) {
- return -1;
- }
- }
-
- snprintf(xpath, sizeof(xpath), "%s/@service_state", base);
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- if (!isdigit(ret[0])) {
- ev->ev.group.rg_state =
- rg_state_str_to_id(ret);
- } else {
- ev->ev.group.rg_state = atoi(ret);
- }
- free(ret);
- }
-
- snprintf(xpath, sizeof(xpath), "%s/@service_owner", base);
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- if (!isdigit(ret[0])) {
- ev->ev.group.rg_owner =
- ccs_node_name_to_id(ccsfd, ret);
- } else {
- ev->ev.group.rg_owner = !!atoi(ret);
- }
- free(ret);
- }
-
- return 0;
-}
-
-
-static int
-get_config_event(int __attribute__((unused)) ccsfd,
- char __attribute__((unused)) *base,
- event_t __attribute__((unused)) *ev)
-{
- errno = ENOSYS;
- return -1;
-}
-
-
-static event_t *
-get_event(int ccsfd, char *base, int idx, int *_done)
-{
- event_t *ev;
- char xpath[256];
- char *ret = NULL;
-
- *_done = 0;
- snprintf(xpath, sizeof(xpath), "%s/event[%d]/@name",
- base, idx);
- if (ccs_get(ccsfd, xpath, &ret) != 0) {
- *_done = 1;
- return NULL;
- }
-
- ev = malloc(sizeof(*ev));
- if (!ev) {
- free(ret);
- return NULL;
- }
- memset(ev, 0, sizeof(*ev));
- ev->ev_name = ret;
-
- /* Get the script file / inline from config */
- ret = NULL;
- snprintf(xpath, sizeof(xpath), "%s/event[%d]/@file",
- base, idx);
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- ev->ev_script_file = ret;
- } else {
- snprintf(xpath, sizeof(xpath), "%s/event[%d]",
- base, idx);
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- ev->ev_script = ret;
- } else {
- goto out_fail;
- }
- }
-
- /* Get the priority ordering (must be nonzero) */
- ev->ev_prio = 99;
- ret = NULL;
- snprintf(xpath, sizeof(xpath), "%s/event[%d]/@priority",
- base, idx);
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- ev->ev_prio = atoi(ret);
- if (ev->ev_prio <= 0 || ev->ev_prio > EVENT_PRIO_COUNT) {
- logt_print(LOG_ERR,
- "event %s: priority %s invalid\n",
- ev->ev_name, ret);
- goto out_fail;
- }
- free(ret);
- }
-
- /* Get the event class */
- snprintf(xpath, sizeof(xpath), "%s/event[%d]/@class",
- base, idx);
- ret = NULL;
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- snprintf(xpath, sizeof(xpath), "%s/event[%d]",
- base, idx);
- if (!strcasecmp(ret, "node")) {
- ev->ev_type = EVENT_NODE;
- if (get_node_event(ccsfd, xpath, ev) < 0)
- goto out_fail;
- } else if (!strcasecmp(ret, "service") ||
- !strcasecmp(ret, "resource") ||
- !strcasecmp(ret, "rg") ) {
- ev->ev_type = EVENT_RG;
- if (get_rg_event(ccsfd, xpath, ev) < 0)
- goto out_fail;
- } else if (!strcasecmp(ret, "config") ||
- !strcasecmp(ret, "reconfig")) {
- ev->ev_type = EVENT_CONFIG;
- if (get_config_event(ccsfd, xpath, ev) < 0)
- goto out_fail;
- } else {
- logt_print(LOG_ERR,
- "event %s: class %s unrecognized\n",
- ev->ev_name, ret);
- goto out_fail;
- }
-
- free(ret);
- ret = NULL;
- }
-
- return ev;
-out_fail:
- if (ret)
- free(ret);
- deconstruct_event(ev);
- return NULL;
-}
-
-
-static event_t *
-get_default_event(void)
-{
- event_t *ev;
- char xpath[1024];
-
- ev = malloc(sizeof(*ev));
- if (!ev)
- return NULL;
- memset(ev, 0, sizeof(*ev));
- ev->ev_name = strdup("Default");
-
- /* Get the script file / inline from config */
- snprintf(xpath, sizeof(xpath), "%s/default_event_script.sl",
- RESOURCE_ROOTDIR);
-
- ev->ev_prio = 100;
- ev->ev_type = EVENT_NONE;
- ev->ev_script_file = strdup(xpath);
- if (!ev->ev_script_file || ! ev->ev_name) {
- deconstruct_event(ev);
- return NULL;
- }
-
- return ev;
-}
-
-
-/**
- * similar API to failover domain
- */
-int
-construct_events(int ccsfd, event_table_t **events)
-{
- char xpath[256];
- event_t *ev;
- int x = 1, done = 0;
-
- /* Allocate the event list table */
- *events = malloc(sizeof(event_table_t) +
- sizeof(event_t) * (EVENT_PRIO_COUNT+1));
- if (!*events)
- return -1;
- memset(*events, 0, sizeof(event_table_t) +
- sizeof(event_t) * (EVENT_PRIO_COUNT+1));
- (*events)->max_prio = EVENT_PRIO_COUNT;
-
- snprintf(xpath, sizeof(xpath),
- RESOURCE_TREE_ROOT "/events");
-
- do {
- ev = get_event(ccsfd, xpath, x++, &done);
- if (ev)
- list_insert(&((*events)->entries[ev->ev_prio]), ev);
- } while (!done);
-
- ev = get_default_event();
- if (ev)
- list_insert(&((*events)->entries[ev->ev_prio]), ev);
-
- return 0;
-}
-
-
-void
-print_event(FILE *fp, event_t *ev)
-{
- fprintf(fp, " Name: %s\n", ev->ev_name);
-
- switch(ev->ev_type) {
- case EVENT_NODE:
- fprintf(fp, " Node %d State %d\n", ev->ev.node.ne_nodeid,
- ev->ev.node.ne_state);
- break;
- case EVENT_RG:
- fprintf(fp, " RG %s State %s\n", ev->ev.group.rg_name,
- rg_state_str(ev->ev.group.rg_state));
- break;
- case EVENT_CONFIG:
- fprintf(fp, " Config change - unsupported\n");
- break;
- default:
- fprintf(fp, " (Any event)\n");
- break;
- }
-
- if (ev->ev_script) {
- fprintf(fp, " Inline script.\n");
- } else {
- fprintf(fp, " File: %s\n", ev->ev_script_file);
- }
-}
-
-
-void
-dump_events(FILE *fp, event_table_t *events)
-{
- int x, y;
- event_t *ev;
-
- for (x = 0; x <= events->max_prio; x++) {
- if (!events->entries[x])
- continue;
- fprintf(fp, "Event Priority Level %d:\n", x);
- list_for(&(events->entries[x]), ev, y) {
- print_event(fp, ev);
- }
- }
-}
-
-
-void
-print_events(event_table_t *events)
-{
- dump_events(stdout, events);
-}
-
-
-void
-deconstruct_events(event_table_t **eventsp)
-{
- int x;
- event_table_t *events = *eventsp;
- event_t *ev = NULL;
-
- if (!events)
- return;
-
- for (x = 0; x <= events->max_prio; x++) {
- while ((ev = (events->entries[x]))) {
- list_remove(&(events->entries[x]), ev);
- deconstruct_event(ev);
- }
- }
-
- free(events);
- *eventsp = NULL;
-}
-
-
diff --git a/rgmanager/src/daemons/fo_domain.c b/rgmanager/src/daemons/fo_domain.c
deleted file mode 100644
index 0ae1344..0000000
--- a/rgmanager/src/daemons/fo_domain.c
+++ /dev/null
@@ -1,655 +0,0 @@
-/** @file
- * Fail-over Domain & Preferred Node Ordering Driver. Ripped right from
- * the clumanager 1.2 code base.
- *
- * April 2006 - Nofailback option added to restrict failover behavior in ordered
- * + restricted failover domains by Josef Whiter
- */
-#include <string.h>
-#include <list.h>
-#include <logging.h>
-#include <resgroup.h>
-#include <restart_counter.h>
-#include <reslist.h>
-#include <ccs.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <members.h>
-#include <sets.h>
-#include <fo_domain.h>
-#include <groups.h>
-
-
-//#define DEBUG
-
-#ifdef NO_CCS
-#define ccs_get(fd, query, ret) conf_get(query, ret)
-#endif
-
-/*
- <failoverdomains>
- <failoverdomain name="foo">
- <failoverdomainnode name="member" priority="1"/>
- <failoverdomainnode name="member2" priority="1"/>
- <failoverdomainnode name="member3" priority="2"/>
- </failoverdomain>
- </failoverdomains>
- */
-
-static fod_node_t *
-#ifndef NO_CCS
-fod_get_node(int ccsfd, char *base, int idx, fod_t *domain)
-#else
-fod_get_node(int __attribute__((unused)) ccsfd, char *base, int idx, fod_t *domain)
-#endif
-{
- fod_node_t *fodn;
- char xpath[256];
- char *ret = NULL;
-
- snprintf(xpath, sizeof(xpath), "%s/failoverdomainnode[%d]/@name",
- base, idx);
- if (ccs_get(ccsfd, xpath, &ret) != 0)
- return NULL;
-
- list_do(&domain->fd_nodes, fodn) {
- if (strcasecmp(ret, fodn->fdn_name))
- continue;
-
- logt_print(LOG_ERR, "#30: Node %s defined multiple times in "
- "domain %s\n", ret, domain->fd_name);
- free(ret);
- return NULL;
- } while (!list_done(&domain->fd_nodes, fodn));
-
- fodn = malloc(sizeof(*fodn));
- if (!fodn) {
- free(ret);
- return NULL;
- }
- memset(fodn, 0, sizeof(*fodn));
-
- /* Already malloc'd; simply store */
- fodn->fdn_name = ret;
- fodn->fdn_prio = 0;
-
- snprintf(xpath, sizeof(xpath),
- "/cluster/clusternodes/clusternode[@name=\"%s\"]/@nodeid",
- ret);
- if (ccs_get(ccsfd, xpath, &ret) != 0) {
- logt_print(LOG_WARNING, "Node %s has no nodeid attribute\n",
- fodn->fdn_name);
- fodn->fdn_nodeid = -1;
- } else {
- /* 64-bit-ism on rhel4? */
- fodn->fdn_nodeid = atoi(ret);
- free(ret);
- }
-
- /* Don't even bother getting priority if we're not ordered (it's set
- to 0 above */
- if (!(domain->fd_flags & FOD_ORDERED))
- return fodn;
-
- snprintf(xpath, sizeof(xpath), "%s/failoverdomainnode[%d]/@priority",
- base, idx);
- if (ccs_get(ccsfd, xpath, &ret) != 0)
- return fodn;
-
- fodn->fdn_prio = atoi(ret);
- if (fodn->fdn_prio > 100 || fodn->fdn_prio <= 0)
- fodn->fdn_prio = 0;
- free(ret);
-
- return fodn;
-}
-
-
-static fod_t *
-fod_get_domain(int ccsfd, char *base, int idx, fod_t **domains)
-{
- fod_t *fod;
- fod_node_t *fodn;
- char xpath[256];
- char *ret;
- int x = 1;
-
- snprintf(xpath, sizeof(xpath), "%s/failoverdomain[%d]/@name",
- base, idx);
- if (ccs_get(ccsfd, xpath, &ret) != 0)
- return NULL;
-
- list_do(domains, fod) {
- if (strcasecmp(fod->fd_name, ret))
- continue;
-
- logt_print(LOG_ERR, "#31: Domain %s defined multiple times\n",
- ret);
- free(ret);
- return NULL;
- } while (!list_done(domains, fod));
-
- fod = malloc(sizeof(*fod));
- if (!fod) {
- free(ret);
- return NULL;
- }
- memset(fod, 0, sizeof(*fod));
- fod->fd_name = ret;
- fod->fd_nodes = 0;
- fod->fd_flags = 0;
-
- snprintf(xpath, sizeof(xpath), "%s/failoverdomain[%d]/@ordered",
- base, idx);
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- if (atoi(ret) != 0)
- fod->fd_flags |= FOD_ORDERED;
- free(ret);
- }
-
- snprintf(xpath, sizeof(xpath), "%s/failoverdomain[%d]/@restricted",
- base, idx);
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- if (atoi(ret) != 0)
- fod->fd_flags |= FOD_RESTRICTED;
- free(ret);
- }
-
- snprintf(xpath, sizeof(xpath), "%s/failoverdomain[%d]/@nofailback",
- base, idx);
- if (ccs_get(ccsfd, xpath, &ret) == 0) {
- if (atoi(ret) != 0)
- fod->fd_flags |= FOD_NOFAILBACK;
- free(ret);
- }
-
- snprintf(xpath, sizeof(xpath), "%s/failoverdomain[%d]",
- base, idx);
-
- do {
- fodn = fod_get_node(ccsfd, xpath, x++, fod);
- if (fodn) {
- /*
- list_do(&fod->fd_nodes, curr) {
- // insert sorted
- if (fodn->fdn_prio < curr->fdn_prio) {
- list_insert(&fod->fd_nodes, fodn);
- if (curr == fod->fd_nodes)
- fod->fd_nodes = fodn;
- }
- } while (!list_done(&fod->fd_nodes, curr));
- */
- list_insert(&fod->fd_nodes, fodn);
- }
- } while (fodn);
-
- return fod;
-}
-
-
-int
-construct_domains(int ccsfd, fod_t **domains)
-{
- char xpath[256];
- int x = 1;
- fod_t *fod;
-
- snprintf(xpath, sizeof(xpath),
- RESOURCE_TREE_ROOT "/failoverdomains");
-
- do {
- fod = fod_get_domain(ccsfd, xpath, x++, domains);
- if (fod) {
- list_insert(domains, fod);
- }
- } while (fod);
-
- return 0;
-}
-
-
-void
-deconstruct_domains(fod_t **domains)
-{
- fod_t *domain = NULL;
- fod_node_t *node;
-
- while ((domain = *domains)) {
- list_remove(domains, domain);
- while ((node = domain->fd_nodes)) {
- list_remove(&domain->fd_nodes, node);
- if (node->fdn_name)
- free(node->fdn_name);
- free(node);
- }
-
- if (domain->fd_name)
- free(domain->fd_name);
- free(domain);
- }
-}
-
-
-void
-dump_domains(FILE *fp, fod_t **domains)
-{
- fod_t *fod;
- fod_node_t *fodn = NULL;
- /*
- int x;
- int *node_set = NULL;
- int node_set_len = 0;
- */
-
- list_do(domains, fod) {
- fprintf(fp, "Failover domain: %s\n", fod->fd_name);
- fprintf(fp, "Flags: ");
- if (!fod->fd_flags) {
- fprintf(fp, "none\n");
- } else {
- if (fod->fd_flags & FOD_ORDERED)
- fprintf(fp, "Ordered ");
- if (fod->fd_flags & FOD_RESTRICTED)
- fprintf(fp, "Restricted ");
- if (fod->fd_flags & FOD_NOFAILBACK)
- fprintf(fp, "No Failback");
- fprintf(fp, "\n");
- }
-
- list_do(&fod->fd_nodes, fodn) {
- fprintf(fp, " Node %s (id %d, priority %d)\n",
- fodn->fdn_name, fodn->fdn_nodeid,
- fodn->fdn_prio);
- } while (!list_done(&fod->fd_nodes, fodn));
-
- /*
- node_domain_set(fod, &node_set, &node_set_len);
- fprintf(fp, " Failover Order = {");
- for (x = 0; x < node_set_len; x++) {
- fprintf(fp, " %d ", node_set[x]);
- }
- free(node_set);
- fprintf(fp, "}\n");
- */
-
- } while (!list_done(domains, fod));
-}
-
-
-void
-print_domains(fod_t **domains)
-{
- dump_domains(stdout, domains);
-}
-
-
-/**
- * Check to see if a given node is the current preferred node within a domain
- * on which we should start the service...
- * @param nodename Node/member name.
- * @param domain Existing domain.
- * @param membership Current membership mask.
- * @return 0 for No, All domain members offline.
- * 1 for No, 1+ Domain member(s) online.
- * 2 for Yes, Not lowest-ordered, online member.
- * 3 for Yes, Lowest-ordered, online member.
- */
-static int
-node_in_domain(char *nodename, fod_t *domain,
- cluster_member_list_t *membership)
-{
- int online = 0, member_match = 0, preferred = 100, myprio = -1;
- fod_node_t *fodn;
-
- list_do(&domain->fd_nodes, fodn) {
- /*
- * We have to check the membership mask here so that
- * we can decide whether or not 'nodename' is the lowest
- * ordered node.
- */
- if (!memb_online(membership,
- memb_name_to_id(membership, fodn->fdn_name)))
- continue;
-
- /*
- * If we get here, we know:
- * A member of the domain is online somewhere
- */
- online = 1;
- if (!strcmp(nodename, fodn->fdn_name)) {
- /*
- * If we get here, we know:
- * We are a member of the domain.
- */
- member_match = 1;
- myprio = fodn->fdn_prio;
- }
-
- if (fodn->fdn_prio < preferred)
- preferred = fodn->fdn_prio;
- } while (!list_done(&domain->fd_nodes, fodn));
-
- if (!online)
- return 0;
-
- if (!member_match)
- return 1;
-
- /* Figure out if we're the in the most-preferred group */
- preferred = (myprio <= preferred);
- if (!preferred)
- return 2;
-
- return 3;
-}
-
-
-int
-node_domain_set(fod_t **domains, char *name, int **ret, int *retlen, int *flags)
-{
- int x, i, j;
- int *tmpset = NULL;
- int ts_count;
- fod_node_t *fodn;
- fod_t *domain;
- int found = 0;
-
- list_for(domains, domain, x) {
- if (!strcasecmp(domain->fd_name, name)) {
- found = 1;
- break;
- }
- } // while (!list_done(&_domains, fod));
-
- if (!found)
- return -1;
-
- /* Count domain length */
- list_for(&domain->fd_nodes, fodn, x) { }
-
- *retlen = 0;
- *ret = malloc(sizeof(int) * x);
- if (!(*ret))
- return -1;
- tmpset = malloc(sizeof(int) * x);
- if (!tmpset) {
- free(*ret);
- return -1;
- }
-
- *flags = domain->fd_flags;
-
- if (domain->fd_flags & FOD_ORDERED) {
- for (i = 1; i <= 100; i++) {
-
- ts_count = 0;
- list_for(&domain->fd_nodes, fodn, x) {
- if (fodn->fdn_prio == i) {
- s_add(tmpset, &ts_count,
- fodn->fdn_nodeid);
- }
- }
-
- if (!ts_count)
- continue;
-
- /* Shuffle stuff at this prio level */
- if (ts_count > 1)
- s_shuffle(tmpset, ts_count);
- for (j = 0; j < ts_count; j++)
- s_add(*ret, retlen, tmpset[j]);
- }
- }
-
- /* Add unprioritized nodes */
- ts_count = 0;
- list_for(&domain->fd_nodes, fodn, x) {
- if (!fodn->fdn_prio) {
- s_add(tmpset, &ts_count,
- fodn->fdn_nodeid);
- }
- }
-
- if (!ts_count) {
- free(tmpset);
- return 0;
- }
-
- /* Shuffle stuff at this prio level */
- if (ts_count > 1)
- s_shuffle(tmpset, ts_count);
- for (j = 0; j < ts_count; j++)
- s_add(*ret, retlen, tmpset[j]);
-
- free(tmpset);
- return 0;
-}
-
-
-/**
- * See if a given nodeid should start a specified service svcid.
- *
- * @param nodeid The node ID in question.
- * @param membership Current membership mask.
- * @param rg_name The resource group name in question.
- * @param domains List of failover domains.
- * @return 0 on NO, 1 for YES
- */
-int
-node_should_start(int nodeid, cluster_member_list_t *membership,
- const char *rg_name, fod_t **domains)
-{
- char *nodename = NULL;
- char domainname[128] = "";
- int ordered = 0;
- int restricted = 0;
- int nofailback = 0;
- fod_t *fod = NULL;
- int found = 0;
-#ifndef NO_CCS
- int owned_by_node = 0, started = 0, no_owner = 0;
- rg_state_t svc_state;
- struct dlm_lksb lockp;
-#endif
-
- /*
- * Um, if the node isn't online...
- */
- if (!memb_online(membership, nodeid)) {
-#ifdef DEBUG
- logt_print(LOG_DEBUG,"Member #%d is not online -> NO\n", nodeid);
-#endif
- return FOD_ILLEGAL;
- }
-
- nodename = memb_id_to_name(membership, nodeid);
-
-#ifndef NO_CCS /* XXX Testing only */
- if (group_property(rg_name, (char *)"domain",
- domainname, sizeof(domainname))) {
- /*
- * If no domain is present, then the node in question should
- * try to start the service.
- */
-#ifdef DEBUG
- logt_print(LOG_DEBUG,
- "Fail-over Domain for service %s nonexistent\n",
- rg_name);
-#endif
- return FOD_BEST;
- }
-#endif
-
- /*
- * Ok, we've got a failover domain associated with the service.
- * Let's see if the domain actually exists...
- */
- list_do(domains, fod) {
-
- if (!strcasecmp(fod->fd_name, domainname)) {
- found = 1;
- break;
- }
- } while (!list_done(domains, fod));
-
- if (!found) {
- /*
- * Domain doesn't exist! Weird...
- */
- logt_print(LOG_WARNING, "#66: Domain '%s' specified for resource "
- "group %s nonexistent!\n", domainname, rg_name);
- return FOD_BEST;
- }
-
- /*
- * Determine whtehter this domain has failback turned on or not..
- */
- nofailback = !!(fod->fd_flags & FOD_NOFAILBACK);
-
- /*
- * Determine whether this domain is restricted or not...
- */
- restricted = !!(fod->fd_flags & FOD_RESTRICTED);
-
- /*
- * Determine whether this domain is ordered or not...
- */
- ordered = !!(fod->fd_flags & FOD_ORDERED);
-
-#ifndef NO_CCS
- if(nofailback) {
- if (rg_lock(rg_name, &lockp) != 0) {
- logt_print(LOG_WARNING, "Error getting a lock\n");
- return FOD_BEST;
- }
-
- if (get_rg_state(rg_name, &svc_state) == RG_EFAIL) {
- /*
- * Couldn't get the service state, thats odd
- */
- logt_print(LOG_WARNING, "Problem getting state information for "
- "%s\n", rg_name);
- rg_unlock(&lockp);
- return FOD_BEST;
- }
- rg_unlock(&lockp);
-
- /*
- * Check to see if the service is started and if we are the owner in case of
- * restricted+owner+no failback
- */
- if (svc_state.rs_state == RG_STATE_STARTED || svc_state.rs_state == RG_STATE_STARTING)
- started = 1;
- if (svc_state.rs_owner == (uint32_t)nodeid)
- owned_by_node = 1;
- if (!memb_online(membership, svc_state.rs_owner))
- no_owner = 1;
- }
-#endif
-
- switch (node_in_domain(nodename, fod, membership)) {
- case 0:
- /*
- * Node is not a member of the domain and no members of the
- * domain are online.
- */
-#ifdef DEBUG
- logt_print(LOG_DEBUG, "Member #%d is not a member and no "
- "members are online\n", nodeid);
-#endif
- if (!restricted) {
-#ifdef DEBUG
- logt_print(LOG_DEBUG,"Restricted mode off -> BEST\n");
-#endif
- return FOD_BEST;
- }
-#ifdef DEBUG
- logt_print(LOG_DEBUG,"Restricted mode -> ILLEGAL\n");
-#endif
- return FOD_ILLEGAL;
- case 1:
- /*
- * Node is not a member of the domain and at least one member
- * of the domain is online.
- */
- /* In this case, we can ignore 'restricted' */
-#ifdef DEBUG
- logt_print(LOG_DEBUG, "Member #%d is not a member of domain %s "
- "and a member is online\n", nodeid, domainname);
-#endif
- if (!restricted) {
-#ifdef DEBUG
- logt_print(LOG_DEBUG,"Restricted mode off -> GOOD\n");
-#endif
- return FOD_GOOD;
- }
-#ifdef DEBUG
- logt_print(LOG_DEBUG,"Restricted mode -> ILLEGAL\n");
-#endif
- return FOD_ILLEGAL;
- case 2:
- /*
- * Node is a member of the domain, but is not the
- * lowest-ordered, online member.
- */
-#ifdef DEBUG
- logt_print(LOG_DEBUG, "Member #%d is a member, but is not the "
- "lowest-ordered\n", nodeid);
-#endif
- if (ordered) {
- /*
- * If we are ordered we want to see if failback is
- * turned on
- */
-#ifndef NO_CCS
- if (nofailback && started && owned_by_node && !no_owner) {
-#ifdef DEBUG
- logt_print(LOG_DEBUG,"Ordered mode and no "
- "failback -> BEST\n");
-#endif
- return FOD_BEST;
- }
-#endif
-#ifdef DEBUG
- logt_print(LOG_DEBUG,"Ordered mode -> BETTER\n");
-#endif
- return FOD_BETTER;
- }
-
-#ifdef DEBUG
- logt_print(LOG_DEBUG,"Not using ordered mode -> BEST\n");
-#endif
- return FOD_BEST;
- case 3:
- /*
- * Node is a member of the domain and is the lowest-ordered,
- * online member.
- */
-#ifndef NO_CCS
- if(nofailback && started && !owned_by_node && !no_owner) {
-#ifdef DEBUG
- logt_print(LOG_DEBUG, "Member #%d is the lowest-ordered "
- "memeber of the domain, but is not the owner "
- "-> BETTER\n", nodeid);
-#endif
- return FOD_BETTER;
- }
-#endif
-
- /* In this case, we can ignore 'ordered' */
-#ifdef DEBUG
- logt_print(LOG_DEBUG, "Member #%d is the lowest-ordered member "
- "of the domain -> BEST\n", nodeid);
-#endif
- return FOD_BEST;
- default:
- /* Do what? */
- logt_print(LOG_ERR, "#32: Code path error: "
- "Invalid return from node_in_domain()\n");
- return FOD_ILLEGAL;
- }
-
- /* not reached */
- return FOD_ILLEGAL;
-}
diff --git a/rgmanager/src/daemons/groups.c b/rgmanager/src/daemons/groups.c
deleted file mode 100644
index 13ab1f8..0000000
--- a/rgmanager/src/daemons/groups.c
+++ /dev/null
@@ -1,1986 +0,0 @@
-//#define DEBUG
-#include <platform.h>
-#include <resgroup.h>
-#include <restart_counter.h>
-#include <reslist.h>
-#include <vf.h>
-#include <message.h>
-#include <ccs.h>
-#include <logging.h>
-#include <members.h>
-#include <list.h>
-#include <reslist.h>
-#include <assert.h>
-#include <event.h>
-#include <sets.h>
-#include <fo_domain.h>
-#include <groups.h>
-
-/* Use address field in this because we never use it internally,
- and there is no extra space in the cman_node_t type.
- */
-
-#define cn_svccount cn_address.cna_address[0] /* Theses are uint8_t size */
-#define cn_svcexcl cn_address.cna_address[1]
-
-extern event_table_t *master_event_table;
-
-static int config_version = 0;
-static resource_t *_resources = NULL;
-static resource_rule_t *_rules = NULL;
-static resource_node_t *_tree = NULL;
-static fod_t *_domains = NULL;
-
-#ifdef WRAP_LOCKS
-pthread_mutex_t config_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-pthread_mutex_t status_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-#else
-pthread_mutex_t config_mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_mutex_t status_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
-pthread_rwlock_t resource_lock = PTHREAD_RWLOCK_INITIALIZER;
-
-void res_build_name(char *, size_t, resource_t *);
-static int _group_property(const char *groupname, const char *property,
- char *ret, size_t len);
-
-struct status_arg {
- msgctx_t *ctx;
- int fast;
-};
-
-
-/**
- See if a given node ID should start a resource, given cluster membership
-
- @see node_should_start
- */
-int
-node_should_start_safe(uint32_t nodeid, cluster_member_list_t *membership,
- const char *rg_name)
-{
- int ret;
-
- pthread_rwlock_rdlock(&resource_lock);
- ret = node_should_start(nodeid, membership, rg_name, &_domains);
- pthread_rwlock_unlock(&resource_lock);
-
- return ret;
-}
-
-
-int
-node_domain_set_safe(char *domainname, int **ret, int *retlen, int *flags)
-{
- int rv = 0;
- pthread_rwlock_rdlock(&resource_lock);
- rv = node_domain_set(&_domains, domainname, ret, retlen, flags);
- pthread_rwlock_unlock(&resource_lock);
-
- return rv;
-}
-
-
-int
-count_resource_groups(cluster_member_list_t *ml)
-{
- resource_t *res;
- resource_node_t *node;
- char rgname[64], *val;
- int x;
- rg_state_t st;
- struct dlm_lksb lockp;
- cman_node_t *mp;
-
- for (x = 0; x < ml->cml_count; x++) {
- ml->cml_members[x].cn_svccount = 0;
- ml->cml_members[x].cn_svcexcl = 0;
- }
-
- pthread_rwlock_rdlock(&resource_lock);
-
- list_do(&_tree, node) {
-
- res = node->rn_resource;
-
- res_build_name(rgname, sizeof(rgname), res);
-
- if (rg_lock(rgname, &lockp) < 0) {
- logt_print(LOG_ERR, "#XX: Unable to obtain cluster "
- "lock @ %s:%d: %s\n", __FILE__, __LINE__,
- strerror(errno));
- continue;
- }
-
- if (get_rg_state(rgname, &st) < 0) {
- logt_print(LOG_ERR, "#34: Cannot get status "
- "for service %s\n", rgname);
- rg_unlock(&lockp);
- continue;
- }
-
- rg_unlock(&lockp);
-
- if (st.rs_state != RG_STATE_STARTED &&
- st.rs_state != RG_STATE_STARTING)
- continue;
-
- mp = memb_id_to_p(ml, st.rs_owner);
- if (!mp)
- continue;
-
- ++mp->cn_svccount;
-
- val = (char *)res_attr_value(res, "exclusive");
- if (val && ((!strcmp(val, "yes") ||
- (atoi(val)>0))) ) {
- ++mp->cn_svcexcl;
- }
-
- } while (!list_done(&_tree, node));
-
- pthread_rwlock_unlock(&resource_lock);
- return 0;
-}
-
-
-static inline int
-is_exclusive_res(resource_t *res)
-{
- const char *val;
-
- val = res_attr_value(res, "exclusive");
- if (val && ((!strcmp(val, "yes") ||
- (atoi(val)>0))) ) {
- return 1;
- }
- return 0;
-}
-
-
-/* Locked exported function */
-int
-is_exclusive(const char *svcName)
-{
- int ret = 0;
- resource_t *res = NULL;
-
- pthread_rwlock_rdlock(&resource_lock);
- res = find_root_by_ref(&_resources, svcName);
-
- if (!res)
- ret = RG_ENOSERVICE;
- else
- ret = is_exclusive_res(res);
-
- pthread_rwlock_unlock(&resource_lock);
- return ret;
-}
-
-
-static resource_node_t *
-node_by_ref(resource_node_t **tree, const char *name)
-{
- resource_t *res;
- resource_node_t *node, *ret = NULL;
- char rgname[64];
- int x;
-
- list_for(tree, node, x) {
-
- res = node->rn_resource;
- res_build_name(rgname, sizeof(rgname), res);
-
- if (!strcasecmp(name, rgname)) {
- ret = node;
- break;
- }
- }
-
- return ret;
-}
-
-
-int
-count_resource_groups_local(cman_node_t *mp)
-{
- resource_t *res;
- resource_node_t *node;
- char rgname[64];
- rg_state_t st;
-
- mp->cn_svccount = 0;
- mp->cn_svcexcl = 0;
-
- pthread_rwlock_rdlock(&resource_lock);
-
- list_do(&_tree, node) {
-
- res = node->rn_resource;
-
- res_build_name(rgname, sizeof(rgname), res);
-
- if (get_rg_state_local(rgname, &st) < 0) {
- continue;
- }
-
- if (st.rs_state != RG_STATE_STARTED &&
- st.rs_state != RG_STATE_STARTING)
- continue;
-
- if (mp->cn_nodeid != (int)st.rs_owner)
- continue;
-
- ++mp->cn_svccount;
-
- if (is_exclusive_res(res))
- ++mp->cn_svcexcl;
-
- } while (!list_done(&_tree, node));
-
- pthread_rwlock_unlock(&resource_lock);
- return 0;
-}
-
-
-int
-have_exclusive_resources(void)
-{
- resource_t *res;
-
- pthread_rwlock_rdlock(&resource_lock);
-
- list_do(&_resources, res) {
- if (is_exclusive_res(res)) {
- pthread_rwlock_unlock(&resource_lock);
- return 1;
- }
-
- } while (!list_done(&_resources, res));
-
- pthread_rwlock_unlock(&resource_lock);
-
- return 0;
-}
-
-
-int
-check_exclusive_resources(cluster_member_list_t *membership,
- const char *svcName)
-{
- cman_node_t *mp;
- int exclusive, count, excl;
- resource_t *res;
-
- mp = memb_id_to_p(membership, my_id());
- assert(mp);
- count_resource_groups_local(mp);
- exclusive = mp->cn_svcexcl;
- count = mp->cn_svccount;
- pthread_rwlock_rdlock(&resource_lock);
- res = find_root_by_ref(&_resources, svcName);
- if (!res) {
- pthread_rwlock_unlock(&resource_lock);
- return RG_ENOSERVICE;
- }
-
- excl = is_exclusive_res(res);
- pthread_rwlock_unlock(&resource_lock);
- if (exclusive || (count && excl))
- return RG_YES;
-
- return 0;
-}
-
-
-/**
- Find the best target node for a service *besides* the current service
- owner. Takes into account:
-
- - Failover domain (ordering / restricted policy)
- - Exclusive service policy
- */
-uint32_t
-best_target_node(cluster_member_list_t *allowed, uint32_t owner,
- const char *rg_name, int lock)
-{
- int x;
- int highscore = 1;
- int score;
- uint32_t highnode = owner, nodeid;
- char *val;
- resource_t *res;
- int exclusive;
-
- if (lock)
- pthread_rwlock_rdlock(&resource_lock);
- count_resource_groups(allowed);
- if (lock)
- pthread_rwlock_unlock(&resource_lock);
-
- for (x=0; x < allowed->cml_count; x++) {
- if (!allowed->cml_members[x].cn_member)
- continue;
-
- nodeid = allowed->cml_members[x].cn_nodeid;
-
- /* Don't allow trying a restart just yet */
- if (owner != 0 && nodeid == owner)
- continue;
-
- if (lock)
- pthread_rwlock_rdlock(&resource_lock);
- score = node_should_start(nodeid, allowed, rg_name, &_domains);
- if (!score) { /* Illegal -- failover domain constraint */
- if (lock)
- pthread_rwlock_unlock(&resource_lock);
- continue;
- }
-
- /* Add 2 to score if it's an exclusive service and nodeid
- isn't running any services currently. Set score to 0 if
- it's an exclusive service and the target node already
- is running a service. */
- res = find_root_by_ref(&_resources, rg_name);
- if (!res) {
- if (lock)
- pthread_rwlock_unlock(&resource_lock);
- continue;
- }
- val = (char *)res_attr_value(res, "exclusive");
- exclusive = val && ((!strcmp(val, "yes") || (atoi(val)>0)));
-
- if (lock)
- pthread_rwlock_unlock(&resource_lock);
-
- if (exclusive) {
-
- if (allowed->cml_members[x].cn_svccount > 0) {
- /* Definitely not this guy */
- continue;
- } else {
- score += 2;
- }
- } else if (allowed->cml_members[x].cn_svcexcl) {
- /* This guy has an exclusive resource group.
- Can't relocate / failover to him. */
- continue;
- }
-
- if (score < highscore)
- continue;
-
- highnode = nodeid;
- highscore = score;
- }
-
- return highnode;
-}
-
-
-int
-check_depend(resource_t *res)
-{
- const char *val;
- rg_state_t rs;
-
- val = res_attr_value(res, "depend");
- if (!val)
- /* No dependency */
- return -1;
-
- if (get_rg_state_local(val, &rs) == 0)
- return (rs.rs_state == RG_STATE_STARTED);
-
- return 1;
-}
-
-
-int
-check_depend_safe(const char *rg_name)
-{
- resource_t *res;
- int ret;
-
- pthread_rwlock_rdlock(&resource_lock);
- res = find_root_by_ref(&_resources, rg_name);
- if (!res) {
- ret = -1;
- goto out_unlock;
- }
-
- ret = check_depend(res);
-out_unlock:
- pthread_rwlock_unlock(&resource_lock);
- return ret;
-}
-
-
-static int
-check_rdomain_crash(const char *svcName)
-{
- int *nodes = NULL, nodecount = 0;
- int *fd_nodes = NULL, fd_nodecount = 0, fl = 0;
- int *isect = NULL, icount = 0;
- char fd_name[256];
-
- if (_group_property(svcName, "domain", fd_name, sizeof(fd_name)) != 0)
- goto out_free;
-
- member_online_set(&nodes, &nodecount);
-
- if (node_domain_set(&_domains, fd_name, &fd_nodes,
- &fd_nodecount, &fl) != 0)
- goto out_free;
-
- if (!(fl & FOD_RESTRICTED))
- goto out_free;
-
- if (s_intersection(fd_nodes, fd_nodecount, nodes, nodecount,
- &isect, &icount) < 0)
- goto out_free;
-
- if (icount == 0) {
- logt_print(LOG_NOTICE, "Marking %s as stopped: "
- "Restricted domain unavailable\n", svcName);
- rt_enqueue_request(svcName, RG_STOP, NULL, 0, 0,
- 0, 0);
- }
-
-out_free:
- if (fd_nodes)
- free(fd_nodes);
- if (nodes)
- free(nodes);
- if (isect)
- free(isect);
-
- return 0;
-}
-
-
-/**
- Start or failback a resource group: if it's not running, start it.
- If it is running and we're a better member to run it, then ask for
- it.
- */
-static void
-consider_start(resource_node_t *node, char *svcName, rg_state_t *svcStatus,
- cluster_member_list_t *membership)
-{
- char *val;
- cman_node_t *mp;
- int autostart, exclusive;
- struct dlm_lksb lockp;
- int fod_ret;
-
- mp = memb_id_to_p(membership, my_id());
- assert(mp);
-
- /* Service cannot be started if Frozen */
- if (svcStatus->rs_flags & RG_FLAG_FROZEN)
- return;
- /*
- * Service must be not be running elsewhere to consider for a
- * local start.
- */
- if (svcStatus->rs_state == RG_STATE_STARTED &&
- svcStatus->rs_owner == (uint32_t)mp->cn_nodeid)
- return;
-
- if (svcStatus->rs_state == RG_STATE_DISABLED)
- return;
-
- /* Stopped, and hasn't been started yet. See if
- autostart is disabled. If it is, leave it stopped */
- if (svcStatus->rs_state == RG_STATE_STOPPED &&
- svcStatus->rs_transition == 0) {
- val = (char *)res_attr_value(node->rn_resource, "autostart");
- autostart = !(val && ((!strcmp(val, "no") ||
- (atoi(val)==0))));
- if (!autostart) {
- /*
- logt_print(LOG_DEBUG,
- "Skipping RG %s: Autostart disabled\n",
- svcName);
- */
- /*
- Mark non-autostart services as disabled to avoid
- confusion!
- */
- if (rg_lock(svcName, &lockp) < 0) {
- logt_print(LOG_ERR, "#XX: Unable to obtain cluster "
- "lock @ %s:%d: %s\n", __FILE__, __LINE__,
- strerror(errno));
- return;
- }
-
- if (get_rg_state(svcName, svcStatus) != 0) {
- logt_print(LOG_ERR, "#34: Cannot get status "
- "for service %s\n", svcName);
- rg_unlock(&lockp);
- return;
- }
-
- if (svcStatus->rs_transition == 0 &&
- svcStatus->rs_state == RG_STATE_STOPPED) {
- svcStatus->rs_state = RG_STATE_DISABLED;
- set_rg_state(svcName, svcStatus);
- }
-
- rg_unlock(&lockp);
-
- return;
- }
- }
-
- /* See if service this one depends on is running. If not,
- don't start it */
- if (check_depend(node->rn_resource) == 0) {
- logt_print(LOG_DEBUG,
- "Skipping RG %s: Dependency missing\n", svcName);
- return;
- }
-
- val = (char *)res_attr_value(node->rn_resource, "exclusive");
- exclusive = val && ((!strcmp(val, "yes") || (atoi(val)>0)));
-
- if (exclusive && mp->cn_svccount) {
- logt_print(LOG_DEBUG,
- "Skipping RG %s: Exclusive and I am running services\n",
- svcName);
- return;
- }
-
- /*
- Don't start other services if I'm running an exclusive
- service.
- */
- if (mp->cn_svcexcl) {
- logt_print(LOG_DEBUG,
- "Skipping RG %s: I am running an exclusive service\n",
- svcName);
- return;
- }
-
- /*
- * Start any stopped services, or started services
- * that are owned by a down node.
- */
- fod_ret = node_should_start(mp->cn_nodeid, membership,
- svcName, &_domains);
- if (fod_ret == FOD_BEST)
- rt_enqueue_request(svcName, RG_START, NULL, 0, mp->cn_nodeid,
- 0, 0);
- else if (fod_ret == FOD_ILLEGAL)
- check_rdomain_crash(svcName);
-}
-
-
-static void
-consider_relocate(const char *svcName, rg_state_t *svcStatus, uint32_t nodeid,
- cluster_member_list_t *membership)
-{
- int a, b, req = RG_RELOCATE;
-
- /*
- Service must be running locally in order to consider for
- a relocate
- */
- if ((svcStatus->rs_state != RG_STATE_STARTING &&
- svcStatus->rs_state != RG_STATE_STARTED) ||
- svcStatus->rs_owner != (uint32_t)my_id())
- return;
-
- /*
- * Send the resource group to a node if it's got a higher prio
- * to run the resource group.
- */
-#if 0
- if (best_target_node(membership, my_id(), svcName, 0) !=
- nodeid) {
- return;
- }
-#endif
- a = node_should_start(nodeid, membership, svcName, &_domains);
- b = node_should_start(my_id(), membership, svcName, &_domains);
-
- if (a <= b)
- return;
-
- if (group_migratory(svcName, 1)) {
- req = RG_MIGRATE;
- }
-
- logt_print(LOG_NOTICE, "%s %s to better node %s\n",
- req==RG_MIGRATE ? "Migrating":"Relocating",
- svcName,
- memb_id_to_name(membership, nodeid));
-
- rt_enqueue_request(svcName, req, NULL, 0, nodeid, 0, 0);
-}
-
-
-char **
-get_service_names(int *len)
-{
- resource_node_t *node = NULL;
- int nservices, ncopied = 0, x;
- char **ret = NULL;
- char rg_name[64];
-
- pthread_rwlock_rdlock(&resource_lock);
-
- nservices = 0;
- list_do(&_tree, node) {
- ++nservices;
- } while (!list_done(&_tree, node));
-
- ret = malloc(sizeof(char *) * (nservices + 1));
- if (!ret)
- goto out_fail;
-
- memset(ret, 0, sizeof(char *) * (nservices + 1));
- nservices = 0;
- list_for(&_tree, node, nservices) {
- res_build_name(rg_name, sizeof(rg_name),
- node->rn_resource);
-
- if (!strlen(rg_name))
- continue;
-
- ret[ncopied] = strdup(rg_name);
- if (ret[ncopied]) {
- ncopied++;
- } else {
- goto out_fail;
- }
- }
-
- if (len)
- *len = ncopied;
- pthread_rwlock_unlock(&resource_lock);
- return ret;
-
-out_fail:
- pthread_rwlock_unlock(&resource_lock);
- for (x = 0; x < ncopied; x++)
- free(ret[x]);
- if (ret)
- free(ret);
- return NULL;
-}
-
-
-
-
-
-/**
- * Called to decide what services to start locally during a node_event.
- * Originally a part of node_event, it is now its own function to cut down
- * on the length of node_event.
- *
- * @see node_event
- */
-int
-eval_groups(int local, uint32_t nodeid, int nodeStatus)
-{
- struct dlm_lksb lockp;
- char svcName[64], *nodeName;
- resource_node_t *node;
- rg_state_t svcStatus;
- cluster_member_list_t *membership;
- int ret, state_updated = 0;
-
- if (rg_locked()) {
- logt_print(LOG_DEBUG,
- "Resource groups locked; not evaluating\n");
- return -EAGAIN;
- }
-
- membership = member_list();
-
- pthread_rwlock_rdlock(&resource_lock);
-
- /* Requires read lock */
- count_resource_groups(membership);
-
- list_do(&_tree, node) {
-
- state_updated = 0;
- res_build_name(svcName, sizeof(svcName), node->rn_resource);
-
- /*
- * Lock the service information and get the current service
- * status.
- */
- if ((ret = rg_lock(svcName, &lockp)) < 0) {
- logt_print(LOG_ERR,
- "#33: Unable to obtain cluster lock: %s\n",
- strerror(-ret));
- pthread_rwlock_unlock(&resource_lock);
- free_member_list(membership);
- return ret;
- }
-
- if (get_rg_state(svcName, &svcStatus) != 0) {
- logt_print(LOG_ERR,
- "#34: Cannot get status for service %s\n",
- svcName);
- rg_unlock(&lockp);
- continue;
- }
-
- /* Mark the service as stopped if applicable */
- if ((svcStatus.rs_owner == nodeid && !nodeStatus) &&
- (svcStatus.rs_state == RG_STATE_STARTED ||
- svcStatus.rs_state == RG_STATE_RECOVER ||
- svcStatus.rs_state == RG_STATE_STARTING ||
- svcStatus.rs_state == RG_STATE_STOPPING )) {
-
- logt_print(LOG_DEBUG,
- "Marking %s on down member %d as stopped",
- svcName, nodeid);
-
- svcStatus.rs_last_owner = svcStatus.rs_owner;
- svcStatus.rs_state = RG_STATE_STOPPED;
- svcStatus.rs_owner = 0;
- svcStatus.rs_transition = (uint64_t)time(NULL);
- /* If host fails, we need to remember
- * frozen flag */
- svcStatus.rs_flags &= RG_FLAG_FROZEN;
-
- if (set_rg_state(svcName, &svcStatus) != 0) {
- logt_print(LOG_ERR, "Failed to update state"
- " of %s during recovery; cannot "
- "fail over", svcName);
- rg_unlock(&lockp);
- continue;
- }
-
- state_updated = 1;
- }
-
- rg_unlock(&lockp);
-
- if (state_updated) {
- /* don't do this with lock held */
- broadcast_event(svcName, RG_STATE_STOPPED, -1,
- svcStatus.rs_last_owner);
- }
-
- if (svcStatus.rs_owner == 0)
- nodeName = (char *)"none";
- else
- nodeName = memb_id_to_name(membership,
- svcStatus.rs_owner);
-
- /* Disabled/failed/in recovery? Do nothing */
- if ((svcStatus.rs_state == RG_STATE_DISABLED) ||
- (svcStatus.rs_state == RG_STATE_FAILED) ||
- (svcStatus.rs_state == RG_STATE_RECOVER)) {
- continue;
- }
-
- logt_print(LOG_DEBUG, "Evaluating RG %s, state %s, owner "
- "%s\n", svcName,
- rg_state_str(svcStatus.rs_state),
- nodeName);
-
- if ((local && nodeStatus) ||
- svcStatus.rs_state == RG_STATE_STOPPED) {
-
- consider_start(node, svcName, &svcStatus, membership);
-
- } else if (!local && !nodeStatus) {
-
- /*
- * Start any stopped services, or started services
- * that are owned by a down node.
- */
- consider_start(node, svcName, &svcStatus, membership);
-
- /*
- * TODO
- * Mark a service as 'stopped' if no members in its
- * restricted fail-over domain are running.
- */
- } else {
- /* Send to the node if that ndoe is a better
- owner for this service */
- consider_relocate(svcName, &svcStatus, nodeid,
- membership);
- }
-
- } while (!list_done(&_tree, node));
-
- pthread_rwlock_unlock(&resource_lock);
- free_member_list(membership);
-
- logt_print(LOG_DEBUG, "Event (%d:%d:%d) Processed\n", local,
- (int)nodeid, nodeStatus);
-
- return 0;
-}
-
-
-/**
- * Called to decide what services to start locally after a service event.
- *
- * @see eval_groups
- */
-int
-group_event(const char __attribute__ ((unused)) *rg_name,
- uint32_t state,
- int __attribute__ ((unused)) owner)
-{
- char svcName[64], *nodeName;
- resource_node_t *node;
- rg_state_t svcStatus;
- cluster_member_list_t *membership;
- int depend;
-
- if (rg_locked()) {
- logt_print(LOG_DEBUG,
- "Resource groups locked; not evaluating\n");
- return -EAGAIN;
- }
-
- membership = member_list();
- if (!membership)
- return -1;
-
- pthread_rwlock_rdlock(&resource_lock);
-
- /* Requires read lock */
- count_resource_groups(membership);
-
- list_do(&_tree, node) {
-
- res_build_name(svcName, sizeof(svcName), node->rn_resource);
-
- if (get_rg_state_local(svcName, &svcStatus) != 0)
- continue;
-
- if (svcStatus.rs_owner == 0)
- nodeName = (char *)"none";
- else
- nodeName = memb_id_to_name(membership,
- svcStatus.rs_owner);
-
- /* Disabled/failed/in recovery? Do nothing */
- if ((svcStatus.rs_state == RG_STATE_DISABLED) ||
- (svcStatus.rs_state == RG_STATE_FAILED) ||
- (svcStatus.rs_state == RG_STATE_RECOVER)) {
- continue;
- }
-
- depend = check_depend(node->rn_resource);
-
- /* Skip if we have no dependency */
- if (depend == -1)
- continue;
-
- /*
- If we have:
- (a) a met dependency
- (b) we're in the STOPPED state, and
- (c) our new service event is a started service
-
- Then see if we should start this other service as well.
- */
- if (depend == 1 &&
- svcStatus.rs_state == RG_STATE_STOPPED &&
- state == RG_STATE_STARTED) {
-
- logt_print(LOG_DEBUG, "Evaluating RG %s, state %s, owner "
- "%s\n", svcName,
- rg_state_str(svcStatus.rs_state),
- nodeName);
- consider_start(node, svcName, &svcStatus, membership);
- continue;
- }
-
- /*
- If we lost a dependency for this service and it's running
- locally, stop it.
- */
- if (depend == 0 &&
- svcStatus.rs_state == RG_STATE_STARTED &&
- svcStatus.rs_owner == (uint32_t)my_id()) {
-
- logt_print(LOG_WARNING, "Stopping service %s: Dependency missing\n",
- svcName);
- rt_enqueue_request(svcName, RG_STOP, NULL, 0, my_id(),
- 0, 0);
- }
-
- } while (!list_done(&_tree, node));
-
- pthread_rwlock_unlock(&resource_lock);
- free_member_list(membership);
-
- return 0;
-}
-
-
-/**
- Tells us if a resource group can be migrated.
- */
-int
-group_migratory(const char *groupname, int lock)
-{
- resource_node_t *rn;
- resource_t *res;
- int migrate = 0, x, ret = 0;
-
- if (lock)
- pthread_rwlock_rdlock(&resource_lock);
-
- res = find_root_by_ref(&_resources, groupname);
- if (!res) {
- /* Nonexistent or non-TL RG cannot be migrated */
- goto out_unlock;
- }
-
- for (x = 0; res->r_rule->rr_actions[x].ra_name; x++) {
- if (!strcmp(res->r_rule->rr_actions[x].ra_name,
- "migrate")) {
- migrate = 1;
- break;
- }
- }
-
- if (!migrate)
- goto out_unlock;
-
- list_do(&_tree, rn) {
- if (rn->rn_resource == res && rn->rn_child) {
- /* TL service w/ children cannot be migrated */
- goto out_unlock;
- }
- } while (!list_done(&_tree, rn));
-
-
- /* Ok, we have a migrate option to the resource group,
- the resource group has no children, and the resource
- group exists. We're all good */
- ret = 1;
-
-out_unlock:
- if (lock)
- pthread_rwlock_unlock(&resource_lock);
- return ret;
-}
-
-
-
-/**
- Perform an operation on a resource group. That is, walk down the
- tree for that resource group, performing the given operation on
- all children in the necessary order.
-
- XXX Needs to handle more return codes to be more OCF compliant
-
- @param groupname Resource group to operate on
- @param op Operation to perform
- @return 0 on success, 1 on failure/error.
- */
-int
-group_op(const char *groupname, int op)
-{
- resource_t *res;
- int ret = -1;
-
- pthread_rwlock_rdlock(&resource_lock);
- /* XXX get group from somewhere else */
- res = find_root_by_ref(&_resources, groupname);
- if (!res) {
- pthread_rwlock_unlock(&resource_lock);
- return -1;
- }
-
- switch (op) {
- case RG_START:
- ret = res_start(&_tree, res, NULL);
- break;
- case RG_STOP:
- ret = res_stop(&_tree, res, NULL);
- break;
- case RG_STATUS:
- ret = res_status(&_tree, res, NULL);
- break;
- case RG_STATUS_INQUIRY:
- ret = res_status_inquiry(&_tree, res, NULL);
- break;
- case RG_CONDSTOP:
- ret = res_condstop(&_tree, res, NULL);
- break;
- case RG_CONDSTART:
- ret = res_condstart(&_tree, res, NULL);
- break;
- case RG_CONVALESCE:
- ret = res_convalesce(&_tree, res, NULL);
- break;
- }
- pthread_rwlock_unlock(&resource_lock);
-
-#if 0
- /*
- Do NOT return error codes if we failed to stop for one of these
- reasons. It didn't start, either, so it's safe to assume that
- if the program wasn't installed, there's nothing to tear down.
- */
- if (op == RG_STOP) {
- switch(ret) {
- case OCF_RA_SUCCESS:
- case OCF_RA_NOT_INSTALLED:
- case OCF_RA_NOT_CONFIGURED:
- ret = 0;
- break;
- default:
- ret = 1;
- break;
- }
- }
-#endif
-
- return ret;
-}
-
-
-int
-group_migrate(const char *groupname, int target)
-{
- resource_node_t *rn = NULL, *tmp;
- resource_t *res;
- char *tgt_name;
- int ret = RG_ENOSERVICE;
- cluster_member_list_t *membership;
-
- if (target <= 0) {
- logt_print(LOG_WARNING,
- "Illegal node ID %d during migrate operation\n",
- target);
- return RG_EINVAL;
- }
-
- membership = member_list();
- if (!membership) {
- logt_print(LOG_ERR, "Unable to determine membership during "
- "migrate operation\n");
- return RG_EFAIL;
- }
-
- pthread_rwlock_rdlock(&resource_lock);
-
- tgt_name = memb_id_to_name(membership, target);
- if (!tgt_name) {
- logt_print(LOG_WARNING, "Node ID %d not in membership during "
- "migrate operation\n", target);
- ret = RG_EINVAL;
- goto out;
- }
-
- res = find_root_by_ref(&_resources, groupname);
- if (!res) {
- logt_print(LOG_WARNING,
- "Unable to find '%s' in resource list during"
- "migrate operation\n", groupname);
- goto out;
- }
-
- list_do(&_tree, tmp) {
- if (tmp->rn_resource == res) {
- rn = tmp;
- break;
- }
- } while (!list_done(&_tree, tmp));
-
- if (!rn) {
- logt_print(LOG_WARNING,
- "Unable to find '%s' it top level of resource "
- "tree during migrate operation\n", groupname);
- goto out;
- }
-
- logt_print(LOG_NOTICE, "Migrating %s to %s\n", groupname, tgt_name);
- ret = res_exec(rn, RS_MIGRATE, tgt_name, 0);
- if (ret == 0) {
- logt_print(LOG_NOTICE,
- "Migration of %s to %s completed\n",
- groupname, tgt_name);
- } else {
- logt_print(LOG_ERR,
- "Migration of %s to %s failed; return code %d\n",
- groupname, tgt_name, ret);
- }
-
-out:
- pthread_rwlock_unlock(&resource_lock);
- free_member_list(membership);
- return ret;
-}
-
-
-/**
- Gets an attribute of a resource group.
-
- @param groupname Name of group
- @param property Name of property to check for
- @param ret Preallocated return buffer
- @param len Length of buffer pointed to by ret
- @return 0 on success, -1 on failure.
- */
-static int
-_group_property(const char *groupname, const char *property,
- char *ret, size_t len)
-{
- resource_t *res = NULL;
- int x = 0;
-
- res = find_root_by_ref(&_resources, groupname);
- if (!res) {
- return -1;
- }
-
- for (; res->r_attrs[x].ra_name; x++) {
- if (strcasecmp(res->r_attrs[x].ra_name, property))
- continue;
- strncpy(ret, res->r_attrs[x].ra_value, len-1);
- ret[len-1] = '\0';
- return 0;
- }
-
- return -1;
-}
-
-
-int
-group_property(const char *groupname, const char *property,
- char *ret_val, size_t len)
-{
- int ret = -1;
- pthread_rwlock_rdlock(&resource_lock);
- ret = _group_property(groupname, property, ret_val, len);
- pthread_rwlock_unlock(&resource_lock);
- return ret;
-}
-
-
-/**
- Send the state of a resource group to a given file descriptor.
-
- @param fd File descriptor to send state to
- @param rgname Resource group name whose state we want to send.
- @see send_rg_states
- */
-static void
-send_rg_state(msgctx_t *ctx, char *rgname, int fast)
-{
- rg_state_msg_t msg, *msgp = &msg;
- struct dlm_lksb lockp;
-
- msgp->rsm_hdr.gh_magic = GENERIC_HDR_MAGIC;
- msgp->rsm_hdr.gh_length = sizeof(msg);
- msgp->rsm_hdr.gh_command = RG_STATUS;
-
- /* try fast read -- only if it fails and fast is not
- specified should we do the full locked read */
- if (get_rg_state_local(rgname, &msgp->rsm_state) != 0 &&
- !fast) {
- if (rg_lock(rgname, &lockp) < 0)
- return;
- if (get_rg_state(rgname, &msgp->rsm_state) < 0) {
- rg_unlock(&lockp);
- return;
- }
- rg_unlock(&lockp);
- }
-
- swab_rg_state_msg_t(msgp);
-
- if (msg_send(ctx, msgp, sizeof(msg)) < 0)
- perror("msg_send");
-}
-
-
-/**
- Send status from a thread because we don't want rgmanager's
- main thread to block in the case of DLM issues
- */
-static void *
-status_check_thread(void *arg)
-{
- msgctx_t *ctx = ((struct status_arg *)arg)->ctx;
- int fast = ((struct status_arg *)arg)->fast;
- resource_node_t *node;
- generic_msg_hdr hdr;
- char rg[64];
-
- free(arg);
-
- if (central_events_enabled()) {
- /* Never call get_rg_state() (distributed) if
- central events are enabled, otherwise we
- might overwrite the rg state with 'stopped'
- when it should be 'disabled' (e.g. autostart="0") */
- fast = 1;
- }
-
- /* See if we have a slot... */
- if (rg_inc_status() < 0) {
- /* Too many outstanding status checks. try again later. */
- msg_send_simple(ctx, RG_FAIL, RG_EAGAIN, 0);
- msg_close(ctx);
- msg_free_ctx(ctx);
- pthread_exit(NULL);
- }
-
- /*send_master_state(ctx);*/
-
- pthread_rwlock_rdlock(&resource_lock);
-
- list_do(&_tree, node) {
-
- res_build_name(rg, sizeof(rg), node->rn_resource);
- send_rg_state(ctx, rg, fast);
- } while (!list_done(&_tree, node));
-
- pthread_rwlock_unlock(&resource_lock);
-
- msg_send_simple(ctx, RG_SUCCESS, 0, 0);
-
- /* XXX wait for client to tell us it's done; I don't know why
- this is needed when doing fast I/O, but it is. */
- msg_receive(ctx, &hdr, sizeof(hdr), 10);
- msg_close(ctx);
- msg_free_ctx(ctx);
-
- rg_dec_status();
-
- pthread_exit(NULL);
-}
-
-
-/**
- Send all resource group states to a file descriptor
-
- @param fd File descriptor to send states to.
- @return 0
- */
-int
-send_rg_states(msgctx_t *ctx, int fast)
-{
- struct status_arg *arg;
- pthread_t newthread;
- pthread_attr_t attrs;
-
- arg = malloc(sizeof(struct status_arg));
- if (!arg) {
- msg_send_simple(ctx, RG_FAIL, 0, 0);
- return -1;
- }
-
- arg->ctx = ctx;
- arg->fast = fast;
-
- pthread_attr_init(&attrs);
- pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED);
- pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
- pthread_attr_setstacksize(&attrs, 65535);
-
- pthread_create(&newthread, &attrs, status_check_thread, arg);
- pthread_attr_destroy(&attrs);
-
- return 0;
-}
-
-
-int
-svc_exists(const char *svcname)
-{
- resource_node_t *node;
- int ret = 0;
- char rg[64];
-
- pthread_rwlock_rdlock(&resource_lock);
-
- list_do(&_tree, node) {
- res_build_name(rg, sizeof(rg), node->rn_resource);
-
- if (strcmp(rg, svcname) == 0) {
- ret = 1;
- break;
- }
- } while (!list_done(&_tree, node));
-
- pthread_rwlock_unlock(&resource_lock);
-
- return ret;
-}
-
-
-/*
- * Perform an operation on all resources groups.
- *
- * Returns the number of requests queued. This value is
- * only used during shutdown, where we queue RG_STOP_EXITING
- * only for services we have running locally as an optimization.
- */
-int
-rg_doall(int request, int block,
- const char __attribute__ ((unused)) *debugfmt)
-{
- resource_node_t *curr;
- rg_state_t svcblk;
- char rg[64];
- int queued = 0;
-
- pthread_rwlock_rdlock(&resource_lock);
- list_do(&_tree, curr) {
-
- /* Group name */
- res_build_name(rg, sizeof(rg), curr->rn_resource);
-
- //if (debugfmt)
- //logt_print(LOG_DEBUG, debugfmt, rg);
-
- /* Optimization: Don't bother even queueing the request
- during the exit case if we don't own it */
- if (request == RG_STOP_EXITING) {
- if (get_rg_state_local(rg, &svcblk) < 0)
- continue;
-
- /* Always run stop if we're the owner, regardless
- of state; otherwise, don't run stop */
- if (svcblk.rs_owner != (uint32_t)my_id())
- continue;
- }
-
- rt_enqueue_request(rg, request, NULL, 0,
- 0, 0, 0);
- ++queued;
- } while (!list_done(&_tree, curr));
-
- pthread_rwlock_unlock(&resource_lock);
-
- /* XXX during shutdown, if we're doing a simultaenous shutdown,
- this will cause this rgmanager to hang waiting for all the
- other rgmanagers to complete. */
- if (block)
- rg_wait_threads();
- return queued;
-}
-
-
-/**
- Stop changed resources.
- */
-static void *
-q_status_checks(void __attribute__ ((unused)) *arg)
-{
- resource_node_t *curr;
- rg_state_t svcblk;
- char rg[64];
- struct dlm_lksb lockp;
-
- /* Only one status thread at a time, please! */
- if (pthread_mutex_trylock(&status_mutex) != 0)
- pthread_exit(NULL);
-
- pthread_rwlock_rdlock(&resource_lock);
- list_do(&_tree, curr) {
-
- /* Group name */
- res_build_name(rg, sizeof(rg), curr->rn_resource);
-
- /* Local check - no one will make us take a service */
- if (get_rg_state_local(rg, &svcblk) < 0) {
- if (rg_lock(rg, &lockp) != 0)
- continue;
- if (get_rg_state(rg, &svcblk) < 0) {
- rg_unlock(&lockp);
- continue;
- }
- rg_unlock(&lockp);
- }
-
- if (svcblk.rs_owner != (uint32_t)my_id() ||
- (svcblk.rs_state != RG_STATE_STARTED &&
- svcblk.rs_state != RG_STATE_MIGRATE))
- continue;
-
- rt_enqueue_request(rg, RG_STATUS,
- NULL, 1, 0, 0, 0);
-
- } while (!list_done(&_tree, curr));
-
- pthread_rwlock_unlock(&resource_lock);
- pthread_mutex_unlock(&status_mutex);
-
- pthread_exit(NULL);
-}
-
-
-void
-do_status_checks(void)
-{
- pthread_attr_t attrs;
- pthread_t newthread;
-
- pthread_attr_init(&attrs);
- pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED);
- pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
- pthread_attr_setstacksize(&attrs, 65535);
-
- pthread_create(&newthread, &attrs, q_status_checks, NULL);
- pthread_attr_destroy(&attrs);
-}
-
-
-/**
- Stop changed resources.
- */
-static void
-do_condstops(void)
-{
- resource_node_t *curr;
- struct dlm_lksb lockp;
- rg_state_t svcblk;
- int need_kill;
- char rg[64];
-
- logt_print(LOG_INFO, "Stopping changed resources.\n");
-
- pthread_rwlock_rdlock(&resource_lock);
- list_do(&_tree, curr) {
-
- /* Group name */
- res_build_name(rg, sizeof(rg), curr->rn_resource);
-
- /* If we're not running it, no need to CONDSTOP */
- if (get_rg_state_local(rg, &svcblk) < 0) {
- continue;
- }
-
- if (svcblk.rs_owner != (uint32_t)my_id())
- continue;
-
- /* Set state to uninitialized if we're killing a RG */
- need_kill = 0;
- if (curr->rn_resource->r_flags & RF_NEEDSTOP) {
- need_kill = 1;
- logt_print(LOG_DEBUG, "Removing %s\n", rg);
- }
-
- if (!curr->rn_child && ((curr->rn_resource->r_rule->rr_flags &
- RF_DESTROY) == 0) && group_migratory(rg, 0) &&
- need_kill == 1) {
- /* Do something smart here: flip state? */
- logt_print(LOG_NOTICE,
- "%s removed from the config, but I am not stopping it.\n",
- rg);
- if (rg_lock(rg, &lockp) != 0)
- continue;
- if (get_rg_state(rg, &svcblk) < 0)
- goto cont;
- svcblk.rs_state = RG_STATE_DISABLED;
- set_rg_state(rg, &svcblk);
-cont:
- rg_unlock(&lockp);
- continue;
- }
-
- rt_enqueue_request(rg, need_kill ? RG_DISABLE : RG_CONDSTOP,
- NULL, 0, 0, 0, 0);
-
- } while (!list_done(&_tree, curr));
-
- pthread_rwlock_unlock(&resource_lock);
- rg_wait_threads();
-}
-
-
-/**
- Start changed resources.
- */
-static void
-do_condstarts(void)
-{
- resource_node_t *curr;
- char rg[64], *val;
- rg_state_t svcblk;
- int need_init, new_groups = 0, autostart;
- struct dlm_lksb lockp;
-
- logt_print(LOG_INFO, "Starting changed resources.\n");
-
- /* Pass 1: Start any normally changed resources */
- pthread_rwlock_rdlock(&resource_lock);
- list_do(&_tree, curr) {
-
- /* Group name */
- res_build_name(rg, sizeof(rg), curr->rn_resource);
-
- /* New RG. We'll need to initialize it. */
- need_init = 0;
- if (!(curr->rn_resource->r_flags & RF_RECONFIG) &&
- (curr->rn_resource->r_flags & RF_NEEDSTART))
- need_init = 1;
-
- if (!need_init) {
- if (get_rg_state_local(rg, &svcblk) < 0)
- continue;
- } else {
- if (rg_lock(rg, &lockp) != 0)
- continue;
-
- if (get_rg_state(rg, &svcblk) < 0) {
- rg_unlock(&lockp);
- continue;
- }
-
- rg_unlock(&lockp);
- }
-
- if (!need_init && svcblk.rs_owner != (uint32_t)my_id())
- continue;
-
- if (need_init) {
- ++new_groups;
- logt_print(LOG_NOTICE, "Initializing %s\n", rg);
- }
-
- if (!curr->rn_child && ((curr->rn_resource->r_rule->rr_flags &
- RF_INIT) == 0) && group_migratory(rg, 0) &&
- need_init == 1) {
- /* Do something smart here? */
- logt_print(LOG_NOTICE,
- "%s was added to the config, but I am not initializing it.\n",
- rg);
- continue;
- }
-
- rt_enqueue_request(rg, need_init ? RG_INIT : RG_CONDSTART,
- NULL, 0, 0, 0, 0);
-
- } while (!list_done(&_tree, curr));
-
- pthread_rwlock_unlock(&resource_lock);
- rg_wait_threads();
-
- if (!new_groups)
- return;
-
- /* Pass 2: Tag all new resource groups as stopped */
- pthread_rwlock_rdlock(&resource_lock);
- list_do(&_tree, curr) {
-
- /* Group name */
- res_build_name(rg, sizeof(rg), curr->rn_resource);
-
- /* New RG. We'll need to initialize it. */
- if (!(curr->rn_resource->r_flags & RF_NEEDSTART))
- continue;
-
- if (rg_lock(rg, &lockp) != 0)
- continue;
-
- if (get_rg_state(rg, &svcblk) < 0) {
- rg_unlock(&lockp);
- continue;
- }
-
- /* If it is a replacement of an old RG, it will
- be in the DISABLED state, which will prevent it
- from restarting. That's bad. However, if it's
- a truly new service, it will be in the UNINITIALIZED
- state, which will be caught by eval_groups. */
- if (svcblk.rs_state != RG_STATE_DISABLED) {
- rg_unlock(&lockp);
- continue;
- }
-
- /* Set it up for an auto-start */
- val = (char *)res_attr_value(curr->rn_resource, "autostart");
- autostart = !(val && ((!strcmp(val, "no") ||
- (atoi(val)==0))));
- if (autostart)
- svcblk.rs_state = RG_STATE_STOPPED;
- else
- svcblk.rs_state = RG_STATE_DISABLED;
-
- set_rg_state(rg, &svcblk);
-
- rg_unlock(&lockp);
-
- } while (!list_done(&_tree, curr));
- pthread_rwlock_unlock(&resource_lock);
-
- /* Pass 3: See if we should start new resource groups */
- eval_groups(1, my_id(), 1);
-}
-
-
-void
-dump_config_version(FILE *fp)
-{
- fprintf(fp, "Cluster configuration version %d\n\n", config_version);
-}
-
-
-void
-dump_resource_info(FILE *fp)
-{
- int x = central_events_enabled();
-
- pthread_rwlock_rdlock(&resource_lock);
- fprintf(fp, "=== Resource Agent Information ===\n");
- dump_resource_rules(fp, &_rules);
- fprintf(fp, "=== Defined Resources ===\n");
- dump_resources(fp, &_resources);
- fprintf(fp, "=== Failover Domains ===\n");
- dump_domains(fp, &_domains);
-
- if (x) {
- fprintf(fp, "=== Events ===\n");
- dump_events(fp, master_event_table);
- }
-
- fprintf(fp, "=== Resource Tree ===\n");
- dump_resource_tree(fp, &_tree);
- pthread_rwlock_unlock(&resource_lock);
-}
-
-
-/**
- Copy out the incarnations after doing CONDSTOPs
- */
-static int
-copy_incarnations(resource_t **leftres, resource_t **rightres)
-{
- resource_t *lc, *rc;
-
- list_do(leftres, lc) {
- rc = find_resource_by_ref(rightres, lc->r_rule->rr_type,
- primary_attr_value(lc));
- /* Resource does not exist */
- if (!rc)
- continue;
-
- /* Ok, see if the resource is the same */
- if (!rescmp(lc, rc))
- rc->r_incarnations = lc->r_incarnations;
- } while (!list_done(leftres, lc));
-
- return 0;
-}
-
-
-/**
- Initialize resource groups. This reads all the resource groups from
- CCS, builds the tree, etc. Ideally, we'll have a similar function
- performing deltas on the two trees so that we can fully support online
- resource group modification.
- */
-int
-init_resource_groups(int reconfigure, int do_init)
-{
- int fd, x, y, cnt;
-
- event_table_t *evt = NULL;
- resource_t *reslist = NULL, *res;
- resource_rule_t *rulelist = NULL, *rule;
- resource_node_t *tree = NULL;
- fod_t *domains = NULL, *fod;
- event_t *evp;
- char *val;
-
- if (reconfigure)
- logt_print(LOG_NOTICE, "Reconfiguring\n");
-
- logt_print(LOG_INFO, "Loading Service Data\n");
- logt_print(LOG_DEBUG, "Loading Resource Rules\n");
- if (load_resource_rules(RESOURCE_ROOTDIR, &rulelist) != 0) {
- return -1;
- }
- x = 0;
- list_do(&rulelist, rule) { ++x; } while (!list_done(&rulelist, rule));
- logt_print(LOG_DEBUG, "%d rules loaded\n", x);
-
- fd = ccs_lock();
- if (fd == -1) {
- logt_print(LOG_CRIT, "#5: Couldn't connect to ccsd!\n");
- return -1;
- }
-
- if (ccs_get(fd, "/cluster/@config_version", &val) == 0) {
- pthread_mutex_lock(&config_mutex);
- config_version = atoi(val);
- pthread_mutex_unlock(&config_mutex);
- free(val);
- }
-
- if (ccs_get(fd, "/cluster/rm/@statusmax", &val) == 0) {
- if (strlen(val))
- rg_set_statusmax(atoi(val));
- free(val);
- }
-
- /* Block operations that would break during configuration
- changes */
- rg_clear_initialized(FL_CONFIG);
-
- logt_print(LOG_DEBUG, "Building Resource Trees\n");
- /* About to update the entire resource tree... */
- if (load_resources(fd, &reslist, &rulelist) != 0) {
- logt_print(LOG_CRIT, "#6: Error loading services\n");
- destroy_resources(&reslist);
- destroy_resource_rules(&rulelist);
- ccs_unlock(fd);
- return -1;
- }
-
- load_resource_defaults(fd, &rulelist);
-
- if (build_resource_tree(fd, &tree, &rulelist, &reslist) != 0) {
- logt_print(LOG_CRIT, "#7: Error building resource tree\n");
- destroy_resource_tree(&tree);
- destroy_resources(&reslist);
- destroy_resource_rules(&rulelist);
- ccs_unlock(fd);
- return -1;
- }
-
- x = 0;
- list_do(&reslist, res) { ++x; } while (!list_done(&reslist, res));
- logt_print(LOG_DEBUG, "%d resources defined\n", x);
-
- logt_print(LOG_DEBUG, "Loading Failover Domains\n");
- construct_domains(fd, &domains);
- x = 0;
- list_do(&domains, fod) { ++x; } while (!list_done(&domains, fod));
- logt_print(LOG_DEBUG, "%d domains defined\n", x);
-
- logt_print(LOG_DEBUG, "Loading Event Triggers\n");
- construct_events(fd, &evt);
- cnt = 0;
- if (evt) {
- for (x=0; x <= evt->max_prio; x++) {
- if (!evt->entries[x])
- continue;
-
- y = 0;
-
- list_do(&evt->entries[x], evp) {
- ++y;
- } while (!list_done(&evt->entries[x], evp));
-
- cnt += y;
- }
- }
- logt_print(LOG_DEBUG, "%d events defined\n", cnt);
-
-
- /* Reconfiguration done */
- ccs_unlock(fd);
-
- if (reconfigure) {
- /* Calc tree deltas */
- pthread_rwlock_wrlock(&resource_lock);
- resource_delta(&_resources, &reslist);
- resource_tree_delta(&_tree, &tree);
- pthread_rwlock_unlock(&resource_lock);
-
- do_condstops();
-
- pthread_rwlock_rdlock(&resource_lock);
- copy_incarnations(&_resources, &reslist);
- pthread_rwlock_unlock(&resource_lock);
- }
-
- /* Swap in the new configuration */
- pthread_rwlock_wrlock(&resource_lock);
- if (_tree)
- destroy_resource_tree(&_tree);
- _tree = tree;
- if (_resources)
- destroy_resources(&_resources);
- _resources = reslist;
- if (_rules)
- destroy_resource_rules(&_rules);
- _rules = rulelist;
- if (_domains)
- deconstruct_domains(&_domains);
- _domains = domains;
- if (master_event_table)
- deconstruct_events(&master_event_table);
- master_event_table = evt;
- pthread_rwlock_unlock(&resource_lock);
-
- if (reconfigure) {
- /* Switch to read lock and do the up-half of the
- reconfig request */
- logt_print(LOG_INFO, "Restarting changed resources.\n");
- do_condstarts();
- } else {
- if (do_init) {
- /* Do initial stop-before-start */
- logt_print(LOG_INFO, "Initializing Services\n");
- rg_doall(RG_INIT, 1, "Initializing %s\n");
- logt_print(LOG_INFO, "Services Initialized\n");
- } else {
- logt_print(LOG_INFO, "Skipping stop-before-start: overridden by administrator\n");
- }
- rg_set_initialized(FL_INIT);
- }
- rg_set_initialized(FL_CONFIG);
-
- return 0;
-}
-
-
-void
-get_recovery_policy(const char *rg_name, char *buf, size_t buflen)
-{
- resource_t *res;
- const char *val;
-
- assert(buflen >= 1); /* and expect partial result if doesn't fit */
-
- pthread_rwlock_rdlock(&resource_lock);
-
- strncpy(buf, "restart", buflen-1);
- buf[buflen-1] = '\0';
-
- res = find_root_by_ref(&_resources, rg_name);
- if (res) {
- val = res_attr_value(res, "recovery");
- if (val) {
- strncpy(buf, val, buflen-1);
- /* Already terminated */
- }
- }
-
- pthread_rwlock_unlock(&resource_lock);
-}
-
-
-int
-get_service_property(const char *rg_name, const char *prop,
- char *buf, size_t buflen)
-{
- int ret = 0;
- resource_t *res;
- const char *val;
-
- memset(buf, 0, buflen);
-
-#if 0
- if (!strcmp(prop, "domain")) {
- /* not needed */
- strncpy(buf, "", buflen);
- } else if (!strcmp(prop, "autostart")) {
- strncpy(buf, "1", buflen);
- } else if (!strcmp(prop, "hardrecovery")) {
- strncpy(buf, "0", buflen);
- } else if (!strcmp(prop, "exclusive")) {
- strncpy(buf, "0", buflen);
- } else if (!strcmp(prop, "nfslock")) {
- strncpy(buf, "0", buflen);
- } else if (!strcmp(prop, "recovery")) {
- strncpy(buf, "restart", buflen);
- } else if (!strcmp(prop, "depend")) {
- /* not needed */
- strncpy(buf, "", buflen);
- } else {
- /* not found / no defaults */
- ret = -1;
- }
-#endif
-
- pthread_rwlock_rdlock(&resource_lock);
- res = find_root_by_ref(&_resources, rg_name);
- if (res) {
- val = res_attr_value(res, prop);
- if (val) {
- ret = 0;
- strncpy(buf, val, buflen);
- }
- }
- pthread_rwlock_unlock(&resource_lock);
-
-#if 0
- if (ret == 0)
- printf("%s(%s, %s) = %s\n", __FUNCTION__, rg_name, prop, buf);
- else
- printf("%s(%s, %s) = NOT FOUND\n", __FUNCTION__, rg_name, prop);
-#endif
-
- return ret;
-}
-
-
-int
-add_restart(const char *rg_name)
-{
- resource_node_t *node;
- int ret = 1;
-
- pthread_rwlock_rdlock(&resource_lock);
- node = node_by_ref(&_tree, rg_name);
- if (node) {
- ret = restart_add(node->rn_restart_counter);
- }
- pthread_rwlock_unlock(&resource_lock);
-
- return ret;
-}
-
-
-int
-check_restart(const char *rg_name)
-{
- resource_node_t *node;
- int ret = 0;
-
- pthread_rwlock_rdlock(&resource_lock);
- node = node_by_ref(&_tree, rg_name);
- if (node) {
- ret = restart_threshold_exceeded(node->rn_restart_counter);
- }
- pthread_rwlock_unlock(&resource_lock);
-
- return ret;
-}
-
-int
-clear_restart(const char *rg_name)
-{
- resource_node_t *node;
- int ret = 0;
-
- pthread_rwlock_rdlock(&resource_lock);
- node = node_by_ref(&_tree, rg_name);
- if (node) {
- ret = restart_clear(node->rn_restart_counter);
- }
- pthread_rwlock_unlock(&resource_lock);
-
- return ret;
-}
-
-
-void
-kill_resource_groups(void)
-{
- pthread_rwlock_wrlock(&resource_lock);
-
- destroy_resource_tree(&_tree);
- destroy_resources(&_resources);
- destroy_resource_rules(&_rules);
- deconstruct_domains(&_domains);
-
- pthread_rwlock_unlock(&resource_lock);
-}
diff --git a/rgmanager/src/daemons/main.c b/rgmanager/src/daemons/main.c
deleted file mode 100644
index d596e0d..0000000
--- a/rgmanager/src/daemons/main.c
+++ /dev/null
@@ -1,1283 +0,0 @@
-#include <platform.h>
-#include <ccs.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <rg_locks.h>
-#include <fcntl.h>
-#include <restart_counter.h>
-#include <resgroup.h>
-#include <reslist.h>
-#include <logging.h>
-#include <members.h>
-#include <msgsimple.h>
-#include <vf.h>
-#include <lock.h>
-#include <sys/socket.h>
-#include <message.h>
-#include <rg_queue.h>
-#include <malloc.h>
-#include <cman-private.h>
-#include <event.h>
-#include <members.h>
-#include <daemon_init.h>
-#include <groups.h>
-#include <rg_dbus.h>
-
-#include <cpglock-internal.h>
-
-#ifdef WRAP_THREADS
-void dump_thread_states(FILE *);
-#endif
-static int configure_rgmanager(int ccsfd, int debug, int *cluster_timeout);
-
-void flag_shutdown(int sig);
-
-int watchdog_init(void);
-
-
-int cluster_timeout = 10;
-int shutdown_pending = 0, running = 1, need_reconfigure = 0;
-char debug = 0; /* XXX* */
-static int signalled = 0;
-static uint8_t ALIGNED port = RG_PORT;
-static char *rgmanager_lsname = (char *)"rgmanager"; /* XXX default */
-static int status_poll_interval = DEFAULT_CHECK_INTERVAL;
-static int stops_queued = 0;
-
-static void
-segfault(int __attribute__ ((unused)) sig)
-{
- char ow[64];
- int err; // dumb error checking... will be replaced by logsys
-
- snprintf(ow, sizeof(ow), "PID %d Thread %d: SIGSEGV\n", getpid(),
- gettid());
- err = write(2, ow, strlen(ow));
- while(1)
- sleep(60);
-}
-
-
-static int
-send_exit_msg(msgctx_t *ctx)
-{
- msg_send_simple(ctx, RG_EXITING, my_id(), 0);
-
- return 0;
-}
-
-
-static void
-send_node_states(msgctx_t *ctx)
-{
- int x;
- event_master_t master;
- generic_msg_hdr hdr;
- cluster_member_list_t *ml = member_list();
-
- master.m_nodeid = 0;
- event_master_info_cached(&master);
-
- for (x = 0; x < ml->cml_count; x++) {
- if (ml->cml_members[x].cn_member == 1) {
- msg_send_simple(ctx, RG_STATUS_NODE,
- ml->cml_members[x].cn_nodeid,
- (ml->cml_members[x].cn_nodeid &&
- (ml->cml_members[x].cn_nodeid ==
- (int)master.m_nodeid)));
- }
- }
- msg_send_simple(ctx, RG_SUCCESS, 0, 0);
- msg_receive(ctx, &hdr, sizeof(hdr), 10);
- free_member_list(ml);
-}
-
-
-/**
- This updates our local membership view and handles whether or not we
- should exit, as well as determines node transitions (thus, calling
- node_event()).
-
- @see node_event
- @return 0
- */
-static int
-membership_update(void)
-{
- cluster_member_list_t *new_ml = NULL, *node_delta = NULL,
- *old_membership = NULL;
- int x;
- int me = 0;
- cman_handle_t h;
- int quorate;
-
- h = cman_init(NULL);
- quorate = cman_is_quorate(h);
- if (!quorate) {
- cman_finish(h);
-
- if (!rg_quorate())
- return -1;
-
- logt_print(LOG_EMERG, "#1: Quorum Dissolved\n");
- rg_set_inquorate();
- member_list_update(NULL);/* Clear member list */
- rg_lockall(L_SYS);
- rg_doall(RG_INIT, 1, "Emergency stop of %s\n");
-#ifndef USE_OPENAIS
- logt_print(LOG_DEBUG, "Invalidating local VF cache\n");
- vf_invalidate();
-#endif
- logt_print(LOG_DEBUG, "Flushing resource group cache\n");
- kill_resource_groups();
- rg_clear_initialized(0);
- return -1;
- } else if (!rg_quorate()) {
-
- rg_set_quorate();
- rg_unlockall(L_SYS);
- rg_unlockall(L_USER);
- logt_print(LOG_NOTICE, "Quorum Regained\n");
- }
-
- old_membership = member_list();
- new_ml = get_member_list(h);
- memb_mark_down(new_ml, 0);
-
- for(x=0; new_ml && x<new_ml->cml_count;x++) {
- if (new_ml->cml_members[x].cn_nodeid == 0) {
- new_ml->cml_members[x].cn_member = 0;
- }
- }
-
- for (x = 0; new_ml && x < new_ml->cml_count; x++) {
-
- if (new_ml->cml_members[x].cn_member == 0) {
- printf("skipping %d - node not member\n",
- new_ml->cml_members[x].cn_nodeid);
- continue;
- }
- if (new_ml->cml_members[x].cn_nodeid == my_id())
- continue;
-
-#ifdef DEBUG
- printf("Checking for listening status of %d\n",
- new_ml->cml_members[x].cn_nodeid);
-#endif
-
- do {
- quorate = cman_is_listening(h,
- new_ml->cml_members[x].cn_nodeid,
- port);
-
- if (quorate == 0) {
- logt_print(LOG_DEBUG, "Node %d is not listening\n",
- new_ml->cml_members[x].cn_nodeid);
- new_ml->cml_members[x].cn_member = 0;
- break;
- } else if (quorate < 0) {
- if (errno == ENOTCONN) {
- new_ml->cml_members[x].cn_member = 0;
- break;
- }
- perror("cman_is_listening");
- usleep(50000);
- continue;
- }
-#ifdef DEBUG
- else {
- printf("Node %d IS listening\n",
- new_ml->cml_members[x].cn_nodeid);
- }
-#endif
- break;
- } while(1);
- }
-
- cman_finish(h);
- member_list_update(new_ml);
-
- /*
- * Handle nodes lost. Do our local node event first.
- */
- node_delta = memb_lost(old_membership, new_ml);
-
- me = memb_online(node_delta, my_id());
- if (me) {
- /* Should not happen */
- logt_print(LOG_INFO, "State change: LOCAL OFFLINE\n");
- if (node_delta)
- free_member_list(node_delta);
- node_event(1, my_id(), 0, 0);
- /* NOT REACHED */
- /* Following simply quiets static analyzers */
- exit(1);
- }
-
- for (x=0; node_delta && x < node_delta->cml_count; x++) {
-
- logt_print(LOG_INFO, "State change: %s DOWN\n",
- node_delta->cml_members[x].cn_name);
- /* Don't bother evaluating anything resource groups are
- locked. This is just a performance thing */
- if (!rg_locked()) {
- node_event_q(0, node_delta->cml_members[x].cn_nodeid,
- 0, 0);
- } else {
- logt_print(LOG_DEBUG, "Not taking action - services"
- " locked\n");
- }
- }
-
- free_member_list(node_delta);
-
- /*
- * Handle nodes gained. Do our local node event first.
- */
- node_delta = memb_gained(old_membership, new_ml);
-
- me = memb_online(node_delta, my_id());
- if (me) {
- logt_print(LOG_INFO, "State change: Local UP\n");
- node_event_q(1, my_id(), 1, 1);
- }
-
- for (x=0; node_delta && x < node_delta->cml_count; x++) {
-
- if (!node_delta->cml_members[x].cn_member)
- continue;
-
- if (node_delta->cml_members[x].cn_nodeid == my_id())
- continue;
-
- logt_print(LOG_INFO, "State change: %s UP\n",
- node_delta->cml_members[x].cn_name);
- node_event_q(0, node_delta->cml_members[x].cn_nodeid, 1, 1);
- }
-
- free_member_list(node_delta);
- free_member_list(new_ml);
- free_member_list(old_membership);
-
- rg_unlockall(L_SYS);
-
- return 0;
-}
-
-
-static int
-lock_commit_cb(char __attribute__ ((unused)) *key,
- uint64_t __attribute__ ((unused)) viewno,
- void *data, uint32_t datalen)
-{
- char lockstate;
-
- if (datalen != 1) {
- logt_print(LOG_WARNING, "%s: invalid data length!\n", __FUNCTION__);
- free(data);
- return 0;
- }
-
- lockstate = *(char *)data;
- free(data);
-
- if (lockstate == 0) {
- rg_unlockall(L_USER); /* Doing this multiple times
- has no effect */
- logt_print(LOG_NOTICE, "Resource Groups Unlocked\n");
- return 0;
- }
-
- if (lockstate == 1) {
- rg_lockall(L_USER); /* Doing this multiple times
- has no effect */
- logt_print(LOG_NOTICE, "Resource Groups Locked\n");
- return 0;
- }
-
- logt_print(LOG_DEBUG, "Invalid lock state in callback: %d\n", lockstate);
- return 0;
-}
-
-
-static void
-do_lockreq(msgctx_t *ctx, int req)
-{
- int ret;
- char state;
-#ifdef OPENAIS
- msgctx_t everyone;
-#else
- cluster_member_list_t *m = member_list();
-#endif
-
- state = (req==RG_LOCK)?1:0;
-
-#ifdef OPENAIS
- ret = ds_write("rg_lockdown", &state, 1);
- logt_print(LOG_INFO, "FIXME: send RG_LOCK update to all!\n");
-#else
- ret = vf_write(m, VFF_IGN_CONN_ERRORS, "rg_lockdown", &state, 1);
- free_member_list(m);
-#endif
-
- if (ret == 0) {
- msg_send_simple(ctx, RG_SUCCESS, 0, 0);
- } else {
- msg_send_simple(ctx, RG_FAIL, 0, 0);
- }
-}
-
-
-/**
- * Receive and process a message on a file descriptor and decide what to
- * do with it. This function doesn't handle messages from the quorum daemon.
- *
- * @param fd File descriptor with a waiting message.S
- * @return -1 - failed to receive/handle message, or invalid
- * data received. 0 - handled message successfully.
- * @see quorum_msg
- */
-static int
-dispatch_msg(msgctx_t *ctx, int nodeid, int need_close)
-{
- int ret = 0, sz = -1, nid, read_only = 1;
- char msgbuf[4096];
- generic_msg_hdr *msg_hdr = (generic_msg_hdr *)msgbuf;
- SmMessageSt *msg_sm = (SmMessageSt *)msgbuf;
-
- if (ctx->type == MSG_CLUSTER) {
- read_only = 0;
- } else if (ctx->u.local_info.cred.uid == 0) {
- read_only = 0;
- }
-
- memset(msgbuf, 0, sizeof(msgbuf));
-
- /* Peek-a-boo */
- sz = msg_receive(ctx, msg_hdr, sizeof(msgbuf), 1);
- if (sz < (int)sizeof (generic_msg_hdr)) {
- logt_print(LOG_ERR,
- "#37: Error receiving header from %d sz=%d CTX %p\n",
- nodeid, sz, ctx);
- goto out;
- }
-
- if (sz < 0)
- return -1;
-
- if (sz > (int)sizeof(msgbuf)) {
- raise(SIGSTOP);
- }
-
- /*
- printf("RECEIVED %d %d %d %p\n", sz, (int)sizeof(msgbuf),
- (int)sizeof(generic_msg_hdr), ctx);
- msg_print(ctx);
- */
-
- /* Decode the header */
- swab_generic_msg_hdr(msg_hdr);
- if ((msg_hdr->gh_magic != GENERIC_HDR_MAGIC)) {
- logt_print(LOG_ERR,
- "#38: Invalid magic: Wanted 0x%08x, got 0x%08x\n",
- GENERIC_HDR_MAGIC, msg_hdr->gh_magic);
- goto out;
- }
-
- if ((int)msg_hdr->gh_length != sz) {
- logt_print(LOG_ERR, "#XX: Read size mismatch: %d %d\n",
- ret, msg_hdr->gh_length);
- goto out;
- }
-
- switch (msg_hdr->gh_command) {
- case RG_STATUS:
- //logt_print(LOG_DEBUG, "Sending service states to CTX%p\n",ctx);
- if (send_rg_states(ctx, msg_hdr->gh_arg1) == 0)
- need_close = 0;
- break;
-
- case RG_STATUS_NODE:
- //log_printf(LOG_DEBUG, "Sending node states to CTX%p\n",ctx);
- send_node_states(ctx);
- break;
-
- case RG_LOCK:
- case RG_UNLOCK:
- if (read_only) {
- msg_send_simple(ctx, RG_FAIL, RG_EPERM, 0);
- goto out;
- }
- if (rg_quorate())
- do_lockreq(ctx, msg_hdr->gh_command);
- break;
-
- case RG_QUERY_LOCK:
- if (rg_quorate()) {
- ret = (rg_locked() & L_USER) ? RG_LOCK : RG_UNLOCK;
- msg_send_simple(ctx, ret, 0, 0);
- }
- break;
-
- case RG_ACTION_REQUEST:
- if (read_only) {
- msg_send_simple(ctx, RG_FAIL, RG_EPERM, 0);
- goto out;
- }
-
- if (sz < (int)sizeof(msg_sm)) {
- logt_print(LOG_ERR,
- "#39: Error receiving entire request (%d/%d)\n",
- ret, (int)sizeof(msg_sm));
- ret = -1;
- goto out;
- }
-
- /* XXX perf: reencode header */
- swab_generic_msg_hdr(msg_hdr);
- /* Decode SmMessageSt message */
- swab_SmMessageSt(msg_sm);
-
- if (!svc_exists(msg_sm->sm_data.d_svcName)) {
- msg_sm->sm_data.d_ret = RG_ENOSERVICE;
- /* No such service! */
- swab_SmMessageSt(msg_sm);
-
- if (msg_send(ctx, msg_sm, sizeof (SmMessageSt)) <
- (int)sizeof (SmMessageSt))
- logt_print(LOG_ERR, "#40: Error replying to "
- "action request.\n");
- ret = -1;
- goto out;
- }
-
- if (central_events_enabled() &&
- msg_sm->sm_hdr.gh_arg1 != RG_ACTION_MASTER) {
-
- /* Centralized processing or request is from
- clusvcadm */
- nid = event_master();
- if (nid < 0) {
- logt_print(LOG_ERR, "#40b: Unable to determine "
- "event master\n");
- ret = -1;
- goto out;
- }
- else if (nid != my_id()) {
- /* Forward the message to the event master */
- forward_message(ctx, msg_sm, nid);
- } else {
- /* for us: queue it */
- user_event_q(msg_sm->sm_data.d_svcName,
- msg_sm->sm_data.d_action,
- msg_sm->sm_hdr.gh_arg1,
- msg_sm->sm_hdr.gh_arg2,
- msg_sm->sm_data.d_svcOwner,
- ctx);
- }
-
- return 0;
- }
-
- /* Distributed processing and/or request is from master node
- -- Queue request */
- if (rt_enqueue_request(msg_sm->sm_data.d_svcName,
- msg_sm->sm_data.d_action,
- ctx, 0, msg_sm->sm_data.d_svcOwner,
- msg_sm->sm_hdr.gh_arg1,
- msg_sm->sm_hdr.gh_arg2) != 0) {
-
- /* Clean up this context if we fail to
- * queue the request. */
- send_ret(ctx, msg_sm->sm_data.d_svcName,
- RG_EAGAIN, msg_sm->sm_data.d_action, 0);
- need_close = 1;
- ret = 0;
- goto out;
- }
- return 0;
-
- case RG_EVENT:
- if (read_only) {
- msg_send_simple(ctx, RG_FAIL, RG_EPERM, 0);
- goto out;
- }
-
- /* Service event. Run a dependency check */
- if (sz < (int)sizeof(msg_sm)) {
- logt_print(LOG_ERR,
- "#39: Error receiving entire request (%d/%d)\n",
- ret, (int)sizeof(msg_sm));
- ret = -1;
- goto out;
- }
-
- /* XXX perf: reencode header */
- swab_generic_msg_hdr(msg_hdr);
- /* Decode SmMessageSt message */
- swab_SmMessageSt(msg_sm);
-
- /* Send to our rg event handler */
- rg_event_q(msg_sm->sm_data.d_svcName,
- msg_sm->sm_data.d_action,
- msg_sm->sm_hdr.gh_arg1,
- msg_sm->sm_hdr.gh_arg2);
- break;
-
- case RG_EXITING:
- if (read_only) {
- msg_send_simple(ctx, RG_FAIL, RG_EPERM, 0);
- goto out;
- }
-
- if (!member_online(msg_hdr->gh_arg1))
- break;
-
- logt_print(LOG_NOTICE, "Member %d shutting down\n",
- msg_hdr->gh_arg1);
- member_set_state(msg_hdr->gh_arg1, 0);
- node_event_q(0, msg_hdr->gh_arg1, 0, 1);
- break;
-
- case VF_MESSAGE:
- if (read_only) {
- msg_send_simple(ctx, RG_FAIL, RG_EPERM, 0);
- goto out;
- }
-
- /* Ignore; our VF thread handles these
- - except for VF_CURRENT XXX (bad design) */
- if (msg_hdr->gh_arg1 == VF_CURRENT)
- vf_process_msg(ctx, 0, msg_hdr, sz);
- break;
-
- default:
- if (read_only) {
- goto out;
- }
-
- logt_print(LOG_DEBUG, "unhandled message request %d\n",
- msg_hdr->gh_command);
- break;
- }
-out:
- if (need_close) {
- msg_close(ctx);
- msg_free_ctx(ctx);
- }
- return ret;
-}
-
-/**
- Grab an event off of the designated context
-
- @param fd File descriptor to check
- @return Event
- */
-static int
-handle_cluster_event(msgctx_t *ctx)
-{
- int ret;
- msgctx_t *newctx;
- int nodeid;
-
- ret = msg_wait(ctx, 0);
-
- switch(ret) {
- case M_PORTOPENED:
- msg_receive(ctx, NULL, 0, 0);
- logt_print(LOG_DEBUG, "Event: Port Opened\n");
- membership_update();
- break;
- case M_PORTCLOSED:
- /* Might want to handle powerclosed like membership change */
- msg_receive(ctx, NULL, 0, 0);
- logt_print(LOG_DEBUG, "Event: Port Closed\n");
- membership_update();
- break;
- case M_NONE:
- msg_receive(ctx, NULL, 0, 0);
- logt_print(LOG_DEBUG, "NULL cluster message\n");
- break;
- case M_OPEN:
- newctx = msg_new_ctx();
- if (msg_accept(ctx, newctx) >= 0 &&
- rg_quorate()) {
- /* Handle message */
- /* When request completes, the fd is closed */
- nodeid = msg_get_nodeid(newctx);
- dispatch_msg(newctx, nodeid, 1);
- break;
- }
- break;
-
- case M_DATA:
- nodeid = msg_get_nodeid(ctx);
- dispatch_msg(ctx, nodeid, 0);
- break;
-
- case M_OPEN_ACK:
- case M_CLOSE:
- logt_print(LOG_DEBUG, "I should NOT get here: %d\n",
- ret);
- break;
- case M_STATECHANGE:
- msg_receive(ctx, NULL, 0, 0);
- logt_print(LOG_DEBUG, "Membership Change Event\n");
- if (running) {
- rg_unlockall(L_SYS);
- membership_update();
- }
- break;
- case M_TRY_SHUTDOWN:
- msg_receive(ctx, NULL, 0, 0);
- logt_print(LOG_WARNING, "#67: Shutting down uncleanly\n");
- rg_set_inquorate();
- rg_doall(RG_INIT, 1, "Emergency stop of %s");
- rg_clear_initialized(0);
-#if defined(LIBCMAN_VERSION) && LIBCMAN_VERSION >= 2
- /* cman_replyto_shutdown() */
-#endif
- running = 0;
- break;
- case M_CONFIG_UPDATE:
- msg_receive(ctx, NULL, 0, 0);
- need_reconfigure = 1;
- break;
- }
-
- return ret;
-}
-
-
-void dump_threads(FILE *fp);
-void dump_config_version(FILE *fp);
-void dump_vf_states(FILE *fp);
-void dump_cluster_ctx(FILE *fp);
-void dump_resource_info(FILE *fp);
-
-
-static void
-dump_internal_state(const char *loc)
-{
- FILE *fp;
- if (!loc)
- return;
- fp=fopen(loc, "w+");
- if (!fp)
- return;
- dump_config_version(fp);
- dump_threads(fp);
- dump_vf_states(fp);
-#ifdef WRAP_THREADS
- dump_thread_states(fp);
-#endif
- dump_cluster_ctx(fp);
- dump_resource_info(fp);
- fclose(fp);
-}
-
-static int
-event_loop(msgctx_t *localctx, msgctx_t *clusterctx)
-{
- int n = 0, max, ret;
- fd_set rfds;
- msgctx_t *newctx;
- struct timeval tv;
- int nodeid;
-
- tv.tv_sec = status_poll_interval;
- tv.tv_usec = 0;
-
- if (signalled) {
- signalled = 0;
-
- dump_internal_state("/var/lib/cluster/rgmanager-dump");
- }
-
- rgm_dbus_init();
-
- while (running && (tv.tv_sec || tv.tv_usec)) {
- FD_ZERO(&rfds);
- max = -1;
- msg_fd_set(clusterctx, &rfds, &max);
- msg_fd_set(localctx, &rfds, &max);
-
- n = select(max + 1, &rfds, NULL, NULL, &tv);
-
- if (n <= 0)
- break;
-
- if (msg_fd_isset(clusterctx, &rfds)) {
- msg_fd_clr(clusterctx, &rfds);
- handle_cluster_event(clusterctx);
- if (need_reconfigure)
- break;
- continue;
- }
-
- if (!msg_fd_isset(localctx, &rfds)) {
- continue;
- }
-
- msg_fd_clr(localctx, &rfds);
- newctx = msg_new_ctx();
- ret = msg_accept(localctx, newctx);
-
- if (ret == -1)
- continue;
-
- if (rg_quorate()) {
- /* Handle message */
- /* When request completes, the fd is closed */
- nodeid = msg_get_nodeid(newctx);
- dispatch_msg(newctx, nodeid, 1);
- continue;
- }
-
- if (!rg_initialized()) {
- msg_send_simple(newctx, RG_FAIL, RG_EQUORUM, 0);
- msg_close(newctx);
- msg_free_ctx(newctx);
- continue;
- }
-
- if (!rg_quorate()) {
- printf("Dropping connect: NO QUORUM\n");
- msg_send_simple(newctx, RG_FAIL, RG_EQUORUM, 0);
- msg_close(newctx);
- msg_free_ctx(newctx);
- }
- }
-
- if (!running)
- return 0;
-
- if (need_reconfigure) {
- need_reconfigure = 0;
- configure_rgmanager(-1, 0, NULL);
-
- /*
- * A shutdown during reconfiguration would slow down
- * the exit request, so it's pointless to run the
- * deltas at this point
- */
- if (shutdown_pending)
- return 0;
- config_event_q();
- return 0;
- }
-
- /* Did we receive a SIGTERM? */
- if (n < 0)
- return 0;
-
- /* No new messages. Drop in the status check requests. */
- if (n == 0 && rg_quorate()) {
- do_status_checks();
- return 0;
- }
-
- return 0;
-}
-
-
-void
-flag_shutdown(int __attribute__ ((unused)) sig)
-{
- shutdown_pending = 1;
-}
-
-
-static void
-cleanup(msgctx_t *clusterctx)
-{
- kill_resource_groups();
- send_exit_msg(clusterctx);
-}
-
-
-static void
-statedump(int __attribute__ ((unused)) sig)
-{
- signalled++;
-}
-
-/*
- * return -1 on error
- * 0 cpglock is not needed
- * 1 cpglock is needed
- */
-static int
-cpglockd_needed(void)
-{
- char *v;
- int ccsfd;
- int need = 0;
- ccsfd = ccs_force_connect(NULL, 0);
- if (ccsfd < 0)
- return -1;
-
-
- if (ccs_get(ccsfd,
- "/cluster/clusternodes/clusternode/altname/@name", &v) == 0) {
- if (v) {
- need = 1;
- free(v);
- }
- }
-
- if (need) {
- if (ccs_get(ccsfd, "/cluster/totem/@rrp_mode", &v) == 0) {
- if (v != NULL) {
- if (!strcasecmp(v, "none")) {
- need = 0;
- }
- free(v);
- }
- }
- }
-
- ccs_disconnect(ccsfd);
- return need;
-}
-
-static int
-rgmanager_disabled(int ccsfd)
-{
- char *v;
- int disabled = 0;
- int internal = 0;
-
- if (ccsfd < 0) {
- internal = 1;
- ccsfd = ccs_force_connect(NULL, 0);
- if (ccsfd < 0)
- return -1;
- }
-
- if (ccs_get(ccsfd, "/cluster/rm/@disabled", &v) == 0) {
- if (atoi(v) == 1) {
- disabled = 1;
- shutdown_pending = 1;
- logt_print(LOG_NOTICE, "Resource Group Manager Disabled\n");
- }
- free(v);
- }
-
- if (internal)
- ccs_disconnect(ccsfd);
-
- return disabled;
-}
-
-
-/*
- * Configure logging based on data in cluster.conf
- */
-static int
-configure_rgmanager(int ccsfd, int dbg, int *token_secs)
-{
- char *v;
- char internal = 0;
- int status_child_max = 0;
- int tmp;
-
- if (ccsfd < 0) {
- internal = 1;
- ccsfd = ccs_connect();
- if (ccsfd < 0)
- return -1;
- }
-
- setup_logging(ccsfd);
-
- rgmanager_disabled(ccsfd);
-
- if (token_secs && ccs_get(ccsfd, "/cluster/totem/@token", &v) == 0) {
- tmp = atoi(v);
- if (tmp >= 1000) {
- *token_secs = tmp / 1000;
- if (tmp % 1000)
- ++(*token_secs);
- }
- free(v);
- }
-
- if (ccs_get(ccsfd, "/cluster/rm/@transition_throttling", &v) == 0) {
- set_transition_throttling(atoi(v));
- free(v);
- }
-
- if (ccs_get(ccsfd, "/cluster/rm/@central_processing", &v) == 0) {
- set_central_events(atoi(v));
- if (atoi(v))
- logt_print(LOG_NOTICE,
- "Centralized Event Processing enabled\n");
- free(v);
- }
-
- if (ccs_get(ccsfd, "/cluster/rm/@status_poll_interval", &v) == 0) {
- status_poll_interval = atoi(v);
- if (status_poll_interval >= 1) {
- logt_print(LOG_NOTICE,
- "Status Polling Interval set to %d\n",
- status_poll_interval);
- } else {
- logt_print(LOG_WARNING, "Ignoring illegal "
- "status_poll_interval of %s\n", v);
- status_poll_interval = DEFAULT_CHECK_INTERVAL;
- }
-
- free(v);
- }
-
- if (ccs_get(ccsfd, "/cluster/rm/@status_child_max", &v) == 0) {
- status_child_max = atoi(v);
- if (status_child_max >= 1) {
- logt_print(LOG_NOTICE,
- "Status Child Max set to %d\n",
- status_child_max);
- rg_set_childmax(status_child_max);
- } else {
- logt_print(LOG_WARNING, "Ignoring illegal "
- "status_child_max of %s\n", v);
- }
-
- free(v);
- }
-
- if (internal)
- ccs_disconnect(ccsfd);
-
- return 0;
-}
-
-
-static int
-cman_connect(cman_handle_t *ch)
-{
- if (!ch)
- exit(1);
-
- *ch = cman_init(NULL);
- if (!(*ch)) {
- logt_print(LOG_NOTICE, "Waiting for CMAN to start\n");
-
- while (!(*ch = cman_init(NULL))) {
- sleep(1);
- if (shutdown_pending)
- return 1;
- }
- }
-
- if (!cman_is_quorate(*ch)) {
- /*
- There are two ways to do this; this happens to be the simpler
- of the two. The other method is to join with a NULL group
- and log in -- this will cause the plugin to not select any
- node group (if any exist).
- */
- logt_print(LOG_NOTICE, "Waiting for quorum to form\n");
-
- while (cman_is_quorate(*ch) == 0) {
- sleep(1);
- if (shutdown_pending)
- return 1;
- }
- logt_print(LOG_NOTICE, "Quorum formed\n");
- }
-
- return 0;
-}
-
-
-static int
-wait_for_fencing(void)
-{
- if (node_has_fencing(my_id()) && !fence_domain_joined()) {
- logt_print(LOG_INFO, "Waiting for fence domain join operation "
- "to complete\n");
-
- while (fence_domain_joined() == 0) {
- if (shutdown_pending)
- return 1;
- sleep(1);
- }
- logt_print(LOG_INFO, "Fence domain joined\n");
- } else {
- logt_print(LOG_DEBUG, "Fence domain already joined "
- "or no fencing configured\n");
- }
-
- return 0;
-}
-
-
-static void *
-shutdown_thread(void __attribute__ ((unused)) *arg)
-{
- rg_lockall(L_SYS|L_SHUTDOWN);
- stops_queued = rg_doall(RG_STOP_EXITING, 1, NULL);
- running = 0;
-
- pthread_exit(NULL);
-}
-
-
-#ifdef WRAP_THREADS
-void dump_thread_states(FILE *);
-#endif
-int
-main(int argc, char **argv)
-{
- int rv, do_init = 1;
- int cpg_locks = 0;
- char foreground = 0, wd = 1, cpg_lock_opt = 0;
- cman_node_t me;
- msgctx_t *cluster_ctx;
- msgctx_t *local_ctx;
- pthread_t th;
- cman_handle_t clu = NULL;
-
- while ((rv = getopt(argc, argv, "wfdNqC::")) != EOF) {
- switch (rv) {
- case 'w':
- wd = 0;
- break;
- case 'd':
- debug = 1;
- break;
- case 'N':
- do_init = 0;
- break;
- case 'f':
- foreground = 1;
- break;
- case 'q':
- rgm_dbus_notify = 0;
- break;
- case 'C':
- if (optarg) {
- if (!strcmp(optarg, "0")) {
- /* force disable */
- cpg_lock_opt = -1;
- } else if (!strcmp(optarg, "1")) {
- /* force enable */
- cpg_lock_opt = 1;
- } else {
- fprintf(stderr,
- "Unknown argument for -C: argument must be 1 or 0\n");
- return -1;
- }
- } else {
- /* auto handling: enable when RRP mode is enabled */
- cpg_lock_opt = 0;
- }
- break;
- default:
- return 1;
- break;
- }
- }
-
- if (getenv("RGMANAGER_DEBUG")) {
- debug = 1;
- }
-
- /* If we're disabled in the configuration, don't fork */
- if (rgmanager_disabled(-1) > 0) {
- fprintf(stderr,
- "rgmanager disabled in configuration; not starting\n");
- return 2;
- }
-
- if (!foreground && (geteuid() == 0)) {
- daemon_init(argv[0]);
- if (wd && !debug && !watchdog_init())
- logt_print(LOG_NOTICE, "Failed to start watchdog\n");
- }
-
- setup_signal(SIGINT, flag_shutdown);
- setup_signal(SIGTERM, flag_shutdown);
- setup_signal(SIGUSR1, statedump);
- unblock_signal(SIGCHLD);
- setup_signal(SIGPIPE, SIG_IGN);
-
- if (debug) {
- setup_signal(SIGSEGV, segfault);
- } else {
- unblock_signal(SIGSEGV);
- }
-
- init_logging(NULL, foreground, (debug? LOG_DEBUG : SYSLOGLEVEL));
-
- rv = -1;
- if (cman_connect(&clu) != 0)
- goto out; /* Clean exit if sigint/sigterm here */
-
- if (cman_init_subsys(clu) < 0) {
- perror("cman_init_subsys");
- return -1;
- }
-
- xmlInitParser();
-
- cpg_locks = 0;
- if (cpg_lock_opt == 1) { /* force enable */
- cpg_locks = 1;
- } else if (cpg_lock_opt == 0) { /* autodetect */
- cpg_locks = cpglockd_needed();
- if (cpg_locks < 0) {
- printf("Unable to determine if cpglock is required!\n");
- cman_finish(clu);
- return -1;
- }
- }
-
- if (!cpg_locks) {
- if (clu_lock_init(rgmanager_lsname) != 0) {
- printf("Locks not working!\n");
- cman_finish(clu);
- return -1;
- }
- } else {
- logt_print(LOG_INFO, "Using CPG for locking (EXPERIMENTAL)\n");
- if (cpg_lock_initialize() != 0) {
- printf("Locks not working!\n");
- cman_finish(clu);
- return -1;
- }
- }
-
- memset(&me, 0, sizeof(me));
- cman_get_node(clu, CMAN_NODEID_US, &me);
-
- if (me.cn_nodeid == 0) {
- printf("Unable to determine local node ID\n");
- perror("cman_get_node");
- goto out_ls;
- }
- set_my_id(me.cn_nodeid);
-
- logt_print(LOG_INFO, "I am node #%d\n", my_id());
-
- if (wait_for_fencing() != 0) {
- rv = 0;
- goto out_ls;
- }
-
- /*
- We know we're quorate. At this point, we need to
- read the resource group trees from ccsd.
- */
- configure_rgmanager(-1, debug, &cluster_timeout);
- if (shutdown_pending == 1)
- goto out_ls;
-
- logt_print(LOG_NOTICE, "Resource Group Manager Starting\n");
-
- if (rgm_dbus_notify && rgm_dbus_init() != 0) {
- rgm_dbus_notify = 0;
- logt_print(LOG_NOTICE, "Failed to initialize DBus; "
- "notifications disabled\n");
- }
-
- if (init_resource_groups(0, do_init) != 0) {
- logt_print(LOG_CRIT, "#8: Couldn't initialize services\n");
- goto out_ls;
- }
-
- if (shutdown_pending) {
- rv = 0;
- goto out_ls;
- }
-
- if (msg_listen(MSG_SOCKET, RGMGR_SOCK, me.cn_nodeid, &local_ctx) < 0) {
- logt_print(LOG_CRIT,
- "#10: Couldn't set up cluster message system: %s\n",
- strerror(errno));
- goto out_ls;
- }
-
- if (msg_listen(MSG_CLUSTER, &port, me.cn_nodeid, &cluster_ctx) < 0) {
- logt_print(LOG_CRIT,
- "#10b: Couldn't set up cluster message system: %s\n",
- strerror(errno));
- goto out_ls;
- }
-
- rg_set_quorate();
-
- /*
- msg_print(local_ctx);
- msg_print(cluster_ctx);
- */
-
- /*
- Initialize the VF stuff.
- */
-#ifdef OPENAIS
- if (ds_init() < 0) {
- logt_print(LOG_CRIT, "#11b: Couldn't initialize SAI AIS CKPT\n");
- goto out_ls;
- }
-
- ds_key_init("rg_lockdown", 32, 10);
-#else
- if (vf_init(me.cn_nodeid, port, NULL, RGM_DBUS_UPDATE,
- cluster_timeout) != 0) {
- logt_print(LOG_CRIT, "#11: Couldn't set up VF listen socket\n");
- goto out_ls;
- }
-
- vf_key_init("rg_lockdown", 10, NULL, lock_commit_cb);
- vf_key_init("Transition-Master", 10, NULL, master_event_callback);
-#endif
-
- /*
- Do everything useful
- */
- while (running) {
- event_loop(local_ctx, cluster_ctx);
-
- if (shutdown_pending == 1) {
- /* Kill local socket; local requests need to
- be ignored here */
- msg_close(local_ctx);
- ++shutdown_pending;
- logt_print(LOG_NOTICE, "Shutting down\n");
- pthread_create(&th, NULL, shutdown_thread, NULL);
- }
- }
-
- if (rg_initialized())
- cleanup(cluster_ctx);
- rv = 0;
- xmlCleanupParser();
-out_ls:
- clu_lock_finished(rgmanager_lsname);
-
-out:
- rgm_dbus_release();
- logt_print(LOG_DEBUG, "Stopped %d services\n", stops_queued);
- logt_print(LOG_NOTICE, "Disconnecting from CMAN\n");
- cman_finish(clu);
-
- if (stops_queued && !central_events_enabled()) {
- logt_print(LOG_DEBUG, "Pausing to allow services to "
- "start on other node(s)\n");
- sleep(get_transition_throttling() * 3);
- }
-
- logt_print(LOG_NOTICE, "Exiting\n");
-
- close_logging();
- /*malloc_stats();*/
-
- daemon_cleanup();
- exit(rv);
-}
diff --git a/rgmanager/src/daemons/reslist.c b/rgmanager/src/daemons/reslist.c
deleted file mode 100644
index ced3fc2..0000000
--- a/rgmanager/src/daemons/reslist.c
+++ /dev/null
@@ -1,995 +0,0 @@
-#include <libxml/parser.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/xpath.h>
-#include <ccs.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <resgroup.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <list.h>
-#include <restart_counter.h>
-#include <reslist.h>
-#include <pthread.h>
-#include <libgen.h>
-#ifndef NO_CCS
-#include <logging.h>
-#endif
-#include <groups.h>
-
-
-void
-res_build_name(char *buf, size_t buflen, resource_t *res)
-{
- snprintf(buf, buflen, "%s:%s", res->r_rule->rr_type,
- res->r_attrs[0].ra_value);
-}
-
-/**
- Find and determine an attribute's value.
-
- @param res Resource node to look examine
- @param attrname Attribute to retrieve.
- @return value of attribute or NULL if not found
- */
-const char *
-res_attr_value(resource_t *res, const char *attrname)
-{
- resource_attr_t *ra;
- int x;
-
- for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) {
- if (strcmp(attrname, res->r_attrs[x].ra_name))
- continue;
-
- ra = &res->r_attrs[x];
-
- if (ra->ra_flags & RA_INHERIT)
- /* Can't check inherited resources */
- return NULL;
-
- return ra->ra_value;
- }
-
- return NULL;
-}
-
-
-/**
- Find and determine an attribute's value. Takes into account inherited
- attribute flag, and append attribute flag, which isn't implemented yet.
-
- @param node Resource tree node to look examine
- @param attrname Attribute to retrieve.
- @param ptype Resource type to look for (if inheritance)
- @return value of attribute or NULL if not found
- */
-static char *
-_attr_value(resource_node_t *node, const char *attrname, const char *ptype)
-{
- resource_t *res;
- resource_attr_t *ra;
- char *c, p_type[32];
- size_t len;
- int x;
-
- if (!node)
- return NULL;
-
- res = node->rn_resource;
-
- /* Go up the tree if it's not the right parent type */
- if (ptype && strcmp(res->r_rule->rr_type, ptype))
- return _attr_value(node->rn_parent, attrname, ptype);
-
- for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) {
- if (strcmp(attrname, res->r_attrs[x].ra_name))
- continue;
-
- ra = &res->r_attrs[x];
-
- if (!(ra->ra_flags & RA_INHERIT))
- return ra->ra_value;
- /*
- Handle resource_type%field to be more precise, so we
- don't have to worry about this being a child
- of an unexpected type. E.g. lots of things have the
- "name" attribute.
- */
- c = strchr(ra->ra_value, '%');
- if (!c) {
- /* Someone doesn't care or uses older
- semantics of inheritance */
- return _attr_value(node->rn_parent, ra->ra_value,
- NULL);
- }
-
- /* Difference guaranteed to be non-negative
- (for x >= 0: &ra->ra_value[x] >= &ra->ra_value[0]) */
- len = (c - ra->ra_value);
- if (len >= sizeof(p_type))
- len = sizeof(p_type) - 1;
-
- memcpy(p_type, ra->ra_value, len);
- p_type[len] = '\0';
-
- /* Skip the "%" and recurse */
- return _attr_value(node->rn_parent, ++c, p_type);
- }
-
- return NULL;
-}
-
-
-const char *
-attr_value(resource_node_t *node, const char *attrname)
-{
- return _attr_value(node, attrname, NULL);
-}
-
-
-/**
- Run to the top of the tree. Used to determine certain attributes of the
- resource group in-line, during resource tree operations.
- */
-const char *
-rg_attr_value(resource_node_t *node, const char *attrname)
-{
- for (; node->rn_parent; node = node->rn_parent);
- return res_attr_value(node->rn_resource, attrname);
-}
-
-
-const char *
-primary_attr_value(resource_t *res)
-{
- int x;
- resource_attr_t *ra;
-
- for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) {
- ra = &res->r_attrs[x];
-
- if (!(ra->ra_flags & RA_PRIMARY))
- continue;
-
- return ra->ra_value;
- }
-
- return NULL;
-}
-
-
-/**
- Compare two resources.
-
- @param left Left resource
- @param right Right resource
- @return -1 on different resource, 0 if the same, 1 if different,
- 2 if different, but only safe resources are different
-
- */
-int
-rescmp(resource_t *left, resource_t *right)
-{
- int x, y = 0, found = 0, ret = 0;
-
-
- /* Completely different resource class... */
- if (strcmp(left->r_rule->rr_type, right->r_rule->rr_type)) {
- return -1;
- }
-
- /*
- printf("Comparing %s:%s to %s:%s\n",
- left->r_rule->rr_type, left->r_attrs[0].ra_value,
- right->r_rule->rr_type, right->r_attrs[0].ra_value)
- */
-
- for (x = 0; left->r_attrs && left->r_attrs[x].ra_name; x++) {
-
- found = 0;
- for (y = 0; right->r_attrs && right->r_attrs[y].ra_name; y++) {
- if (!strcmp(right->r_attrs[y].ra_name,
- left->r_attrs[x].ra_name))
- found = 1;
- else
- /* Different attribute name */
- continue;
-
- if (right->r_attrs[y].ra_flags !=
- left->r_attrs[x].ra_flags) {
- /* Flags are different. Change in
- resource agents? */
- /*
- printf("* flags differ %08x vs %08x\n",
- left->r_attrs[x].ra_flags,
- right->r_attrs[y].ra_flags);
- */
- return 1;
- }
-
- if (strcmp(right->r_attrs[y].ra_value,
- left->r_attrs[x].ra_value)) {
- /* Different attribute value. */
- /*
- printf("* different value for attr '%s':"
- " '%s' vs '%s'",
- right->r_attrs[y].ra_name,
- left->r_attrs[x].ra_value,
- right->r_attrs[y].ra_value);
- */
- if (left->r_attrs[x].ra_flags & RA_RECONFIG) {
- /* printf(" [SAFE]\n"); */
- ret = 2;
- } else {
- /* printf("\n"); */
- return 1;
- }
- }
- }
-
- /* Attribute missing -> different attribute value. */
- if (!found) {
- /*
- printf("* Attribute '%s' deleted\n",
- left->r_attrs[x].ra_name);
- */
- return 1;
- }
- }
-
- /* Different attribute count */
- if (x != y) {
- /* printf("* Attribute count differ (attributes added!) "); */
- return 1;
- }
-
- /* All the same */
- return ret;
-}
-
-
-/**
- Find a resource given its reference. A reference is the value of the
- primary attribute.
-
- @param reslist List of resources to traverse.
- @param type Type of resource to look for.
- @param ref Reference
- @return Resource matching type/ref or NULL if none.
- */
-resource_t *
-find_resource_by_ref(resource_t **reslist, const char *type, const char *ref)
-{
- resource_t *curr;
- resource_t *first_possible = NULL;
- int x, flags = RA_UNIQUE|RA_REQUIRED;
-
- list_do(reslist, curr) {
- if (strcmp(curr->r_rule->rr_type, type))
- continue;
-
- /*
- This should be one operation - the primary attr
- is generally at the head of the array.
- */
- for (x = 0; curr->r_attrs && curr->r_attrs[x].ra_name;
- x++) {
- if (strcmp(ref, curr->r_attrs[x].ra_value))
- continue;
- if (((curr->r_attrs[x].ra_flags & flags) == flags) &&
- !first_possible)
- first_possible = curr;
- if (!(curr->r_attrs[x].ra_flags & RA_PRIMARY))
- continue;
- return curr;
- }
- } while (!list_done(reslist, curr));
-
- return first_possible;
-}
-
-
-/**
- Find a root resource by ref (service, usually). No name is required.
- Only one type of root resource may exist because of the primary
- attribute flag
-
- @param reslist List of resources to traverse.
- @param ref Reference
- @return Resource matching type/ref or NULL if none.
- */
-resource_t *
-find_root_by_ref(resource_t **reslist, const char *ref)
-{
- resource_t *curr;
- char ref_buf[128];
- char *type;
- char *name = (char *)ref;
- int x;
-
- snprintf(ref_buf, sizeof(ref_buf), "%s", ref);
-
- type = ref_buf;
- if ((name = strchr(ref_buf, ':'))) {
- *name = 0;
- name++;
- } else {
- /* Default type */
- type = (char *)"service";
- name = (char *)ref;
- }
-
- list_do(reslist, curr) {
-
- /*
- This should be one operation - the primary attr
- is generally at the head of the array.
- */
- for (x = 0; curr->r_attrs && curr->r_attrs[x].ra_name;
- x++) {
- if (strcmp(type, curr->r_rule->rr_type))
- continue;
- if (!(curr->r_attrs[x].ra_flags & RA_PRIMARY))
- continue;
- if (strcmp(name, curr->r_attrs[x].ra_value))
- continue;
-
- return curr;
- }
- } while (!list_done(reslist, curr));
-
-
- return NULL;
-}
-
-
-/**
- Store a resource in the resource list if it's legal to do so.
- Otherwise, don't store it.
- Note: This function needs to be rewritten; it's way too long and way
- too indented.
-
- @param reslist Resource list to store the new resource.
- @param newres Resource to store
- @return 0 on succes; nonzero on failure.
- */
-int
-store_resource(resource_t **reslist, resource_t *newres)
-{
- resource_t *curr;
- int x, y;
-
- if (!*reslist) {
- /* first resource */
- list_insert(reslist, newres);
- return 0;
- }
-
- list_do(reslist, curr) {
-
- if (strcmp(curr->r_rule->rr_type, newres->r_rule->rr_type))
- continue;
-
- for (x = 0; newres->r_attrs && newres->r_attrs[x].ra_name;
- x++) {
- /*
- Look for conflicting primary/unique keys
- */
- if (!(newres->r_attrs[x].ra_flags &
- (RA_PRIMARY | RA_UNIQUE)))
- continue;
-
- for (y = 0; curr->r_attrs[y].ra_name; y++) {
- if (curr->r_attrs[y].ra_flags & RA_INHERIT)
- continue;
-
- if (strcmp(curr->r_attrs[y].ra_name,
- newres->r_attrs[x].ra_name))
- continue;
- if (!strcmp(curr->r_attrs[y].ra_value,
- newres->r_attrs[x].ra_value)) {
- /*
- Unique/primary is not unique
- */
-#ifdef NO_CCS
- printf("Error: "
- "%s attribute collision. "
- "type=%s attr=%s value=%s\n",
- (newres->r_attrs[x].ra_flags&
- RA_PRIMARY)?"Primary":
- "Unique",
- newres->r_rule->rr_type,
- newres->r_attrs[x].ra_name,
- newres->r_attrs[x].ra_value
- );
-#else
- logt_print(LOG_ERR,
- "%s attribute collision. "
- "type=%s attr=%s value=%s\n",
- (newres->r_attrs[x].ra_flags&
- RA_PRIMARY)?"Primary":
- "Unique",
- newres->r_rule->rr_type,
- newres->r_attrs[x].ra_name,
- newres->r_attrs[x].ra_value
- );
-#endif
- return -1;
- }
- break;
- }
- }
- } while (!list_done(reslist, curr));
-
- list_insert(reslist, newres);
- return 0;
-}
-
-
-/**
- Execute an XPath query, returning the first match. Multiple matches are
- ignored. Please be advised that this is quite inefficient.
-
- @param doc Loaded XML document to search
- @param ctx Predefined XML XPath context
- @param query Query to execute.
- @return newly allocated pointer to value or NULL if not found.
- */
-char *
-xpath_get_one(xmlDocPtr __attribute__ ((unused)) doc,
- xmlXPathContextPtr ctx, const char *query)
-{
- char *val = NULL, *ret = NULL;
- xmlXPathObjectPtr obj;
- xmlNodePtr node;
- size_t size = 0;
- int nnv = 0;
-
- obj = xmlXPathEvalExpression((unsigned char *)query, ctx);
- if (!obj)
- return NULL;
- if (!obj->nodesetval)
- goto out;
- if (obj->nodesetval->nodeNr <= 0)
- goto out;
-
- node = obj->nodesetval->nodeTab[0];
- if(!node)
- goto out;
-
- if (((node->type == XML_ATTRIBUTE_NODE) && strstr(query, "@*")) ||
- ((node->type == XML_ELEMENT_NODE) && strstr(query, "child::*"))){
- if (node->children && node->children->content)
- size = strlen((char *)node->children->content)+
- strlen((char *)node->name)+2;
- else
- size = strlen((char *)node->name)+2;
- nnv = 1;
- } else {
- if (node->children && node->children->content) {
- size = strlen((char *)node->children->content)+1;
- } else {
- goto out;
- }
- }
-
- val = (char *)malloc(size);
- if(!val)
- goto out;
- memset(val, 0, size);
- if (nnv) {
- sprintf(val, "%s=%s", node->name, node->children ?
- (char *)node->children->content:"");
- } else {
- sprintf(val, "%s", node->children ? node->children->content :
- node->name);
- }
-
- ret = val;
-out:
- xmlXPathFreeObject(obj);
-
- return ret;
-}
-
-
-/**
- Obliterate a resource_t structure.
-
- @param res Resource to free.
- */
-void
-destroy_resource(resource_t *res)
-{
- int x;
-
- if (res->r_name)
- free(res->r_name);
-
- if (res->r_attrs) {
- for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) {
- free(res->r_attrs[x].ra_name);
- free(res->r_attrs[x].ra_value);
- }
-
- free(res->r_attrs);
- }
-
- if (res->r_actions) {
- /* Don't free the strings; they're part of the rule */
- free(res->r_actions);
- }
-
- free(res);
-}
-
-
-
-/**
- Obliterate a resource_t list.
-
- @param list Resource list to free.
- */
-void
-destroy_resources(resource_t **list)
-{
- resource_t *res;
-
- while ((res = *list)) {
- list_remove(list, res);
- destroy_resource(res);
- }
-}
-
-
-/**
- Print a resource_t structure to stdout
-
- @param res Resource to print.
- */
-void
-print_resource(FILE *fp, resource_t *res)
-{
- int x;
-
- fprintf(fp, "Resource type: %s", res->r_rule->rr_type);
- if (res->r_flags & RF_INLINE)
- fprintf(fp, " [INLINE]");
- if (res->r_flags & RF_NEEDSTART)
- fprintf(fp, " [NEEDSTART]");
- if (res->r_flags & RF_NEEDSTOP)
- fprintf(fp, " [NEEDSTOP]");
- if (res->r_flags & RF_COMMON)
- fprintf(fp, " [COMMON]");
- if (res->r_flags & RF_RECONFIG)
- fprintf(fp, " [RECONFIG]");
- fprintf(fp, "\n");
-
- if (res->r_rule->rr_maxrefs)
- fprintf(fp, "Instances: %d/%d\n", res->r_refs,
- res->r_rule->rr_maxrefs);
- if (res->r_rule->rr_agent)
- fprintf(fp, "Agent: %s\n", basename(res->r_rule->rr_agent));
-
- fprintf(fp, "Attributes:\n");
- if (!res->r_attrs) {
- fprintf(fp, " - None -\n\n");
- return;
- }
-
- for (x = 0; res->r_attrs[x].ra_name; x++) {
-
- if (!(res->r_attrs[x].ra_flags & RA_INHERIT)) {
- fprintf(fp, " %s = %s", res->r_attrs[x].ra_name,
- res->r_attrs[x].ra_value);
- } else {
- fprintf(fp, " %s", res->r_attrs[x].ra_name);
- }
-
- if (!res->r_attrs[x].ra_flags) {
- fprintf(fp, "\n");
- continue;
- }
-
- fprintf(fp, " [");
- if (res->r_attrs[x].ra_flags & RA_PRIMARY)
- fprintf(fp, " primary");
- if (res->r_attrs[x].ra_flags & RA_UNIQUE)
- fprintf(fp, " unique");
- if (res->r_attrs[x].ra_flags & RA_REQUIRED)
- fprintf(fp, " required");
- if (res->r_attrs[x].ra_flags & RA_RECONFIG)
- fprintf(fp, " reconfig");
- if (res->r_attrs[x].ra_flags & RA_INHERIT)
- fprintf(fp, " inherit(\"%s\")", res->r_attrs[x].ra_value);
- fprintf(fp, " ]\n");
- }
-
- fprintf(fp, "\n");
-}
-
-
-void
-dump_resources(FILE *fp, resource_t **resources)
-{
- resource_t *curr;
- int x;
-
- list_for(resources, curr, x) {
- print_resource(fp, curr);
- }
-}
-
-
-void
-print_resources(resource_t **resources)
-{
- dump_resources(stdout, resources);
-}
-
-
-resource_act_t *
-act_dup(resource_act_t *acts)
-{
- size_t x;
- resource_act_t *newacts;
-
- for (x = 0; acts[x].ra_name; x++);
-
- ++x;
- x *= sizeof(resource_act_t);
-
- newacts = malloc(x);
- if (!newacts)
- return NULL;
-
- memcpy(newacts, acts, x);
-
- return newacts;
-}
-
-
-/* Copied from resrules.c -- _get_actions */
-static void
-#ifndef NO_CCS
-_get_actions_ccs(int ccsfd, char *base, resource_t *res)
-#else
-_get_actions_ccs(int __attribute__((unused)) ccsfd, char *base, resource_t *res)
-#endif
-{
- char xpath[256];
- int idx = 0;
- char *act, *ret;
- int interval, timeout, depth;
-
- do {
- /* setting these to -1 prevents overwriting with 0 */
- interval = -1;
- depth = -1;
- act = NULL;
- timeout = -1;
-
- snprintf(xpath, sizeof(xpath),
- "%s/action[%d]/@name", base, ++idx);
-
-#ifndef NO_CCS
- if (ccs_get(ccsfd, xpath, &act) != 0)
-#else
- if (conf_get(xpath, &act) != 0)
-#endif
- break;
-
- snprintf(xpath, sizeof(xpath),
- "%s/action[%d]/@timeout", base, idx);
-#ifndef NO_CCS
- if (ccs_get(ccsfd, xpath, &ret) == 0 && ret) {
-#else
- if (conf_get(xpath, &ret) == 0 && ret) {
-#endif
- timeout = expand_time(ret);
- if (timeout < 0)
- timeout = 0;
- free(ret);
- }
-
- snprintf(xpath, sizeof(xpath),
- "%s/action[%d]/@interval", base, idx);
-#ifndef NO_CCS
- if (ccs_get(ccsfd, xpath, &ret) == 0 && ret) {
-#else
- if (conf_get(xpath, &ret) == 0 && ret) {
-#endif
- interval = expand_time(ret);
- if (interval < 0)
- interval = 0;
- free(ret);
- }
-
- if (!strcmp(act, "status") || !strcmp(act, "monitor")) {
- snprintf(xpath, sizeof(xpath),
- "%s/action[%d]/@depth", base, idx);
-#ifndef NO_CCS
- if (ccs_get(ccsfd, xpath, &ret) == 0 && ret) {
-#else
- if (conf_get(xpath, &ret) == 0 && ret) {
-#endif
- depth = atoi(ret);
- if (depth < 0)
- depth = 0;
-
- /* */
- if (ret[0] == '*')
- depth = -1;
- free(ret);
- }
- }
-
- if (store_action(&res->r_actions, act, depth, timeout,
- interval) != 0)
- free(act);
- } while (1);
-}
-
-
-/**
- Try to load all the attributes in our rule set. If none are found,
- or an error occurs, return NULL and move on to the next one.
-
- @param ccsfd File descriptor connected to CCS
- @param rule Resource rule set to use when looking for data
- @param base Base XPath path to start with.
- @return New resource if legal or NULL on failure/error
- */
-resource_t *
-load_resource(int ccsfd, resource_rule_t *rule, char *base)
-{
- resource_t *res = NULL;
- char ccspath[1024];
- char *attrname, *attr;
- int x, found = 0, flags;
-
- res = malloc(sizeof(*res));
- if (!res) {
- printf("Out of memory\n");
- return NULL;
- }
-
- memset(res, 0, sizeof(*res));
- pthread_mutex_init(&res->r_mutex, NULL);
- res->r_rule = rule;
-
- for (x = 0; res->r_rule->rr_attrs &&
- res->r_rule->rr_attrs[x].ra_name; x++) {
-
- flags = rule->rr_attrs[x].ra_flags;
- attrname = strdup(rule->rr_attrs[x].ra_name);
- if (!attrname) {
- destroy_resource(res);
- return NULL;
- }
-
- /*
- Ask CCS for the respective attribute
- */
- attr = NULL;
- snprintf(ccspath, sizeof(ccspath), "%s/@%s", base, attrname);
-
-#ifndef NO_CCS
- if (ccs_get(ccsfd, ccspath, &attr) != 0) {
-#else
- if (conf_get(ccspath, &attr) != 0) {
-#endif
-
- if (flags & (RA_REQUIRED | RA_PRIMARY)) {
- /* Missing required attribute. We're done. */
- free(attrname);
- destroy_resource(res);
- return NULL;
- }
-
- if (!(flags & RA_INHERIT)) {
- /*
- If we don't have the inherit flag, see if
- we have a value anyway. If we do,
- this value is the default value, and
- should be used.
- */
- if (!rule->rr_attrs[x].ra_value) {
- free(attrname);
- continue;
- }
-
- /* Copy default value from resource rule */
- attr = strdup(rule->rr_attrs[x].ra_value);
- }
- }
-
- found = 1;
-
- /*
- If we are supposed to inherit and we don't have an
- instance of the specified attribute in CCS, then we
- keep the inherit flag and use it as the attribute.
-
- However, if we _do_ have the attribute for this instance,
- we drop the inherit flag and use the attribute.
- */
- if (flags & RA_INHERIT) {
- if (attr) {
- flags &= ~RA_INHERIT;
- } else {
- attr = strdup(rule->rr_attrs[x].ra_value);
- if (!attr) {
- destroy_resource(res);
- free(attrname);
- return NULL;
- }
- }
- }
-
- /*
- Store the attribute. We'll ensure all required
- attributes are present soon.
- */
- if (attrname && attr)
- store_attribute(&res->r_attrs, attrname, attr, flags);
- }
-
- if (!found) {
- destroy_resource(res);
- return NULL;
- }
-
- res->r_actions = act_dup(rule->rr_actions);
- _get_actions_ccs(ccsfd, base, res);
-
- return res;
-}
-
-
-/**
- Read all resources in the resource manager block in CCS.
-
- @param ccsfd File descriptor connected to CCS.
- @param reslist Empty list to fill with resources.
- @param rulelist List of rules to use when searching CCS.
- @return 0 on success, nonzero on failure.
- */
-int
-load_resources(int ccsfd, resource_t **reslist, resource_rule_t **rulelist)
-{
- int resID = 0;
- resource_t *newres = NULL;
- resource_rule_t *currule;
- char tok[256];
-
- list_do(rulelist, currule) {
-
- for (resID = 1; ; resID++) {
- snprintf(tok, sizeof(tok), RESOURCE_BASE "/%s[%d]",
- currule->rr_type, resID);
-
- newres = load_resource(ccsfd, currule, tok);
- if (!newres)
- break;
-
- if (store_resource(reslist, newres) != 0) {
-#ifdef NO_CCS
- printf("Error storing %s resource\n",
- newres->r_rule->rr_type);
-#else
- logt_print(LOG_ERR,
- "Error storing %s resource\n",
- newres->r_rule->rr_type);
-#endif
-
- destroy_resource(newres);
- continue;
- }
-
- /* Just information */
- newres->r_flags = RF_DEFINED;
- }
- } while (!list_done(rulelist, currule));
-
- return 0;
-}
-
-
-/**
- Try to load all the attributes in our rule set. If none are found,
- or an error occurs, return NULL and move on to the next one.
-
- @param ccsfd File descriptor connected to CCS
- @param rule Resource rule set to use when looking for data
- @param base Base XPath path to start with.
- @return New resource if legal or NULL on failure/error
- */
-static int
-load_defaults(int ccsfd, resource_rule_t *rule, char *base)
-{
- char ccspath[1024];
- char *attrname, *attr;
- int x, flags;
-
- for (x = 0; rule->rr_attrs && rule->rr_attrs[x].ra_name; x++) {
-
- flags = rule->rr_attrs[x].ra_flags;
-
- /* Defaults for primary/unique may not be assigned */
- if (flags & (RA_PRIMARY | RA_UNIQUE))
- continue;
- attrname = strdup(rule->rr_attrs[x].ra_name);
- if (!attrname)
- return -1;
-
- attr = NULL;
- snprintf(ccspath, sizeof(ccspath), "%s/@%s", base, attrname);
-
-#ifndef NO_CCS
- if (ccs_get(ccsfd, ccspath, &attr) != 0) {
-#else
- if (conf_get(ccspath, &attr) != 0) {
-#endif
- free(attrname);
- continue;
- }
-
- if (rule->rr_attrs[x].ra_value &&
- !strcmp(rule->rr_attrs[x].ra_value, attr)) {
- free(attrname);
- free(attr);
- continue;
- }
-
- if (rule->rr_attrs[x].ra_value) {
- printf("changing default for %s attr %s from %s to %s\n", rule->rr_type,
- rule->rr_attrs[x].ra_name, rule->rr_attrs[x].ra_value,
- attr);
- } else {
- printf("setting default for %s attr %s to %s\n", rule->rr_type,
- rule->rr_attrs[x].ra_name, attr);
- }
-
- flags &= ~RA_INHERIT;
-
- /*
- * Overwrite defaults
- */
- if (attrname && attr)
- store_attribute(&rule->rr_attrs, attrname, attr, flags);
- }
-
- /* FIXME - add action support */
-
- return 0;
-}
-
-
-/**
- Read all resources in the resource manager block in CCS.
-
- @param ccsfd File descriptor connected to CCS.
- @param rulelist List of rules to use when searching CCS.
- @return 0 on success, nonzero on failure.
- */
-int
-load_resource_defaults(int ccsfd, resource_rule_t **rulelist)
-{
- int rid = 0;
- resource_rule_t *currule;
- char tok[256];
-
- list_for(rulelist, currule, rid) {
-
- snprintf(tok, sizeof(tok), RESOURCE_DEFAULTS "/%s",
- currule->rr_type);
-
- if (load_defaults(ccsfd, currule, tok) != 0)
- return -1;
- }
-
- return 0;
-}
-
diff --git a/rgmanager/src/daemons/resrules.c b/rgmanager/src/daemons/resrules.c
deleted file mode 100644
index c2cfdfa..0000000
--- a/rgmanager/src/daemons/resrules.c
+++ /dev/null
@@ -1,1218 +0,0 @@
-#include <libxml/parser.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/xpath.h>
-#include <ccs.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <limits.h>
-#include <resgroup.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <list.h>
-#include <ctype.h>
-#include <restart_counter.h>
-#include <reslist.h>
-#include <pthread.h>
-#include <dirent.h>
-#include <libgen.h>
-#ifndef NO_CCS
-#include <logging.h>
-#endif
-
-
-/**
- Store a new resource rule in the given rule list.
-
- @param rulelist List of rules to store new rule in.
- @param newrule New rule to store.
- @return 0 on success or -1 if rule with same name
- already exists in rulelist
- */
-static int
-store_rule(resource_rule_t **rulelist, resource_rule_t *newrule)
-{
- resource_rule_t *curr;
-
- list_do(rulelist, curr) {
- if (!strcasecmp(newrule->rr_type, curr->rr_type)) {
-#ifdef NO_CCS
- fprintf(stderr, "Error storing %s: Duplicate\n",
- newrule->rr_type);
-#else
- logt_print(LOG_ERR, "Error storing %s: Duplicate\n",
- newrule->rr_type);
-#endif
- return -1;
- }
-
- } while (!list_done(rulelist, curr));
-
- /* insert sorted in alphabetical order so rg_test produces
- * reproducible output all the time */
- list_do(rulelist, curr) {
- if (strcasecmp(newrule->rr_type, curr->rr_type) < 0) {
- list_insert(&curr, newrule);
- /* reset list if we have a new low */
- if (curr == *rulelist)
- *rulelist = newrule;
- return 0;
- }
- } while (!list_done(rulelist, curr));
-
- list_insert(rulelist, newrule);
- return 0;
-}
-
-
-/**
- Obliterate a resource_rule_t structure.
-
- @param rr Resource rule to free.
- */
-static void
-destroy_resource_rule(resource_rule_t *rr)
-{
- int x;
-
- if (rr->rr_type)
- free(rr->rr_type);
- if (rr->rr_agent)
- free(rr->rr_agent);
- if (rr->rr_version)
- free(rr->rr_version);
-
- if (rr->rr_attrs) {
- for (x = 0; rr->rr_attrs &&
- rr->rr_attrs[x].ra_name; x++) {
- free(rr->rr_attrs[x].ra_name);
- if (rr->rr_attrs[x].ra_value)
- free(rr->rr_attrs[x].ra_value);
- }
-
- free(rr->rr_attrs);
- }
-
- if (rr->rr_actions) {
- for (x = 0; rr->rr_actions &&
- rr->rr_actions[x].ra_name; x++) {
- free(rr->rr_actions[x].ra_name);
- }
-
- free(rr->rr_actions);
- }
-
- if (rr->rr_childtypes) {
- for (x = 0; rr->rr_childtypes &&
- rr->rr_childtypes[x].rc_name; x++)
- free(rr->rr_childtypes[x].rc_name);
- free(rr->rr_childtypes);
- }
-
- free(rr);
-}
-
-
-/**
- Destroy a list of resource rules.
-
- @param rules List of rules to destroy.
- */
-void
-destroy_resource_rules(resource_rule_t **rules)
-{
- resource_rule_t *rr;
-
- while ((rr = *rules)) {
- list_remove(rules, rr);
- destroy_resource_rule(rr);
- }
-}
-
-
-/**
- Get and store the maxparents (max instances) attribute for a given
- resource rule set.
-
- @param doc Pre-parsed XML document pointer.
- @param ctx Pre-allocated XML XPath context pointer.
- @param base XPath prefix to search
- @param rr Resource rule to store new information in.
- */
-static void
-_get_maxparents(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base,
- resource_rule_t *rr)
-{
- char xpath[256];
- char *ret;
-
- snprintf(xpath, sizeof(xpath),
- "%s/attributes/@maxinstances",
- base);
- ret = xpath_get_one(doc, ctx, xpath);
- if (ret) {
- rr->rr_maxrefs = atoi(ret);
- if (rr->rr_maxrefs < 0)
- rr->rr_maxrefs = 0;
- free(ret);
- }
-}
-
-
-/**
- Get and store a bit field.
-
- @param doc Pre-parsed XML document pointer.
- @param ctx Pre-allocated XML XPath context pointer.
- @param base XPath prefix to search
- @param rr Resource rule to store new information in.
- */
-static void
-_get_rule_flag(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base,
- resource_rule_t *rr, const char *flag, int bit)
-{
- char xpath[256];
- char *ret;
-
- snprintf(xpath, sizeof(xpath),
- "%s/attributes/@%s",
- base, flag);
- ret = xpath_get_one(doc, ctx, xpath);
- if (ret) {
- if (atoi(ret)) {
- rr->rr_flags |= bit;
- } else {
- rr->rr_flags &= ~bit;
- }
- free(ret);
- }
-}
-
-
-/**
- Get and store the version
-
- @param doc Pre-parsed XML document pointer.
- @param ctx Pre-allocated XML XPath context pointer.
- @param base XPath prefix to search
- @param rr Resource rule to store new information in.
- */
-static void
-_get_version(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base,
- resource_rule_t *rr)
-{
- char xpath[256];
- char *ret;
-
- snprintf(xpath, sizeof(xpath), "%s/@version", base);
- ret = xpath_get_one(doc, ctx, xpath);
- if (ret) {
- rr->rr_version = ret;
- free(ret);
- }
- rr->rr_version = NULL;
-}
-
-
-/* Relying on compiler to cope with constants efficiently */
-#define TIMEF_M ( 60 * 1 )
-#define TIMEF_H ( 60 * TIMEF_M )
-#define TIMEF_D ( 24 * TIMEF_H )
-#define TIMEF_W ( 7 * TIMEF_D )
-#define TIMEF_Y ( 365 * TIMEF_D )
-
-/* NOTE: Only int type oveflows are checked (no targeted against time_t) */
-int
-expand_time (const char *val)
-{
- int curval, tmp, ret = 0;
-
- if (!val || *val == '\0')
- return 0;
-
- do {
- curval = 0;
-
- while (isdigit(*val)) {
- tmp = *val - '0';
-
- if (curval > INT_MAX/10
- || (curval == INT_MAX/10 && tmp > INT_MAX%10))
- /* Overflow */
- break;
-
- curval *= 10;
- curval += tmp;
- ++val;
- }
-
- if (isdigit(*val))
- /* Overflow detected */
- return 0;
-
- /* Watch for overflow also here */
- switch(*val) {
- case 0:
- case 'S':
- case 's':
- break;
- case 'M':
- case 'm':
- if (curval > INT_MAX/TIMEF_M)
- return 0;
- curval *= TIMEF_M;
- break;
- case 'h':
- case 'H':
- if (curval > INT_MAX/TIMEF_H)
- return 0;
- curval *= TIMEF_H;
- break;
- case 'd':
- case 'D':
- if (curval > INT_MAX/TIMEF_D)
- return 0;
- curval *= TIMEF_D;
- break;
- case 'w':
- case 'W':
- if (curval > INT_MAX/TIMEF_W)
- return 0;
- curval *= TIMEF_W;
- break;
- case 'y':
- case 'Y':
- if (curval > INT_MAX/TIMEF_Y)
- return 0;
- curval *= TIMEF_Y;
- break;
- default:
- curval = 0;
- }
- ret += curval;
-
- } while (*++val != '\0');
-
- return ret;
-}
-
-
-
-/**
- * Store a resource action
- * @param actsp Action array; may be modified and returned!
- * @param name Name of the action
- * @param depth Resource depth (status/monitor; -1 means *ALL LEVELS*
- * ... this means that only the highest-level check depth
- * will ever be performed!)
- * @param timeout Timeout (not used)
- * @param interval Time interval for status/monitor
- * @return 0 on success, -1 on failure
- *
- */
-int
-store_action(resource_act_t **actsp, char *name, int depth,
- int timeout, int interval)
-{
- int x = 0, replace = 0;
- resource_act_t *acts = *actsp;
-
- if (!name)
- return -1;
-
- if (depth < 0 && timeout < 0 && interval < 0)
- return -1;
-
- if (!acts) {
- /* Can't create with anything < 0 */
- if (depth < 0 || timeout < 0 || interval < 0)
- return -1;
-
- acts = malloc(sizeof(resource_act_t) * 2);
- if (!acts)
- return -1;
- acts[0].ra_name = name;
- acts[0].ra_depth = depth;
- acts[0].ra_timeout = timeout;
- acts[0].ra_interval = interval;
- acts[0].ra_last = 0;
- acts[1].ra_name = NULL;
-
- *actsp = acts;
- return 0;
- }
-
- for (x = 0; acts[x].ra_name; x++) {
- if (!strcmp(acts[x].ra_name, name) &&
- (depth == acts[x].ra_depth || depth == -1)) {
- printf("Replacing action '%s' depth %d: ",
- name, acts[x].ra_depth);
- if (timeout >= 0) {
- printf("timeout: %d->%d ",
- (int)acts[x].ra_timeout,
- (int)timeout);
- acts[x].ra_timeout = timeout;
- }
- if (interval >= 0) {
- printf("interval: %d->%d",
- (int)acts[x].ra_interval,
- (int)interval);
- acts[x].ra_interval = interval;
- }
- acts[x].ra_last = 0;
- printf("\n");
- replace = 1;
- }
- }
-
- if (replace)
- /* If we replaced something, we're done */
- return 1;
-
- /* Can't create with anything < 0 */
- if (depth < 0 || timeout < 0 || interval < 0)
- return -1;
-
- acts = realloc(acts, sizeof(resource_act_t) * (x+2));
- if (!acts)
- return -1;
-
- acts[x].ra_name = name;
- acts[x].ra_depth = depth;
- acts[x].ra_timeout = timeout;
- acts[x].ra_interval = interval;
- acts[x].ra_last = 0;
-
- acts[x+1].ra_name = NULL;
-
- *actsp = acts;
- return 0;
-}
-
-
-static void
-_get_actions(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base,
- resource_rule_t *rr)
-{
- char xpath[256];
- int idx = 0;
- char *act, *ret;
- int interval, timeout, depth;
-
- do {
- interval = 0;
- depth = 0;
- act = NULL;
- timeout = 0;
-
- snprintf(xpath, sizeof(xpath),
- "%s/action[%d]/@name", base, ++idx);
-
- act = xpath_get_one(doc, ctx, xpath);
- if (!act)
- break;
-
- snprintf(xpath, sizeof(xpath),
- "%s/action[%d]/@timeout", base, idx);
- ret = xpath_get_one(doc, ctx, xpath);
- if (ret) {
- timeout = expand_time(ret);
- if (timeout < 0)
- timeout = 0;
- free(ret);
- }
-
- snprintf(xpath, sizeof(xpath),
- "%s/action[%d]/@interval", base, idx);
- ret = xpath_get_one(doc, ctx, xpath);
- if (ret) {
- interval = expand_time(ret);
- if (interval < 1)
- interval = 1;
- free(ret);
- }
-
- if (!strcmp(act, "status") || !strcmp(act, "monitor")) {
- snprintf(xpath, sizeof(xpath),
- "%s/action[%d]/@depth", base, idx);
- ret = xpath_get_one(doc, ctx, xpath);
- if (ret) {
- depth = atoi(ret);
- if (depth < 0)
- depth = 0;
- free(ret);
- }
- }
-
- if (store_action(&rr->rr_actions, act, depth, timeout,
- interval) != 0)
- free(act);
- } while (1);
-}
-
-
-
-
-/**
- Store an attribute with the given name, value, and flags in a resource_t
- structure.
- XXX This could be rewritten to use the list macros.
-
- @param attrsp Attribute array to store new attribute in.
- @param name Name of attribute (must be non-null)
- @param value Value of attribute
- @param flags Attribute flags, or 0 if none.
- @return 0 on success, nonzero on error/failure
- */
-int
-store_attribute(resource_attr_t **attrsp, char *name, char *value, int flags)
-{
- int x = 0;
- resource_attr_t *attrs = *attrsp;
-
- if (!name)
- return -1;
-
- if (!attrs) {
- attrs = malloc(sizeof(resource_attr_t) * 2);
- if (!attrs)
- return -1;
- attrs[0].ra_name = name;
- attrs[0].ra_value = value;
- attrs[0].ra_flags = flags;
- attrs[1].ra_name = NULL;
- attrs[1].ra_value= NULL;
-
- *attrsp = attrs;
- return 0;
- }
-
- for (x = 0; attrs[x].ra_name; x++) {
- if (strcmp(attrs[x].ra_name, name) == 0) {
- free(name);
- free(attrs[x].ra_value);
- attrs[x].ra_value = value;
- attrs[x].ra_flags = flags;
- return 0;
- }
- }
-
- attrs = realloc(attrs, sizeof(resource_attr_t) * (x+2));
- if (!attrs)
- return -1;
-
- /* Primary attribute goes first. This makes this interaction
- with CCS work way faster. */
- if (flags & RA_PRIMARY) {
- attrs[x].ra_name = attrs[0].ra_name;
- attrs[x].ra_value = attrs[0].ra_value;
- attrs[x].ra_flags = attrs[0].ra_flags;
- attrs[0].ra_name = name;
- attrs[0].ra_value = value;
- attrs[0].ra_flags = flags;
- } else {
- attrs[x].ra_name = name;
- attrs[x].ra_value = value;
- attrs[x].ra_flags = flags;
- }
- attrs[x+1].ra_name = NULL;
- attrs[x+1].ra_value = NULL;
-
- *attrsp = attrs;
- return 0;
-}
-
-
-/**
- Store a child type in the child array of a resource rule.
- XXX Could be rewritten to use list macros.
-
- @param childp Child array. Might be modified.
- @param name Name of child type
- @param start Start level
- @param stop Stop level
- @param forbid Do NOT allow this child type to exist
- @param flags set to 1 to note that it was defined inline
- @return 0 on success, nonzero on failure
- */
-static int
-store_childtype(resource_child_t **childp, char *name, int start,
- int stop, int forbid, int flags)
-{
- int x = 0;
- resource_child_t *child = *childp;
-
- if (!name)
- return -1;
-
- if (!child) {
- child = malloc(sizeof(resource_child_t) * 2);
- if (!child)
- return -1;
- child[0].rc_name = name;
- child[0].rc_startlevel = start;
- child[0].rc_stoplevel = stop;
- child[0].rc_forbid = forbid;
- child[0].rc_flags = flags;
- child[1].rc_name = NULL;
-
- *childp = child;
- return 0;
- }
-
- for (x = 0; child[x].rc_name; x++);
-
- child = realloc(child, sizeof(resource_child_t) * (x+2));
- if (!child)
- return -1;
-
- child[x].rc_name = name;
- child[x].rc_startlevel = start;
- child[x].rc_stoplevel = stop;
- child[x].rc_forbid = forbid;
- child[x].rc_flags = flags;
- child[x+1].rc_name = NULL;
-
- *childp = child;
- return 0;
-}
-
-
-/**
- Print a resource_t structure to specified stream
-
- @param rr Resource rule to print.
- @param fp Destination stream.
- */
-void
-print_resource_rule(FILE *fp, resource_rule_t *rr)
-{
- int x;
-
- fprintf(fp, "Resource Rules for \"%s\"\n", rr->rr_type);
-
- if (rr->rr_version)
- fprintf(fp, "OCF API Version: %s\n", rr->rr_version);
-
- if (rr->rr_maxrefs)
- fprintf(fp, "Max instances: %d\n", rr->rr_maxrefs);
- if (rr->rr_agent)
- fprintf(fp, "Agent: %s\n", basename(rr->rr_agent));
-
- fprintf(fp, "Flags: ");
- if (rr->rr_flags) {
- if (rr->rr_flags & RF_INIT)
- fprintf(fp, "init_on_add ");
- if (rr->rr_flags & RF_DESTROY)
- fprintf(fp, "destroy_on_delete ");
- } else {
- fprintf(fp, "(none)");
- }
- fprintf(fp, "\n");
-
- fprintf(fp, "Attributes:\n");
- if (!rr->rr_attrs) {
- fprintf(fp, " - None -\n");
- goto actions;
- }
-
- for (x = 0; rr->rr_attrs[x].ra_name; x++) {
- fprintf(fp, " %s", rr->rr_attrs[x].ra_name);
-
- if (!rr->rr_attrs[x].ra_flags && !rr->rr_attrs[x].ra_value) {
- fprintf(fp, "\n");
- continue;
- }
-
- if (rr->rr_attrs[x].ra_flags) {
- fprintf(fp, " [");
- if (rr->rr_attrs[x].ra_flags & RA_PRIMARY)
- fprintf(fp, " primary");
- if (rr->rr_attrs[x].ra_flags & RA_UNIQUE)
- fprintf(fp, " unique");
- if (rr->rr_attrs[x].ra_flags & RA_REQUIRED)
- fprintf(fp, " required");
- if (rr->rr_attrs[x].ra_flags & RA_INHERIT)
- fprintf(fp, " inherit");
- if (rr->rr_attrs[x].ra_flags & RA_RECONFIG)
- fprintf(fp, " reconfig");
- fprintf(fp, " ]");
- }
-
- if (rr->rr_attrs[x].ra_value)
- fprintf(fp, " default=\"%s\"\n", rr->rr_attrs[x].ra_value);
- else
- fprintf(fp, "\n");
- }
-
-actions:
- fprintf(fp, "Actions:\n");
- if (!rr->rr_actions) {
- fprintf(fp, " - None -\n");
- goto children;
- }
-
- for (x = 0; rr->rr_actions[x].ra_name; x++) {
- fprintf(fp, " %s\n", rr->rr_actions[x].ra_name);
- if (rr->rr_actions[x].ra_timeout)
- fprintf(fp, " Timeout (hint): %d seconds\n",
- (int)rr->rr_actions[x].ra_timeout);
- if (rr->rr_actions[x].ra_depth)
- fprintf(fp, " OCF Check Depth (status/monitor): "
- "%d seconds\n",
- (int)rr->rr_actions[x].ra_depth);
- if (rr->rr_actions[x].ra_interval)
- fprintf(fp, " Check Interval: %d seconds\n",
- (int)rr->rr_actions[x].ra_interval);
- }
-
-
-children:
- fprintf(fp, "Explicitly defined child resource types:\n");
- if (!rr->rr_childtypes) {
- fprintf(fp, " - None -\n\n");
- return;
- }
- for (x = 0; rr->rr_childtypes[x].rc_name; x++) {
- fprintf(fp, " %s", rr->rr_childtypes[x].rc_name);
- if (rr->rr_childtypes[x].rc_forbid) {
- fprintf(fp, " (forbidden)\n");
- continue;
- }
- if (rr->rr_childtypes[x].rc_startlevel ||
- rr->rr_childtypes[x].rc_stoplevel) {
- fprintf(fp, " [");
-
- if (rr->rr_childtypes[x].rc_startlevel) {
- fprintf(fp, " startlevel = %d",
- rr->rr_childtypes[x].rc_startlevel);
- }
-
- if (rr->rr_childtypes[x].rc_stoplevel) {
- fprintf(fp, " stoplevel = %d",
- rr->rr_childtypes[x].rc_stoplevel);
- }
- fprintf(fp, " ] ");
- }
-
- fprintf(fp, "\n");
- }
-
- fprintf(fp, "\n");
-}
-
-
-void
-dump_resource_rules(FILE *fp, resource_rule_t **rules)
-{
- resource_rule_t *curr;
- int x;
-
- list_for(rules, curr, x) {
- print_resource_rule(fp, curr);
- }
-}
-
-
-void
-print_resource_rules(resource_rule_t **rules)
-{
- dump_resource_rules(stdout, rules);
-}
-
-
-/**
- Get and store attributes for a given instance of a resource rule.
-
- @param doc Pre-parsed XML document pointer.
- @param ctx Pre-allocated XML XPath context pointer.
- @param base XPath prefix to search
- @param rr Resource rule to store new information in.
- @return 0
- */
-static int
-_get_rule_attrs(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base,
- resource_rule_t *rr)
-{
- char *ret, *attrname, xpath[256];
- int x, flags, primary_found = 0;
-
- for (x = 1; 1; x++) {
- snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@name",
- base, x);
-
- attrname = xpath_get_one(doc,ctx,xpath);
- if (!attrname)
- break;
-
- flags = 0;
-
- /*
- See if this is either the primary identifier or
- a required field.
- */
- snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@required",
- base, x);
- if ((ret = xpath_get_one(doc,ctx,xpath))) {
- if ((atoi(ret) != 0) || (ret[0] == 'y'))
- flags |= RA_REQUIRED;
- free(ret);
- }
-
- /*
- See if this is supposed to be unique
- */
- snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@unique",
- base, x);
- if ((ret = xpath_get_one(doc,ctx,xpath))) {
- if ((atoi(ret) != 0) || (ret[0] == 'y'))
- flags |= RA_UNIQUE;
- free(ret);
- }
-
- snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@primary",
- base, x);
- if ((ret = xpath_get_one(doc,ctx,xpath))) {
- if ((atoi(ret) != 0) || (ret[0] == 'y')) {
- if (primary_found) {
- free(ret);
- free(attrname);
- printf("Multiple primary "
- "definitions for "
- "resource type %s\n",
- rr->rr_type);
- return -1;
- }
- flags |= RA_PRIMARY;
- primary_found = 1;
- }
- free(ret);
- }
-
- /*
- See if this can be reconfigured on the fly without a
- stop/start
- */
- snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@reconfig",
- base, x);
- if ((ret = xpath_get_one(doc,ctx,xpath))) {
- if ((atoi(ret) != 0) || (ret[0] == 'y'))
- flags |= RA_RECONFIG;
- free(ret);
- }
-
- /*
- See if this is supposed to be inherited;
- inheritance supercedes a specified default value
- */
- snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@inherit",
- base, x);
- if ((ret = xpath_get_one(doc,ctx,xpath))) {
- flags |= RA_INHERIT;
-
- if (flags & (RA_REQUIRED | RA_PRIMARY | RA_UNIQUE)) {
- free(ret);
- free(attrname);
- printf("Can not inherit and be primary, "
- "unique, or required\n");
- return -1;
- }
-
- /* Don't free ret */
-
- } else {
- /*
- Use default value, if specified, as the attribute
- value.
- */
- snprintf(xpath, sizeof(xpath),
- "%s/parameter[%d]/content/@default", base, x);
- ret = xpath_get_one(doc,ctx,xpath);
- }
-
- /*
- Store the attribute. We'll ensure all required
- attributes are present soon.
- */
- if (store_attribute(&rr->rr_attrs, attrname, ret, flags) != 0) {
- free(attrname);
- free(ret);
- }
- }
-
- return 0;
-}
-
-
-/**
- Get and store attributes for a given instance of a resource.
-
- @param doc Pre-parsed XML document pointer.
- @param ctx Pre-allocated XML XPath context pointer.
- @param base XPath prefix to search
- @param rr Resource rule to store new information in.
- @return 0
- */
-static int
-_get_childtypes(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base,
- resource_rule_t *rr)
-{
- char *ret, *childname, xpath[256];
- int x, startlevel = 0, stoplevel = 0, forbid = 0;
-
- for (x = 1; 1; x++) {
- snprintf(xpath, sizeof(xpath), "%s/child[%d]/@type",
- base, x);
-
- ret = xpath_get_one(doc,ctx,xpath);
- if (!ret)
- break;
-
- startlevel = stoplevel = forbid = 0;
- childname = ret;
-
- /*
- Try to get the start level if it exists
- */
- snprintf(xpath, sizeof(xpath), "%s/child[%d]/@start",
- base, x);
- if ((ret = xpath_get_one(doc,ctx,xpath))) {
- startlevel = atoi(ret);
- free(ret);
- }
-
-
- /*
- Try to get the stop level if it exists
- */
- snprintf(xpath, sizeof(xpath), "%s/child[%d]/@stop",
- base, x);
- if ((ret = xpath_get_one(doc,ctx,xpath))) {
- stoplevel = atoi(ret);
- free(ret);
- }
-
- /*
- Get the 'forbidden' flag if it exists
- */
- snprintf(xpath, sizeof(xpath), "%s/child[%d]/@forbid",
- base, x);
- if ((ret = xpath_get_one(doc,ctx,xpath))) {
- forbid = atoi(ret);
- free(ret);
- }
-
- /*
- Store the attribute. We'll ensure all required
- attributes are present soon.
- */
- if (childname)
- store_childtype(&rr->rr_childtypes, childname,
- startlevel, stoplevel, forbid, 0);
- }
-
- return 0;
-}
-
-
-/**
- Read a file from a stdout pipe.
- */
-static int
-read_pipe(int fd, char **file, size_t *length)
-{
- char buf[4096];
- int n, done = 0;
-
- *file = NULL;
- *length = 0;
-
- while (!done) {
-
- n = read(fd, buf, sizeof(buf));
- if (n < 0) {
-
- if (errno == EINTR)
- continue;
-
- if (*file)
- free(*file);
- return -1;
- }
-
- if (n == 0 && (!*length))
- return 0;
-
- if (n == 0) {
- done = 1;
- }
-
- if (*file)
- *file = realloc(*file, (*length) + n + done);
- else
- *file = malloc(n + done);
-
- if (!*file)
- return -1;
-
- memcpy((*file) + (*length), buf, n);
- *length += (done + n);
- }
-
- /* Null terminator */
- (*file)[(*length) - 1] = 0;
-
- return 0;
-}
-
-
-static xmlDocPtr
-read_resource_agent_metadata(char *filename)
-{
- int pid;
- int _pipe[2];
- char *data;
- size_t size;
- xmlDocPtr doc;
-
- if (pipe(_pipe) == -1)
- return NULL;
-
- pid = fork();
- if (pid == -1) {
- close(_pipe[0]);
- close(_pipe[1]);
- }
-
- if (pid == 0) {
- /* child */
- close(0);
- close(1);
- close(2);
-
- close(_pipe[0]);
- dup2(_pipe[1], 1);
- close(_pipe[1]);
-
- /* exec */
- execl(filename, filename, "meta-data", NULL);
- exit(1);
- }
-
- close(_pipe[1]);
- /* parent */
- if (read_pipe(_pipe[0], &data, &size) == -1) {
- close(_pipe[0]);
- return NULL;
- }
-
- waitpid(pid, NULL, 0);
- close(_pipe[0]);
-
- if (!size) {
- free(data);
- return NULL;
- }
-
- doc = xmlParseMemory(data, size);
- free(data);
- return doc;
-}
-
-
-/**
- Load the XML rule set for a resource and store attributes, constructing
- a new resource_t structure.
-
- @param filename File name to load rules from
- @param rules Rule list to add new rules to
- @return 0
- */
-static int
-load_resource_rulefile(char *filename, resource_rule_t **rules)
-{
- resource_rule_t *rr = NULL;
- xmlDocPtr doc = NULL;
- xmlXPathContextPtr ctx = NULL;
- int ruleid=0;
- char *type;
- char base[256];
-
- doc = read_resource_agent_metadata(filename);
- if (!doc)
- return 0;
- ctx = xmlXPathNewContext(doc);
-
- do {
- /* Look for resource types */
- snprintf(base, sizeof(base), "/resource-agent[%d]/@name",
- ++ruleid);
- type = xpath_get_one(doc, ctx, base);
- if (!type)
- break;
-
- if (!strcasecmp(type, "action")) {
-#ifdef NO_CCS
- fprintf(stderr,
- "Error: Resource type '%s' is reserved",
- type);
-#else
- logt_print(LOG_ERR,
- "Error: Resource type '%s' is reserved",
- type);
-#endif
- free(type);
- break;
- }
-
- rr = malloc(sizeof(*rr));
- if (!rr) {
- free(type);
- break;
- }
- memset(rr,0,sizeof(*rr));
-
- rr->rr_flags = RF_INIT | RF_DESTROY;
- rr->rr_type = type;
- snprintf(base, sizeof(base), "/resource-agent[%d]", ruleid);
-
- /*
- First, grab the global attributes if existent
- */
- _get_version(doc, ctx, base, rr);
-
- snprintf(base, sizeof(base),
- "/resource-agent[%d]/special[@tag=\"rgmanager\"]",
- ruleid);
- _get_maxparents(doc, ctx, base, rr);
- _get_rule_flag(doc, ctx, base, rr, "init_on_add", RF_INIT);
- _get_rule_flag(doc, ctx, base, rr, "destroy_on_delete", RF_DESTROY);
- rr->rr_agent = strdup(filename);
-
- /*
- Second, add the children fields
- */
- _get_childtypes(doc, ctx, base, rr);
-
- /*
- Get the OCF status check intervals/monitor.
- */
- snprintf(base, sizeof(base), "/resource-agent[%d]/actions",
- ruleid);
- _get_actions(doc, ctx, base, rr);
-
-
- /*
- Last, load the attributes from our XML file and their
- respective instantiations from CCS
- */
- snprintf(base, sizeof(base),
- "/resource-agent[%d]/parameters", ruleid);
- if (_get_rule_attrs(doc, ctx, base, rr) < 0) {
- destroy_resource_rule(rr);
- rr = NULL;
- }
-
- if (!rr)
- continue;
-
- if (store_rule(rules, rr) != 0) {
- destroy_resource_rule(rr);
- rr = NULL;
- }
- } while (1);
-
- if (ctx)
- xmlXPathFreeContext(ctx);
- if (doc)
- xmlFreeDoc(doc);
-
- return 0;
-}
-
-
-/**
- Load all the resource rules we can find from our resource root
- directory.
-
- @param rules Rule list to create/add to
- @return 0 on success, -1 on failure. Sucess does not
- imply any rules have been found; only that no
- errors were encountered.
- */
-int
-load_resource_rules(const char *rpath, resource_rule_t **rules)
-{
- DIR *dir;
- struct dirent *de;
- char *fn, *dot;
- char path[2048];
- struct stat st_buf;
-
- dir = opendir(rpath);
- if (!dir)
- return -1;
-
- while ((de = readdir(dir))) {
-
- fn = basename(de->d_name);
- if (!fn)
- continue;
-
- /* Ignore files with common backup extension */
- if ((fn != NULL) && (strlen(fn) > 0) &&
- (fn[strlen(fn)-1] == '~'))
- continue;
-
- dot = strrchr(fn, '.');
- if (dot) {
- /* Ignore RPM installed save files, patches,
- diffs, etc. */
- if (!strncasecmp(dot, ".rpm", 4)) {
- fprintf(stderr, "Warning: "
- "Ignoring %s/%s: Bad extension %s\n",
- rpath, de->d_name, dot);
- continue;
- }
- }
-
- snprintf(path, sizeof(path), "%s/%s",
- rpath, de->d_name);
-
- if (stat(path, &st_buf))
- continue;
-
- if (S_ISDIR(st_buf.st_mode))
- continue;
-
- if (st_buf.st_mode & (S_IXUSR|S_IXOTH|S_IXGRP)) {
- printf("Loading resource rule from %s\n", path);
- load_resource_rulefile(path, rules);
- }
- }
-
- closedir(dir);
-
- return 0;
-}
-
-
-/**
- Find a resource rule given its type.
-
- @param rulelist Rule list to search
- @param type Rule type identifier
- @return Resource rule or NULL if not found.
- */
-resource_rule_t *
-find_rule_by_type(resource_rule_t **rulelist, const char *type)
-{
- resource_rule_t *curr = NULL;
-
- list_do(rulelist, curr) {
- if (!strcmp(curr->rr_type, type))
- return curr;
- } while (!list_done(rulelist, curr));
-
- return NULL;
-}
diff --git a/rgmanager/src/daemons/restart_counter.c b/rgmanager/src/daemons/restart_counter.c
deleted file mode 100644
index 8ed8f79..0000000
--- a/rgmanager/src/daemons/restart_counter.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/* Time-based restart counters for rgmanager */
-
-#include <stdio.h>
-#include <list.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <time.h>
-#include <restart_counter.h>
-
-
-
-#define RESTART_INFO_MAGIC 0x184820ab
-
-typedef struct {
- list_head();
- time_t restart_time;
-} restart_item_t;
-
-typedef struct {
- int magic;
- time_t expire_timeout;
- int max_restarts;
- int restart_count;
- restart_item_t *restart_nodes;
-} restart_info_t;
-
-
-#define VALIDATE(arg, ret) \
-do { \
- if (!arg) {\
- errno = EINVAL; \
- return ret; \
- } \
- if (((restart_info_t *)arg)->magic != RESTART_INFO_MAGIC) {\
- errno = EINVAL; \
- return ret; \
- } \
-} while(0)
-
-
-/* Remove expired restarts */
-static int
-restart_timer_purge(restart_counter_t arg, time_t now)
-{
- restart_info_t *restarts = (restart_info_t *)arg;
- restart_item_t *i;
- int x, done = 0;
-
- VALIDATE(arg, -1);
-
- /* No timeout */
- if (restarts->expire_timeout == 0)
- return 0;
-
- do {
- done = 1;
- list_for(&restarts->restart_nodes, i, x) {
- if ((now - i->restart_time) >=
- restarts->expire_timeout) {
- restarts->restart_count--;
- list_remove(&restarts->restart_nodes, i);
- done = 0;
- break;
- }
- }
- } while(!done);
-
- return 0;
-}
-
-
-int
-restart_count(restart_counter_t arg)
-{
- restart_info_t *restarts = (restart_info_t *)arg;
- time_t now;
-
- VALIDATE(arg, -1);
- now = time(NULL);
- restart_timer_purge(arg, now);
- return restarts->restart_count;
-}
-
-
-int
-restart_threshold_exceeded(restart_counter_t arg)
-{
- restart_info_t *restarts = (restart_info_t *)arg;
- time_t now;
-
- if (!arg)
- /* No max restarts / threshold = always
- ok to restart! */
- return 0;
-
- VALIDATE(arg, -1);
- now = time(NULL);
- restart_timer_purge(arg, now);
- if (restarts->restart_count >= restarts->max_restarts)
- return 1;
- return 0;
-}
-
-
-/* Add a restart entry to the list. Returns 1 if restart
- count is exceeded */
-int
-restart_add(restart_counter_t arg)
-{
- restart_info_t *restarts = (restart_info_t *)arg;
- restart_item_t *i;
- time_t t;
-
- if (!arg)
- /* No max restarts / threshold = always
- ok to restart! */
- return 0;
-
- VALIDATE(arg, -1);
-
- i = malloc(sizeof(*i));
- if (!i) {
- return -1;
- }
-
- t = time(NULL);
- i->restart_time = t;
-
- list_insert(&restarts->restart_nodes, i);
- restarts->restart_count++;
-
- /* Check and remove old entries */
- restart_timer_purge(restarts, t);
-
- if (restarts->restart_count >= restarts->max_restarts)
- return 1;
-
- return 0;
-}
-
-
-int
-restart_clear(restart_counter_t arg)
-{
- restart_info_t *restarts = (restart_info_t *)arg;
- restart_item_t *i;
-
- VALIDATE(arg, -1);
- while ((i = restarts->restart_nodes)) {
- list_remove(&restarts->restart_nodes, i);
- free(i);
- }
-
- restarts->restart_count = 0;
-
- return 0;
-}
-
-
-restart_counter_t
-restart_init(time_t expire_timeout, int max_restarts)
-{
- restart_info_t *info;
-
- if (max_restarts < 0) {
- errno = EINVAL;
- return NULL;
- }
-
- info = malloc(sizeof(*info));
- if (info == NULL)
- return NULL;
-
- info->magic = RESTART_INFO_MAGIC;
- info->expire_timeout = expire_timeout;
- info->max_restarts = max_restarts;
- info->restart_count = 0;
- info->restart_nodes = NULL;
-
- return (void *)info;
-}
-
-
-int
-restart_cleanup(restart_counter_t arg)
-{
- VALIDATE(arg, -1);
- restart_clear(arg);
- free(arg);
- return 0;
-}
diff --git a/rgmanager/src/daemons/restree.c b/rgmanager/src/daemons/restree.c
deleted file mode 100644
index b46986d..0000000
--- a/rgmanager/src/daemons/restree.c
+++ /dev/null
@@ -1,1935 +0,0 @@
-#include <libxml/parser.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/xpath.h>
-#include <ccs.h>
-#include <rg_locks.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <resgroup.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <list.h>
-#include <restart_counter.h>
-#include <reslist.h>
-#include <pthread.h>
-#include <logging.h>
-#include <assert.h>
-
-/* XXX from resrules.c */
-int _res_op(resource_node_t **tree, resource_t *first, char *type,
- void * __attribute__((unused))ret, int op);
-static inline int
-_res_op_internal(resource_node_t **tree, resource_t *first,
- char *type, void *__attribute__((unused))ret, int realop,
- resource_node_t *node);
-static inline int _res_op_internal(resource_node_t **tree, resource_t *first,
- char *type, void *__attribute__((unused))ret, int realop,
- resource_node_t *node);
-
-/* XXX from reslist.c */
-resource_act_t *act_dup(resource_act_t *acts);
-time_t get_time(char *action, int depth, resource_node_t *node);
-
-
-
-const char *ocf_errors[] = {
- "success", // 0
- "generic error", // 1
- "invalid argument(s)", // 2
- "function not implemented", // 3
- "insufficient privileges", // 4
- "program not installed", // 5
- "program not configured", // 6
- "not running",
- NULL
-};
-
-
-/* XXX MEGA HACK */
-#ifdef NO_CCS
-static int _no_op_mode_ = 0;
-void _no_op_mode(int arg);
-void
-_no_op_mode(int arg)
-{
- _no_op_mode_ = arg;
-}
-#endif
-
-
-/**
- ocf_strerror
- */
-static const char *
-ocf_strerror(int ret)
-{
- if (ret >= 0 && ret < OCF_RA_MAX)
- return ocf_errors[ret];
-
- return "unspecified";
-}
-
-
-/**
- Destroys an environment variable array.
-
- @param env Environment var to kill
- @see build_env
- */
-static void
-kill_env(char **env)
-{
- int x;
-
- for (x = 0; env[x]; x++)
- free(env[x]);
- free(env);
-}
-
-
-/**
- Adds OCF environment variables to a preallocated environment var array
-
- @param res Resource w/ additional variable stuff
- @param args Preallocated environment variable array
- @see build_env
- */
-static void
-add_ocf_stuff(resource_t *res, char **env, int depth, int refcnt, int timeout)
-{
- char ver[10];
- char *minor, *val;
- size_t n;
-
- if (!res->r_rule->rr_version)
- strncpy(ver, OCF_API_VERSION, sizeof(ver)-1);
- else
- strncpy(ver, res->r_rule->rr_version, sizeof(ver)-1);
- ver[sizeof(ver)-1] = '\0';
-
- minor = strchr(ver, '.');
- if (minor) {
- *minor = 0;
- minor++;
- } else
- minor = (char *)"0";
-
- /*
- Store the OCF major version
- */
- n = strlen(OCF_RA_VERSION_MAJOR_STR) + strlen(ver) + 2;
- val = malloc(n);
- if (!val)
- return;
- snprintf(val, n, "%s=%s", OCF_RA_VERSION_MAJOR_STR, ver);
- *env = val; env++;
-
- /*
- Store the OCF minor version
- */
- n = strlen(OCF_RA_VERSION_MINOR_STR) + strlen(minor) + 2;
- val = malloc(n);
- if (!val)
- return;
- snprintf(val, n, "%s=%s", OCF_RA_VERSION_MINOR_STR, minor);
- *env = val; env++;
-
- /*
- Store the OCF root
- */
- n = strlen(OCF_ROOT_STR) + strlen(OCF_ROOT) + 2;
- val = malloc(n);
- if (!val)
- return;
- snprintf(val, n, "%s=%s", OCF_ROOT_STR, OCF_ROOT);
- *env = val; env++;
-
- /*
- Store the OCF Resource Instance (primary attr)
- */
- n = strlen(OCF_RESOURCE_INSTANCE_STR) +
- strlen(res->r_rule->rr_type) + 1 +
- strlen(res->r_attrs[0].ra_value) + 2;
- val = malloc(n);
- if (!val)
- return;
- snprintf(val, n, "%s=%s:%s", OCF_RESOURCE_INSTANCE_STR,
- res->r_rule->rr_type,
- res->r_attrs[0].ra_value);
- *env = val; env++;
-
- /*
- Store the OCF Resource Type
- */
- n = strlen(OCF_RESOURCE_TYPE_STR) +
- strlen(res->r_rule->rr_type) + 2;
- val = malloc(n);
- if (!val)
- return;
- snprintf(val, n, "%s=%s", OCF_RESOURCE_TYPE_STR,
- res->r_rule->rr_type);
- *env = val; env++;
-
- /*
- Store the OCF Check Level (0 for now)
- */
- snprintf(ver, sizeof(ver), "%d", depth);
- n = strlen(OCF_CHECK_LEVEL_STR) + strlen(ver) + 2;
- val = malloc(n);
- if (!val)
- return;
- snprintf(val, n, "%s=%s", OCF_CHECK_LEVEL_STR, ver);
- *env = val; env++;
-
- /*
- Store the resource local refcnt (0 for now)
- */
- snprintf(ver, sizeof(ver), "%d", refcnt);
- n = strlen(OCF_REFCNT_STR) + strlen(ver) + 2;
- val = malloc(n);
- if (!val)
- return;
- snprintf(val, n, "%s=%s", OCF_REFCNT_STR, ver);
- *env = val; env++;
-
- /*
- Store the resource action timeout
- */
- snprintf(ver, sizeof(ver), "%d", timeout);
- n = strlen(OCF_TIMEOUT_STR) + strlen(ver) + 2;
- val = malloc(n);
- if (!val)
- return;
- snprintf(val, n, "%s=%s", OCF_TIMEOUT_STR, ver);
- *env = val; env++;
-}
-
-
-/**
- Allocate and fill an environment variable array.
-
- @param node Node in resource tree to use for parameters
- @param depth Depth (status/monitor/etc.)
- @return Newly allocated environment array or NULL if
- one could not be formed.
- @see kill_env res_exec add_ocf_stuff
- */
-static char **
-build_env(resource_node_t *node, int depth, int refcnt, int timeout)
-{
- resource_t *res = node->rn_resource;
- char **env;
- char *val;
- int x, attrs, n;
-
- for (attrs = 0; res->r_attrs && res->r_attrs[attrs].ra_name; attrs++);
- attrs += 9; /*
- Leave space for:
- OCF_RA_VERSION_MAJOR
- OCF_RA_VERSION_MINOR
- OCF_ROOT
- OCF_RESOURCE_INSTANCE
- OCF_RESOURCE_TYPE
- OCF_CHECK_LEVEL
- OCF_RESKEY_RGMANAGER_meta_refcnt
- OCF_RESKEY_RGMANAGER_meta_timeout
- (null terminator)
- */
-
- env = malloc(sizeof(char *) * attrs);
- if (!env)
- return NULL;
-
- memset(env, 0, sizeof(char *) * attrs);
-
- /* Reset */
- attrs = 0;
- for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) {
-
- val = (char *)attr_value(node, res->r_attrs[x].ra_name);
- if (!val)
- continue;
-
- /* Strlen of both + '=' + 'OCF_RESKEY' + '\0' terminator' */
- n = strlen(res->r_attrs[x].ra_name) + strlen(val) + 2 +
- strlen(OCF_RES_PREFIX);
-
- env[attrs] = malloc(n);
- if (!env[attrs]) {
- kill_env(env);
- return NULL;
- }
-
- /* Prepend so we don't conflict with normal shell vars */
- snprintf(env[attrs], n, "%s%s=%s", OCF_RES_PREFIX,
- res->r_attrs[x].ra_name, val);
-
-#if 0
- /* Don't uppercase; OCF-spec */
- for (n = 0; env[x][n] != '='; n++)
- env[x][n] &= ~0x20; /* Convert to uppercase */
-#endif
- ++attrs;
- }
-
- add_ocf_stuff(res, &env[attrs], depth, refcnt, timeout);
-
- return env;
-}
-
-
-/**
- Set all signal handlers to default for exec of a script.
- ONLY do this after a fork().
- */
-static void
-restore_signals(void)
-{
- sigset_t set;
- int x;
-
- for (x = 1; x < _NSIG; x++)
- signal(x, SIG_DFL);
-
- sigfillset(&set);
- sigprocmask(SIG_UNBLOCK, &set, NULL);
-}
-
-
-/** Find the index for a given operation / depth in a resource node */
-static int
-res_act_index(resource_node_t *node, const char *op_str, int depth)
-{
- int x = 0;
- resource_act_t *act;
-
- for (x = 0; node->rn_actions[x].ra_name; x++) {
- act = &node->rn_actions[x];
- if (depth != act->ra_depth)
- continue;
- if (strcasecmp(act->ra_name, op_str))
- continue;
- return x;
- }
-
- return -1;
-}
-
-
-/**
- Execute a resource-specific agent for a resource node in the tree.
-
- @param node Resource tree node we're dealing with
- @param op Operation to perform (stop/start/etc.)
- @param depth OCF Check level/depth
- @return Return value of script.
- @see build_env
- */
-int
-res_exec(resource_node_t *node, int op, const char *arg, int depth)
-{
- int childpid, pid;
- int ret = 0;
- int act_index;
- int inc = node->rn_resource->r_incarnations;
- time_t sleeptime = 0, timeout = 0;
- char **env = NULL;
- resource_t *res = node->rn_resource;
- const char *op_str = agent_op_str(op);
- char fullpath[2048];
-
- if (!res->r_rule->rr_agent)
- return 0;
-
- /* Get the action index for later */
- act_index = res_act_index(node, op_str, depth);
-
- /* This shouldn't happen, but execing an action for which
- we have an incorrect depth or no status action does not
- indicate a problem. This allows people writing resource
- agents to write agents which have no status/monitor function
- at their option, in violation of the OCF RA API specification. */
- if (act_index < 0)
- return 0;
-
- if (!(node->rn_flags & RF_ENFORCE_TIMEOUTS))
- timeout = node->rn_actions[act_index].ra_timeout;
-
- /* rgmanager ref counts are designed to track *other* incarnations
- on the host. So, if we're started/failed, the RA should not count
- this incarnation */
- if (inc && (node->rn_state == RES_STARTED ||
- node->rn_state == RES_FAILED))
- --inc;
-
-#ifdef DEBUG
- env = build_env(node, depth, inc, (int)timeout);
- if (!env)
- return -errno;
-#endif
-
-#ifdef NO_CCS
- if (_no_op_mode_) {
- printf("[%s] %s:%s\n", op_str, res->r_rule->rr_type,
- res->r_attrs->ra_value);
- return 0;
- }
-#endif
-
- childpid = fork();
- if (childpid < 0)
- return -errno;
-
- if (!childpid) {
- /* Child */
-#if 0
- printf("Exec of script %s, action %s type %s\n",
- res->r_rule->rr_agent, agent_op_str(op),
- res->r_rule->rr_type);
-#endif
-
-#ifndef DEBUG
- env = build_env(node, depth, inc, (int)timeout);
-#endif
-
- if (!env)
- exit(-ENOMEM);
-
- if (res->r_rule->rr_agent[0] != '/')
- snprintf(fullpath, sizeof(fullpath), "%s/%s",
- RESOURCE_ROOTDIR, res->r_rule->rr_agent);
- else
- snprintf(fullpath, sizeof(fullpath), "%s",
- res->r_rule->rr_agent);
-
- restore_signals();
- setpgrp();
-
- if (arg)
- execle(fullpath, fullpath, op_str, arg, NULL, env);
- else
- execle(fullpath, fullpath, op_str, NULL, env);
-
- /* Should not happen */
- free(env);
- exit(1);
- }
-
-#ifdef DEBUG
- kill_env(env);
-#endif
-
- if (node->rn_flags & RF_ENFORCE_TIMEOUTS)
- sleeptime = node->rn_actions[act_index].ra_timeout;
-
- if (sleeptime > 0) {
-
- /* There's a better way to do this, but this is easy and
- doesn't introduce signal woes */
- while (sleeptime) {
- pid = waitpid(childpid, &ret, WNOHANG);
-
- if (pid == childpid)
- break;
- sleep(1);
- --sleeptime;
- }
-
- if (pid != childpid && sleeptime == 0) {
-
- logt_print(LOG_ERR,
- "%s on %s:%s timed out after %d seconds\n",
- op_str, res->r_rule->rr_type,
- res->r_attrs->ra_value,
- (int)node->rn_actions[act_index].ra_timeout);
-
- /* This can't be guaranteed to kill even the child
- process if the child is in disk-wait :( */
- kill(childpid, SIGKILL);
- sleep(1);
- pid = waitpid(childpid, &ret, WNOHANG);
- if (pid == 0) {
- logt_print(LOG_ERR,
- "Task %s PID %d did not exit "
- "after SIGKILL\n",
- op_str, childpid);
- }
-
- /* Always an error if we time out */
- return 1;
- }
- } else {
- do {
- pid = waitpid(childpid, &ret, 0);
- if ((pid < 0) && (errno == EINTR))
- continue;
- } while (0);
- }
-
- if (WIFEXITED(ret)) {
-
- ret = WEXITSTATUS(ret);
-
- if (node->rn_state == RES_STOPPED &&
- op == RS_STOP && ret == OCF_RA_NOT_INSTALLED)
- ret = 0;
-
-#ifndef NO_CCS
- if ((op == RS_STATUS &&
- node->rn_state == RES_STARTED && ret) ||
- (op != RS_STATUS && ret)) {
-#else
- if (ret) {
-#endif
- logt_print(LOG_NOTICE,
- "%s on %s \"%s\" returned %d (%s)\n",
- op_str, res->r_rule->rr_type,
- res->r_attrs->ra_value, ret,
- ocf_strerror(ret));
- }
-
- return ret;
- }
-
- if (!WIFSIGNALED(ret))
- assert(0);
-
- return -EFAULT;
-}
-
-
-static inline void
-assign_restart_policy(resource_t *curres, resource_node_t *parent,
- resource_node_t *node, int ccsfd, char *base)
-{
- char *val;
- int max_restarts = 0;
- time_t restart_expire_time = 0;
- char tok[1024];
-
- if (!curres || !node)
- return;
- node->rn_restart_counter = NULL;
- if (parent &&
- !(node->rn_flags & RF_INDEPENDENT))
- return;
-
- if (node->rn_flags & RF_INDEPENDENT) {
- /* per-resource-node failures / expire times */
- snprintf(tok, sizeof(tok), "%s/@__max_restarts", base);
-#ifndef NO_CCS
- if (ccs_get(ccsfd, tok, &val) == 0) {
-#else
- if (conf_get(tok, &val) == 0) {
-#endif
- max_restarts = atoi(val);
- if (max_restarts <= 0)
- max_restarts = 0;
- free(val);
- }
-
- snprintf(tok, sizeof(tok), "%s/@__restart_expire_time", base);
-#ifndef NO_CCS
- if (ccs_get(ccsfd, tok, &val) == 0) {
-#else
- if (conf_get(tok, &val) == 0) {
-#endif
- restart_expire_time = (time_t)expand_time(val);
- if ((int64_t)restart_expire_time <= 0)
- restart_expire_time = 0;
- free(val);
- }
-
- if (restart_expire_time == 0 || max_restarts == 0)
- return;
- goto out_assign;
- }
-
- val = (char *)res_attr_value(curres, "max_restarts");
- if (!val)
- return;
- max_restarts = atoi(val);
- if (max_restarts <= 0)
- return;
- val = (char *)res_attr_value(curres, "restart_expire_time");
- if (val) {
- restart_expire_time = (time_t)expand_time(val);
- if ((int64_t)restart_expire_time < 0)
- return;
- }
-
-out_assign:
- node->rn_restart_counter = restart_init(restart_expire_time,
- max_restarts);
-}
-
-
-static inline int
-do_load_resource(int ccsfd, char *base,
- resource_rule_t *rule,
- resource_node_t **tree,
- resource_t **reslist,
- resource_node_t *parent,
- resource_node_t **newnode)
-{
- char tok[512];
- char *ref;
- resource_node_t *node;
- resource_t *curres;
- time_t failure_expire = 0;
- int max_failures = 0;
-
- snprintf(tok, sizeof(tok), "%s/@ref", base);
-
-#ifndef NO_CCS
- if (ccs_get(ccsfd, tok, &ref) != 0) {
-#else
- if (conf_get(tok, &ref) != 0) {
-#endif
- /* There wasn't an existing resource. See if there
- is one defined inline */
- curres = load_resource(ccsfd, rule, base);
- if (!curres) {
- /* No ref and no new one inline ==
- no more of the selected type */
- return 1;
- }
-
- if (store_resource(reslist, curres) != 0) {
- printf("Error storing %s resource\n",
- curres->r_rule->rr_type);
- destroy_resource(curres);
- return -1;
- }
-
- curres->r_flags = RF_INLINE;
-
- } else {
-
- curres = find_resource_by_ref(reslist, rule->rr_type,
- ref);
- if (!curres) {
- printf("Error: Reference to nonexistent "
- "resource %s (type %s)\n", ref,
- rule->rr_type);
- free(ref);
- return -1;
- }
-
- if (curres->r_flags & RF_INLINE) {
- printf("Error: Reference to inlined "
- "resource %s (type %s) is illegal\n",
- ref, rule->rr_type);
- free(ref);
- return -1;
- }
- free(ref);
- }
-
- /* Load it if its max refs hasn't been exceeded */
- if (rule->rr_maxrefs && (curres->r_refs >= rule->rr_maxrefs)){
- printf("Warning: Max references exceeded for resource"
- " %s (type %s)\n", curres->r_attrs[0].ra_name,
- rule->rr_type);
- return -1;
- }
-
- node = malloc(sizeof(*node));
- if (!node)
- return -1;
-
- memset(node, 0, sizeof(*node));
-
- //printf("New resource tree node: %s:%s \n", curres->r_rule->rr_type,curres->r_attrs->ra_value);
-
- node->rn_child = NULL;
- node->rn_parent = parent;
- node->rn_resource = curres;
- node->rn_state = RES_STOPPED;
- node->rn_flags = 0;
- node->rn_actions = (resource_act_t *)act_dup(curres->r_actions);
-
-
- if (parent) {
- /* Independent subtree / non-critical for top-level is
- * not useful and can interfere with restart thresholds for
- * non critical resources */
- snprintf(tok, sizeof(tok), "%s/@__independent_subtree", base);
-#ifndef NO_CCS
- if (ccs_get(ccsfd, tok, &ref) == 0) {
-#else
- if (conf_get(tok, &ref) == 0) {
-#endif
- if (atoi(ref) == 1 || strcasecmp(ref, "yes") == 0)
- node->rn_flags |= RF_INDEPENDENT;
- if (atoi(ref) == 2 || strcasecmp(ref, "non-critical") == 0) {
- curres->r_flags |= RF_NON_CRITICAL;
- }
- free(ref);
- }
- }
-
- snprintf(tok, sizeof(tok), "%s/@__enforce_timeouts", base);
-#ifndef NO_CCS
- if (ccs_get(ccsfd, tok, &ref) == 0) {
-#else
- if (conf_get(tok, &ref) == 0) {
-#endif
- if (atoi(ref) > 0 || strcasecmp(ref, "yes") == 0)
- node->rn_flags |= RF_ENFORCE_TIMEOUTS;
- free(ref);
- }
-
- /* per-resource-node failures / expire times */
- snprintf(tok, sizeof(tok), "%s/@__max_failures", base);
-#ifndef NO_CCS
- if (ccs_get(ccsfd, tok, &ref) == 0) {
-#else
- if (conf_get(tok, &ref) == 0) {
-#endif
- max_failures = atoi(ref);
- if (max_failures < 0)
- max_failures = 0;
- free(ref);
- }
-
- snprintf(tok, sizeof(tok), "%s/@__failure_expire_time", base);
-#ifndef NO_CCS
- if (ccs_get(ccsfd, tok, &ref) == 0) {
-#else
- if (conf_get(tok, &ref) == 0) {
-#endif
- failure_expire = (time_t)expand_time(ref);
- if ((int64_t)failure_expire < 0)
- failure_expire = 0;
- free(ref);
- }
-
- if (max_failures && failure_expire) {
- node->rn_failure_counter = restart_init(failure_expire,
- max_failures);
- }
-
- curres->r_refs++;
-
- if (curres->r_refs > 1 &&
- (curres->r_flags & RF_NON_CRITICAL)) {
- res_build_name(tok, sizeof(tok), curres);
- printf("Non-critical flag for %s is being cleared due to multiple references.\n", tok);
- curres->r_flags &= ~RF_NON_CRITICAL;
- }
-
- if (curres->r_flags & RF_NON_CRITICAL) {
- /* Independent subtree is implied if a
- * resource is non-critical
- */
- node->rn_flags |= RF_NON_CRITICAL | RF_INDEPENDENT;
-
- }
-
- assign_restart_policy(curres, parent, node, ccsfd, base);
-
- *newnode = node;
-
- list_insert(tree, node);
-
- return 0;
-}
-
-
-/**
- Build the resource tree. If a new resource is defined inline, add it to
- the resource list. All rules, however, must have already been read in.
-
- @param ccsfd File descriptor connected to CCS
- @param tree Tree to modify/insert on to
- @param parent Parent node, if one exists.
- @param rule Rule surrounding the new node
- @param rulelist List of all rules allowed in the tree.
- @param reslist List of all currently defined resources
- @param base Base CCS path.
- @see destroy_resource_tree
- */
-#define RFL_FOUND 0x1
-#define RFL_FORBID 0x2
-static int
-build_tree(int ccsfd, resource_node_t **tree,
- resource_node_t *parent,
- resource_rule_t *rule,
- resource_rule_t **rulelist,
- resource_t **reslist, char *base)
-{
- char tok[512];
- resource_rule_t *childrule;
- resource_node_t *node = NULL;
- char *ref;
- char *tmp;
- int ccount = 0, x = 0, y = 0, flags = 0;
-
- //printf("DESCEND: %s / %s\n", rule?rule->rr_type:"(none)", base);
-
- /* Pass 1: typed / defined children */
- for (y = 0; rule && rule->rr_childtypes &&
- rule->rr_childtypes[y].rc_name; y++) {
-
-
- flags = 0;
- list_for(rulelist, childrule, x) {
- if (strcmp(rule->rr_childtypes[y].rc_name,
- childrule->rr_type))
- continue;
-
- flags |= RFL_FOUND;
-
- if (rule->rr_childtypes[y].rc_forbid)
- flags |= RFL_FORBID;
-
- break;
- }
-
- if (flags & RFL_FORBID)
- /* Allow all *but* forbidden */
- continue;
-
- if (!(flags & RFL_FOUND))
- /* Not found? Wait for pass 2 */
- continue;
-
- //printf("looking for %s %s @ %s\n",
- //rule->rr_childtypes[y].rc_name,
- //childrule->rr_type, base);
- for (x = 1; ; x++) {
-
- /* Search for base/type[x]/@ref - reference an existing
- resource */
- snprintf(tok, sizeof(tok), "%s/%s[%d]", base,
- childrule->rr_type, x);
-
- flags = 1;
- switch(do_load_resource(ccsfd, tok, childrule, tree,
- reslist, parent, &node)) {
- case -1:
- continue;
- case 1:
- /* 1 == no more */
- //printf("No resource found @ %s\n", tok);
- flags = 0;
- break;
- case 0:
- break;
- }
- if (!flags)
- break;
-
- /* Got a child :: bump count */
- snprintf(tok, sizeof(tok), "%s/%s[%d]", base,
- childrule->rr_type, x);
-
- /* Kaboom */
- build_tree(ccsfd, &node->rn_child, node, childrule,
- rulelist, reslist, tok);
-
- }
- }
-
-
- /* Pass 2: untyped children */
- for (ccount=1; ; ccount++) {
- snprintf(tok, sizeof(tok), "%s/child::*[%d]", base, ccount);
-
-#ifndef NO_CCS
- if (ccs_get(ccsfd, tok, &ref) != 0) {
-#else
- if (conf_get(tok, &ref) != 0) {
-#endif
- /* End of the line. */
- //printf("End of the line: %s\n", tok);
- break;
- }
-
- tmp = strchr(ref, '=');
- if (tmp) {
- *tmp = 0;
- } else {
- /* no = sign... bad */
- free(ref);
- continue;
- }
-
- /* Find the resource rule */
- flags = 0;
- list_for(rulelist, childrule, x) {
- if (!strcasecmp(childrule->rr_type, ref)) {
- /* Ok, matching rule found */
- flags = 1;
- break;
- }
- }
- /* No resource rule matching the child? Press on... */
- if (!flags) {
- free(ref);
- continue;
- }
-
- flags = 0;
- /* Don't descend on anything we should have already picked
- up on in the above loop */
- for (y = 0; rule && rule->rr_childtypes &&
- rule->rr_childtypes[y].rc_name; y++) {
- /* SKIP defined child types of any type */
- if (strcmp(rule->rr_childtypes[y].rc_name, ref))
- continue;
- if (rule->rr_childtypes[y].rc_flags == 0) {
- /* 2 = defined as a real child */
- flags = 2;
- break;
- }
-
- flags = 1;
- break;
- }
-
- free(ref);
- if (flags == 2)
- continue;
-
- x = 1;
- switch(do_load_resource(ccsfd, tok, childrule, tree,
- reslist, parent, &node)) {
- case -1:
- continue;
- case 1:
- /* no more found */
- x = 0;
- printf("No resource found @ %s\n", tok);
- break;
- case 0:
- /* another is found */
- break;
- }
- if (!x) /* no more found */
- break;
-
- /* childrule = rule set of this child at this point */
- /* tok = set above; if we got this far, we're all set */
- /* Kaboom */
-
- build_tree(ccsfd, &node->rn_child, node, childrule,
- rulelist, reslist, tok);
- }
-
- //printf("ASCEND: %s / %s\n", rule?rule->rr_type:"(none)", base);
- return 0;
-}
-
-
-/**
- Set up to call build_tree. Hides the nastiness from the user.
-
- @param ccsfd File descriptor connected to CCS
- @param tree Tree pointer. Should start as a pointer to NULL.
- @param rulelist List of all rules allowed
- @param reslist List of all currently defined resources
- @return 0
- @see build_tree destroy_resource_tree
- */
-int
-build_resource_tree(int ccsfd, resource_node_t **tree,
- resource_rule_t **rulelist,
- resource_t **reslist)
-{
- resource_node_t *root = NULL;
- char tok[512];
-
- snprintf(tok, sizeof(tok), "%s", RESOURCE_TREE_ROOT);
-
- /* Find and build the list of root nodes */
- build_tree(ccsfd, &root, NULL, NULL/*curr*/, rulelist, reslist, tok);
-
- if (root)
- *tree = root;
-
- return 0;
-}
-
-
-/**
- Deconstruct a resource tree.
-
- @param tree Tree to obliterate.
- @see build_resource_tree
- */
-void
-destroy_resource_tree(resource_node_t **tree)
-{
- resource_node_t *node = NULL;
-
- while ((node = *tree)) {
- if ((*tree)->rn_child)
- destroy_resource_tree(&(*tree)->rn_child);
-
- list_remove(tree, node);
-
- if (node->rn_restart_counter) {
- restart_cleanup(node->rn_restart_counter);
- }
-
- if (node->rn_failure_counter) {
- restart_cleanup(node->rn_failure_counter);
- }
-
- if(node->rn_actions){
- free(node->rn_actions);
- }
- free(node);
- }
-}
-
-
-static void
-_print_resource_tree(FILE *fp, resource_node_t **tree, int level)
-{
- resource_node_t *node;
- int x, y;
-
- list_do(tree, node) {
- for (x = 0; x < level; x++)
- fprintf(fp, " ");
-
- fprintf(fp, "%s", node->rn_resource->r_rule->rr_type);
- if (node->rn_flags) {
- fprintf(fp, " [ ");
- if (node->rn_flags & RF_INLINE)
- fprintf(fp, "INLINE ");
- if (node->rn_flags & RF_NEEDSTOP)
- fprintf(fp, "NEEDSTOP ");
- if (node->rn_flags & RF_NEEDSTART)
- fprintf(fp, "NEEDSTART ");
- if (node->rn_flags & RF_COMMON)
- fprintf(fp, "COMMON ");
- if (node->rn_flags & RF_INDEPENDENT)
- fprintf(fp, "INDEPENDENT ");
- if (node->rn_flags & RF_RECONFIG)
- fprintf(fp, "RECONFIG ");
- if (node->rn_flags & RF_INIT)
- fprintf(fp, "INIT ");
- if (node->rn_flags & RF_DESTROY)
- fprintf(fp, "DESTROY ");
- if (node->rn_flags & RF_ENFORCE_TIMEOUTS)
- fprintf(fp, "ENFORCE-TIMEOUTS ");
- if (node->rn_flags & RF_NON_CRITICAL)
- fprintf(fp, "NON-CRITICAL ");
- fprintf(fp, "]");
- }
-
- fprintf(fp, " (S%d) {\n", node->rn_state);
-
- for (x = 0; node->rn_resource->r_attrs &&
- node->rn_resource->r_attrs[x].ra_value; x++) {
- for (y = 0; y < level+1; y++)
- fprintf(fp, " ");
- fprintf(fp, "%s = \"%s\";\n",
- node->rn_resource->r_attrs[x].ra_name,
- attr_value(node,
- node->rn_resource->r_attrs[x].ra_name)
- );
- }
-
- _print_resource_tree(fp, &node->rn_child, level + 1);
-
- for (x = 0; x < level; x++)
- fprintf(fp, " ");
- fprintf(fp, "}\n");
- } while (!list_done(tree, node));
-}
-
-
-void
-print_resource_tree(resource_node_t **tree)
-{
- _print_resource_tree(stdout, tree, 0);
-}
-
-
-void
-dump_resource_tree(FILE *fp, resource_node_t **tree)
-{
- _print_resource_tree(fp, tree, 0);
-}
-
-
-static inline int
-_do_child_levels(resource_node_t **tree, resource_t *first, void *ret,
- int op)
-{
- resource_node_t *node = *tree;
- resource_t *res = node->rn_resource;
- resource_rule_t *rule = res->r_rule;
- int l, lev, x, rv = 0;
-
- for (l = 1; l <= RESOURCE_MAX_LEVELS; l++) {
-
- for (x = 0; rule->rr_childtypes &&
- rule->rr_childtypes[x].rc_name; x++) {
-
- if(op == RS_STOP)
- lev = rule->rr_childtypes[x].rc_stoplevel;
- else
- lev = rule->rr_childtypes[x].rc_startlevel;
-
- if (!lev || lev != l)
- continue;
-
-#if 0
- printf("%s children of %s type %s (level %d)\n",
- agent_op_str(op),
- node->rn_resource->r_rule->rr_type,
- rule->rr_childtypes[x].rc_name, l);
-#endif
-
- /* Do op on all children at our level */
- rv |= _res_op(&node->rn_child, first,
- rule->rr_childtypes[x].rc_name,
- ret, op);
-
- if (rv & SFL_FAILURE && op != RS_STOP)
- return rv;
- }
-
- if (rv != 0 && op != RS_STOP)
- return rv;
- }
-
- return rv;
-}
-
-
-static inline int
-_xx_child_internal(resource_node_t *node, resource_t *first,
- resource_node_t *child, void *ret, int op)
-{
- int x;
- resource_rule_t *rule = node->rn_resource->r_rule;
-
- for (x = 0; rule->rr_childtypes &&
- rule->rr_childtypes[x].rc_name; x++) {
- if (!strcmp(child->rn_resource->r_rule->rr_type,
- rule->rr_childtypes[x].rc_name)) {
- if (rule->rr_childtypes[x].rc_startlevel ||
- rule->rr_childtypes[x].rc_stoplevel) {
- return 0;
- }
- }
- }
-
- return _res_op_internal(&child, first,
- child->rn_resource->r_rule->rr_type,
- ret, op, child);
-}
-
-
-static inline int
-_do_child_default_level(resource_node_t **tree, resource_t *first,
- void *ret, int op)
-{
- resource_node_t *node = *tree, *child;
- int y, rv = 0;
-
- if (op == RS_START || op == RS_STATUS) {
- list_for(&node->rn_child, child, y) {
- rv |= _xx_child_internal(node, first, child, ret, op);
-
- if (rv & SFL_FAILURE)
- return rv;
- }
- } else {
- list_for_rev(&node->rn_child, child, y) {
- rv |= _xx_child_internal(node, first, child, ret, op);
- }
- }
-
- return rv;
-}
-
-
-
-
-
-/**
- Nasty codependent function. Perform an operation by numerical level
- at some point in the tree. This allows indirectly-dependent resources
- (such as IP addresses and user scripts) to have ordering without requiring
- a direct dependency.
-
- @param tree Resource tree to search/perform operations on
- @param first Resource we're looking to perform the operation on,
- if one exists.
- @param ret Unused, but will be used to store status information
- such as resources consumed, etc, in the future.
- @param op Operation to perform if either first is found,
- or no first is declared (in which case, all nodes
- in the subtree).
- @see _res_op res_exec
- */
-static int
-_res_op_by_level(resource_node_t **tree, resource_t *first, void *ret,
- int op)
-{
- resource_node_t *node = *tree;
- resource_t *res = node->rn_resource;
- resource_rule_t *rule = res->r_rule;
- int rv = 0;
-
- if (!rule->rr_childtypes)
- return _res_op(&node->rn_child, first, NULL, ret, op);
-
- if (op == RS_START || op == RS_STATUS) {
- rv |= _do_child_levels(tree, first, ret, op);
- if (rv & SFL_FAILURE)
- return rv;
-
- /* Start default level after specified ones */
- rv |= _do_child_default_level(tree, first, ret, op);
-
- } /* stop */ else {
-
- rv |= _do_child_default_level(tree, first, ret, op);
- rv |= _do_child_levels(tree, first, ret, op);
- }
-
- return rv;
-}
-
-
-static void
-mark_nodes(resource_node_t *node, int state, int setflags, int clearflags)
-{
- int x;
- resource_node_t *child;
-
- list_for(&node->rn_child, child, x) {
- mark_nodes(child, state, setflags,
- clearflags);
- }
-
- if (state >= RES_STOPPED)
- node->rn_state = state;
- node->rn_flags |= (setflags);
- node->rn_flags &= ~(clearflags);
-}
-
-
-/**
- Do a status on a resource node. This takes into account the last time the
- status operation was run and selects the highest possible resource depth
- to use given the elapsed time.
- */
-static int
-do_status(resource_node_t *node)
-{
- int x = 0, idx = -1;
- int has_recover = 0;
- time_t delta = 0, now = 0;
-
- if (node->rn_state == RES_DISABLED)
- return 0;
-
- now = time(NULL);
-
- for (; node->rn_actions[x].ra_name; x++) {
- if (!has_recover &&
- !strcmp(node->rn_actions[x].ra_name, "recover")) {
- has_recover = 1;
- continue;
- }
-
- if (strcmp(node->rn_actions[x].ra_name, "status"))
- continue;
-
- delta = now - node->rn_actions[x].ra_last;
-
- /*
- printf("%s:%s %s level %d interval = %d elapsed = %d\n",
- node->rn_resource->r_rule->rr_type,
- node->rn_resource->r_attrs->ra_value,
- node->rn_actions[x].ra_name, node->rn_actions[x].ra_depth,
- (int)node->rn_actions[x].ra_interval, (int)delta);
- */
-
- /* Ok, it's a 'status' action. See if enough time has
- elapsed for a given type of status action */
- if (delta < node->rn_actions[x].ra_interval ||
- !node->rn_actions[x].ra_interval)
- continue;
-
- if (idx == -1 ||
- node->rn_actions[x].ra_depth > node->rn_actions[idx].ra_depth)
- idx = x;
- }
-
- /* No check levels ready at the moment. */
- /* Cap status check children if configured to do so */
- if (idx == -1 || rg_inc_children() < 0) {
- if (node->rn_checked)
- return node->rn_last_status;
- return 0;
- }
-
- x = res_exec(node, RS_STATUS, NULL, node->rn_actions[idx].ra_depth);
- rg_dec_children();
-
- /* Record status check result *after* the status check has
- * completed. */
- node->rn_actions[idx].ra_last = time(NULL);
-
- /* If we have not exceeded our failure count threshold, then fudge
- * the status check this round */
- if (x && node->rn_failure_counter) {
- if (!restart_threshold_exceeded(node->rn_failure_counter)) {
- x = 0;
- restart_add(node->rn_failure_counter);
- }
- }
-
- node->rn_last_status = x;
- node->rn_last_depth = node->rn_actions[idx].ra_depth;
- node->rn_checked = 1;
-
- if (x == 0)
- return 0;
-
- if (!has_recover)
- return x;
-
- /* Strange/failed status. Try to recover inline. */
- if ((x = res_exec(node, RS_RECOVER, NULL, 0)) == 0) {
- node->rn_last_status = x;
- return 0;
- }
-
- return x;
-}
-
-
-static void
-set_time(const char *action, int depth, resource_node_t *node)
-{
- time_t now;
- int x = 0;
-
- time(&now);
-
- for (; node->rn_actions[x].ra_name; x++) {
-
- if (strcmp(node->rn_actions[x].ra_name, action) ||
- node->rn_actions[x].ra_depth != depth)
- continue;
-
- node->rn_actions[x].ra_last = now;
- break;
- }
-}
-
-
-time_t
-get_time(char *action, int depth, resource_node_t *node)
-{
- int x = 0;
-
- for (; node->rn_actions[x].ra_name; x++) {
-
- if (strcmp(node->rn_actions[x].ra_name, action) ||
- node->rn_actions[x].ra_depth != depth)
- continue;
-
- return node->rn_actions[x].ra_last;
- }
-
- return (time_t)0;
-}
-
-
-static void
-clear_checks(resource_node_t *node)
-{
- time_t now;
- int x = 0;
-
- now = get_time((char *)"start", 0, node);
-
- for (; node->rn_actions[x].ra_name; x++) {
-
- if (strcmp(node->rn_actions[x].ra_name, "monitor") &&
- strcmp(node->rn_actions[x].ra_name, "status"))
- continue;
-
- node->rn_actions[x].ra_last = now;
- }
-
- restart_clear(node->rn_failure_counter);
-
- node->rn_checked = 0;
- node->rn_last_status = 0;
- node->rn_last_depth = 0;
-}
-
-
-/**
- Nasty codependent function. Perform an operation by type for all siblings
- at some point in the tree. This allows indirectly-dependent resources
- (such as IP addresses and user scripts) to have ordering without requiring
- a direct dependency.
-
- @param tree Resource tree to search/perform operations on
- @param first Resource we're looking to perform the operation on,
- if one exists.
- @param type Type to look for.
- @param ret Unused, but will be used to store status information
- such as resources consumed, etc, in the future.
- @param realop Operation to perform if either first is found,
- or no first is declared (in which case, all nodes
- in the subtree).
- @see _res_op_by_level res_exec
- */
-static inline int
-_res_op_internal(resource_node_t __attribute__ ((unused)) **tree,
- resource_t *first,
- char *type, void *__attribute__((unused))ret, int realop,
- resource_node_t *node)
-{
- int rv = 0, me, op, rte = 0;
-
- /* Restore default operation. */
- op = realop;
-
- /* If we're starting by type, do that funky thing. */
- if (type && strlen(type) &&
- strcmp(node->rn_resource->r_rule->rr_type, type))
- return 0;
-
- /* If the resource is found, all nodes in the subtree must
- have the operation performed as well. */
- me = !first || (node->rn_resource == first);
-
- //printf("begin %s: %s %s [0x%x]\n", res_ops[op],
- //node->rn_resource->r_rule->rr_type,
- //primary_attr_value(node->rn_resource),
- //node->rn_flags);
-
- if (me) {
- /*
- If we've been marked as a node which
- needs to be started or stopped, clear
- that flag and start/stop this resource
- and all resource babies.
-
- Otherwise, don't do anything; look for
- children with RF_NEEDSTART and
- RF_NEEDSTOP flags.
-
- CONDSTART and CONDSTOP are no-ops if
- the appropriate flag is not set.
- */
- if ((op == RS_CONVALESCE) &&
- node->rn_state == RES_DISABLED) {
- printf("Node %s:%s - Convalesce\n",
- node->rn_resource->r_rule->rr_type,
- primary_attr_value(node->rn_resource));
- mark_nodes(node, RES_STOPPED, RF_NEEDSTART, 0);
- op = RS_START;
- }
-
- if ((op == RS_CONDSTART) &&
- (node->rn_flags & RF_NEEDSTART)) {
- printf("Node %s:%s - CONDSTART\n",
- node->rn_resource->r_rule->rr_type,
- primary_attr_value(node->rn_resource));
- op = RS_START;
- }
-
- if ((op == RS_CONDSTOP) &&
- (node->rn_flags & RF_NEEDSTOP)) {
- printf("Node %s:%s - CONDSTOP\n",
- node->rn_resource->r_rule->rr_type,
- primary_attr_value(node->rn_resource));
- op = RS_STOP;
- }
- }
-
- /* Start starts before children */
- if (me && (op == RS_START)) {
-
- if (node->rn_state == RES_DISABLED)
- /* Nothing to do - children are also disabled */
- return 0;
-
- if ((realop == RS_START || realop == RS_CONVALESCE) &&
- node->rn_flags & RF_INDEPENDENT)
- restart_clear(node->rn_restart_counter);
-
- pthread_mutex_lock(&node->rn_resource->r_mutex);
-
- if (node->rn_flags & RF_RECONFIG &&
- realop == RS_CONDSTART) {
- rv = res_exec(node, RS_RECONFIG, NULL, 0);
- op = realop; /* reset to CONDSTART */
- } else {
- rv = res_exec(node, op, NULL, 0);
- }
- node->rn_flags &= ~(RF_NEEDSTART | RF_RECONFIG);
- if (rv != 0) {
- if (rv != OCF_RA_NOT_INSTALLED)
- node->rn_state = RES_FAILED;
- pthread_mutex_unlock(&node->rn_resource->r_mutex);
- return SFL_FAILURE;
- }
-
- set_time("start", 0, node);
- clear_checks(node);
-
- if (node->rn_state != RES_STARTED) {
- ++node->rn_resource->r_incarnations;
- node->rn_state = RES_STARTED;
- }
- pthread_mutex_unlock(&node->rn_resource->r_mutex);
-
- } else if (me && (op == RS_STATUS || op == RS_STATUS_INQUIRY)) {
-
- /* Special quick-check for status inquiry */
- if (op == RS_STATUS_INQUIRY) {
- if (res_exec(node, RS_STATUS, NULL, 0) != 0)
- return SFL_FAILURE;
-
- /* XXX: A migratable service (the only place this
- * check can be used) cannot have child dependencies
- * anyway, so this is a short-circuit. */
- return 0;
- }
-
- /* Check status before children*/
- rv = do_status(node);
- if (rv != 0) {
- /*
- If this node's status has failed, all of its
- dependent children are failed, whether or not this
- node is independent or not.
- */
-
- /* If we're an independent subtree, return a flag
- stating that this section is recoverable apart
- from siblings in the resource tree. All child
- resources of this node must be restarted,
- but siblings of this node are not affected. */
- if (node->rn_flags & RF_INDEPENDENT) {
-
- rte = restart_threshold_exceeded(node->rn_restart_counter);
- if ((node->rn_flags & RF_NON_CRITICAL) && (rte ||
- !node->rn_restart_counter)) {
- mark_nodes(node, RES_FAILED,
- RF_NEEDSTOP | RF_QUIESCE, 0);
- restart_clear(node->rn_restart_counter);
- return SFL_RECOVERABLE|SFL_PARTIAL;
- } else if (!rte ||
- !node->rn_restart_counter) {
- restart_add(node->rn_restart_counter);
- mark_nodes(node, RES_FAILED,
- RF_NEEDSTART | RF_NEEDSTOP, 0);
- return SFL_RECOVERABLE;
- } else {
- restart_clear(node->rn_restart_counter);
- return SFL_FAILURE;
- }
- }
-
- return SFL_FAILURE;
- }
-
- if (node->rn_state != RES_DISABLED) {
- node->rn_state = RES_STARTED;
- node->rn_flags &= ~RF_NEEDSTOP;
- }
- }
-
- if (node->rn_child) {
- rv |= _res_op_by_level(&node, me?NULL:first, ret, op);
-
- /* If one or more child resources are failed and at least one
- of them is not an independent subtree then let's check if
- if we are an independent subtree. If so, mark ourself
- and all our children as failed and return a flag stating
- that this section is recoverable apart from siblings in
- the resource tree. */
- if (op == RS_STATUS && (rv & SFL_FAILURE) &&
- (node->rn_flags & RF_INDEPENDENT)) {
-
- rte = restart_threshold_exceeded(node->rn_restart_counter);
-
- rv = SFL_RECOVERABLE;
- if ((node->rn_flags & RF_NON_CRITICAL) && (rte ||
- !node->rn_restart_counter)) {
- /* if non-critical, just stop */
- mark_nodes(node, RES_FAILED, RF_NEEDSTOP | RF_QUIESCE, 0);
-
- rv |= SFL_PARTIAL;
- } else if (!rte || !node->rn_restart_counter) {
- restart_add(node->rn_restart_counter);
- mark_nodes(node, RES_FAILED,
- RF_NEEDSTOP | RF_NEEDSTART, 0);
- } else {
- restart_clear(node->rn_restart_counter);
- rv = SFL_FAILURE;
- }
- }
- }
-
- /* Stop should occur after children have stopped */
- if (me && (op == RS_STOP)) {
-
- /* Decrease incarnations so the script knows how many *other*
- incarnations there are. */
- pthread_mutex_lock(&node->rn_resource->r_mutex);
-
- node->rn_flags &= ~RF_NEEDSTOP;
- rv |= res_exec(node, op, NULL, 0);
-
- if (node->rn_flags & (RF_NEEDSTART|RF_QUIESCE) &&
- node->rn_flags & RF_INDEPENDENT &&
- node->rn_flags & RF_NON_CRITICAL) {
- /* Non-critical resources = do not fail
- * service if the resource fails to stop
- */
- if (rv & SFL_FAILURE) {
- logt_print(LOG_WARNING, "Failed to stop subtree %s:%s"
- " during non-critical recovery "
- "operation\n",
- node->rn_resource->r_rule->rr_type,
- primary_attr_value(
- node->rn_resource));
- rv = SFL_PARTIAL;
- node->rn_flags |= RF_QUIESCE;
- }
- }
-
- if (rv == 0 && (node->rn_state == RES_STARTED ||
- node->rn_state == RES_FAILED)) {
- assert(node->rn_resource->r_incarnations >= 0);
- if (node->rn_resource->r_incarnations > 0)
- --node->rn_resource->r_incarnations;
- } else if (rv != 0 && (node->rn_state != RES_DISABLED &&
- !(node->rn_flags & RF_QUIESCE))) {
- node->rn_state = RES_FAILED;
- pthread_mutex_unlock(&node->rn_resource->r_mutex);
- return SFL_FAILURE;
- }
- pthread_mutex_unlock(&node->rn_resource->r_mutex);
-
- if (node->rn_flags & RF_QUIESCE) {
- mark_nodes(node, RES_DISABLED, 0,
- RF_NEEDSTART|RF_QUIESCE);
- } else {
- node->rn_state = RES_STOPPED;
- }
- }
-
- //printf("end %s: %s %s\n", res_ops[op],
- //node->rn_resource->r_rule->rr_type,
- //primary_attr_value(node->rn_resource));
-
- return rv;
-}
-
-
-/**
- Nasty codependent function. Perform an operation by type for all siblings
- at some point in the tree. This allows indirectly-dependent resources
- (such as IP addresses and user scripts) to have ordering without requiring
- a direct dependency.
-
- @param tree Resource tree to search/perform operations on
- @param first Resource we're looking to perform the operation on,
- if one exists.
- @param type Type to look for.
- @param ret Unused, but will be used to store status information
- such as resources consumed, etc, in the future.
- @param realop Operation to perform if either first is found,
- or no first is declared (in which case, all nodes
- in the subtree).
- @see _res_op_by_level res_exec
- */
-int
-_res_op(resource_node_t **tree, resource_t *first,
- char *type, void * __attribute__((unused))ret, int realop)
-{
- resource_node_t *node;
- int count = 0, rv = 0;
-
- if (realop == RS_STOP) {
- list_for_rev(tree, node, count) {
- rv |= _res_op_internal(tree, first, type, ret, realop,
- node);
- }
- } else {
- list_for(tree, node, count) {
- rv |= _res_op_internal(tree, first, type, ret, realop,
- node);
-
- /* If we hit a problem during a 'status' op in an
- independent subtree, rv will have the
- SFL_RECOVERABLE bit set, but not SFL_FAILURE.
- If we ever hit SFL_FAILURE during a status
- operation, we're *DONE* - even if the subtree
- is flagged w/ indy-subtree */
-
- if (rv & SFL_FAILURE)
- return rv;
- }
- }
-
- return rv;
-}
-
-/**
- Start all occurrences of a resource in a tree
-
- @param tree Tree to search for our resource.
- @param res Resource to start/stop
- @param ret Unused
- */
-int
-res_start(resource_node_t **tree, resource_t *res, void *ret)
-{
- return _res_op(tree, res, NULL, ret, RS_START);
-}
-
-
-/**
- Start all occurrences of a resource in a tree
-
- @param tree Tree to search for our resource.
- @param res Resource to start/stop
- @param ret Unused
- */
-int
-res_condstop(resource_node_t **tree, resource_t *res, void *ret)
-{
- return _res_op(tree, res, NULL, ret, RS_CONDSTOP);
-}
-
-
-/**
- Repair/fix/convalesce all occurrences of a resource in a tree
-
- @param tree Tree to search for our resource.
- @param res Resource to start/stop
- @param ret Unused
- */
-int
-res_convalesce(resource_node_t **tree, resource_t *res, void *ret)
-{
- return _res_op(tree, res, NULL, ret, RS_CONVALESCE);
-}
-
-
-/**
- Start all occurrences of a resource in a tree
-
- @param tree Tree to search for our resource.
- @param res Resource to start/stop
- @param ret Unused
- */
-int
-res_condstart(resource_node_t **tree, resource_t *res, void *ret)
-{
- return _res_op(tree, res, NULL, ret, RS_CONDSTART);
-}
-
-
-/**
- Stop all occurrences of a resource in a tree
-
- @param tree Tree to search for our resource.
- @param res Resource to start/stop
- @param ret Unused
- */
-int
-res_stop(resource_node_t **tree, resource_t *res, void *ret)
-{
- return _res_op(tree, res, NULL, ret, RS_STOP);
-}
-
-
-/**
- Check status of all occurrences of a resource in a tree
-
- @param tree Tree to search for our resource.
- @param res Resource to start/stop
- @param ret Unused
- */
-int
-res_status(resource_node_t **tree, resource_t *res, void *ret)
-{
- return _res_op(tree, res, NULL, ret, RS_STATUS);
-}
-
-
-/**
- Check status of all occurrences of a resource in a tree
-
- @param tree Tree to search for our resource.
- @param res Resource to start/stop
- @param ret Unused
- */
-int
-res_status_inquiry(resource_node_t **tree, resource_t *res, void *ret)
-{
- return _res_op(tree, res, NULL, ret, RS_STATUS_INQUIRY);
-}
-
-
-/**
- Find the delta of two resource lists and flag the resources which need
- to be restarted/stopped/started.
- */
-int
-resource_delta(resource_t **leftres, resource_t **rightres)
-{
- resource_t *lc, *rc;
- int ret;
-
- list_do(leftres, lc) {
- rc = find_resource_by_ref(rightres, lc->r_rule->rr_type,
- primary_attr_value(lc));
-
- /* No restart. It's gone. */
- if (!rc) {
- lc->r_flags |= RF_NEEDSTOP;
- continue;
- }
-
- /* Ok, see if the resource is the same */
- ret = rescmp(lc, rc);
- if (ret == 0) {
- rc->r_flags |= RF_COMMON;
- continue;
- }
-
- if (ret == 2) {
- /* return of 2 from rescmp means
- the two resources differ only
- by reconfigurable bits */
- /* Do nothing on condstop phase;
- do a "reconfig" instead of
- "start" on conststart phase */
- rc->r_flags |= RF_COMMON;
- rc->r_flags |= RF_NEEDSTART;
- rc->r_flags |= RF_RECONFIG;
- continue;
- }
-
- rc->r_flags |= RF_COMMON;
-
- /* Resource has changed. Flag it. */
- lc->r_flags |= RF_NEEDSTOP;
- rc->r_flags |= RF_NEEDSTART;
-
- } while (!list_done(leftres, lc));
-
- /* Ok, if we weren't existing, flag as a needstart. */
- list_do(rightres, rc) {
- if (rc->r_flags & RF_COMMON)
- rc->r_flags &= ~RF_COMMON;
- else
- rc->r_flags |= RF_NEEDSTART;
- } while (!list_done(rightres, rc));
- /* Easy part is done. */
- return 0;
-}
-
-
-/**
- Part 2 of online mods: Tree delta. Ow. It hurts. It hurts.
- We need to do this because resources can be moved from one RG
- to another with nothing changing (not even refcnt!).
- */
-int
-resource_tree_delta(resource_node_t **ltree, resource_node_t **rtree)
-{
- resource_node_t *ln, *rn;
- int rc;
-
- list_do(ltree, ln) {
- /*
- Ok. Run down the left tree looking for obsolete resources.
- (e.g. those that need to be stopped)
-
- If it's obsolete, continue. All children will need to be
- restarted too, so we don't need to compare the children
- of this node.
- */
- if (ln->rn_resource->r_flags & RF_NEEDSTOP) {
- ln->rn_flags |= RF_NEEDSTOP;
- continue;
- }
-
- /*
- Ok. This particular node wasn't flagged.
- */
- list_do(rtree, rn) {
-
- rc = rescmp(ln->rn_resource, rn->rn_resource);
-
- /* Wildly different resource? */
- if (rc <= -1)
- continue;
-
- /*
- If it needs to be started (e.g. it's been altered
- or is new), then we don't really care about its
- children.
- */
-
- if (rn->rn_resource->r_flags & RF_NEEDSTART) {
- rn->rn_flags |= RF_NEEDSTART;
- if ((rn->rn_resource->r_flags & RF_RECONFIG) == 0)
- continue;
- }
-
- if (rc == 0 || rc == 2) {
- if (rc == 2)
- rn->rn_flags |= RF_NEEDSTART | RF_RECONFIG;
-
- if (rc == 0)
- rn->rn_state = ln->rn_state;
-
- /* Ok, same resource. Recurse. */
- ln->rn_flags |= RF_COMMON;
- rn->rn_flags |= RF_COMMON;
- resource_tree_delta(&ln->rn_child,
- &rn->rn_child);
- }
-
- } while (!list_done(rtree, rn));
-
- if (ln->rn_flags & RF_COMMON)
- ln->rn_flags &= ~RF_COMMON;
- else
- ln->rn_flags |= RF_NEEDSTOP;
-
- } while (!list_done(ltree, ln));
-
- /*
- See if we need to start anything. Stuff which wasn't flagged
- as COMMON needs to be started.
-
- As always, if we have to start a node, everything below it
- must also be started.
- */
- list_do(rtree, rn) {
- if (rn->rn_flags & RF_COMMON)
- rn->rn_flags &= ~RF_COMMON;
- else
- rn->rn_flags |= RF_NEEDSTART;
- } while (!list_done(rtree, rn));
-
- return 0;
-}
diff --git a/rgmanager/src/daemons/rg_event.c b/rgmanager/src/daemons/rg_event.c
deleted file mode 100644
index 028741f..0000000
--- a/rgmanager/src/daemons/rg_event.c
+++ /dev/null
@@ -1,568 +0,0 @@
-#include <time.h>
-#include <list.h>
-#include <restart_counter.h>
-#include <reslist.h>
-#include <resgroup.h>
-#include <rg_locks.h>
-#include <gettid.h>
-#include <assert.h>
-#include <libcman.h>
-#include <ccs.h>
-#include <logging.h>
-#include <lock.h>
-#include <event.h>
-#include <stdint.h>
-#include <vf.h>
-#include <members.h>
-#include <groups.h>
-
-
-/**
- * resource group event queue.
- */
-static event_t *event_queue = NULL;
-#ifdef WRAP_LOCKS
-static pthread_mutex_t event_queue_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-static pthread_mutex_t mi_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-#else
-static pthread_mutex_t event_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t mi_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
-static pthread_cond_t event_queue_cond = PTHREAD_COND_INITIALIZER;
-static pthread_t event_thread = 0;
-static int transition_throttling = 5;
-static int central_events = 0;
-
-extern int running;
-extern int shutdown_pending;
-extern int need_reconfigure;
-static int _master = 0;
-static struct dlm_lksb _master_lock;
-static int _xid = 0;
-static event_master_t *mi = NULL;
-
-void flag_shutdown(int sig);
-void flag_reconfigure(int sig);
-
-event_table_t *master_event_table = NULL;
-
-
-void
-set_transition_throttling(int nsecs)
-{
- if (nsecs < 1)
- nsecs = 1;
- transition_throttling = nsecs;
-}
-
-
-int
-get_transition_throttling(void)
-{
- return transition_throttling;
-}
-
-
-void
-set_central_events(int flag)
-{
- central_events = flag;
-}
-
-
-int
-central_events_enabled(void)
-{
- return central_events;
-}
-
-
-static void
-hard_exit(void)
-{
- rg_lockall(L_SYS);
- rg_doall(RG_INIT, 1, "Emergency stop of %s");
- //vf_shutdown();
- exit(1);
-}
-
-
-void
-flag_reconfigure(int __attribute__ ((unused)) sig)
-{
- need_reconfigure++;
-}
-
-
-/**
- Called to handle the transition of a cluster member from up->down or
- down->up. This handles initializing services (in the local node-up case),
- exiting due to loss of quorum (local node-down), and service fail-over
- (remote node down). This is the distributed node event processor;
- for the local-only node event processor, see slang_event.c
-
- @param nodeID ID of the member which has come up/gone down.
- @param nodeStatus New state of the member in question.
- @see eval_groups
- */
-void
-node_event(int local, int nodeID, int nodeStatus,
- int __attribute__((unused)) clean)
-{
- if (!running)
- return;
-
- if (local) {
-
- /* Local Node Event */
- if (nodeStatus == 0) {
- logt_print(LOG_ERR, "Exiting uncleanly\n");
- hard_exit();
- }
-
- if (!rg_initialized()) {
- if (init_resource_groups(0, 0) != 0) {
- logt_print(LOG_ERR,
- "#36: Cannot initialize services\n");
- hard_exit();
- }
- }
-
- if (shutdown_pending) {
- logt_print(LOG_NOTICE, "Processing delayed exit signal\n");
- running = 0;
- return;
- }
- setup_signal(SIGINT, flag_shutdown);
- setup_signal(SIGTERM, flag_shutdown);
- setup_signal(SIGHUP, flag_reconfigure);
-
- eval_groups(1, nodeID, 1);
- return;
- }
-
- /*
- * Nothing to do for events from other nodes if we are not ready.
- */
- if (!rg_initialized()) {
- logt_print(LOG_DEBUG, "Services not initialized.\n");
- return;
- }
-
- eval_groups(0, nodeID, nodeStatus);
-}
-
-
-/**
- Query CCS to see whether a node has fencing enabled or not in
- the configuration. This does not check to see if it's in the
- fence domain.
- */
-int
-node_has_fencing(int nodeid)
-{
- int ccs_desc;
- char *val = NULL;
- char buf[1024];
- int ret = 1;
-
- ccs_desc = ccs_connect();
- if (ccs_desc < 0) {
- logt_print(LOG_ERR, "Unable to connect to ccsd; cannot handle"
- " node event!\n");
- /* Assume node has fencing */
- return 1;
- }
-
- snprintf(buf, sizeof(buf),
- "/cluster/clusternodes/clusternode[@nodeid=\"%d\"]"
- "/fence/method/device/@name", nodeid);
-
- if (ccs_get(ccs_desc, buf, &val) != 0)
- ret = 0;
- if (val)
- free(val);
- ccs_disconnect(ccs_desc);
- return ret;
-}
-
-
-/* Since the API for groupd is private, use group_tool to find
- out if we've joined the fence domain */
-int
-fence_domain_joined(void)
-{
- int rv;
-
- rv = system("fence_tool ls &> /dev/null");
- if (rv == 0)
- return 1;
- return 0;
-}
-
-
-/**
- Callback from view-formation when a commit occurs for the Transition-
- Master key.
- */
-int32_t
-master_event_callback(char __attribute__ ((unused)) *key,
- uint64_t __attribute__ ((unused)) viewno,
- void *data, uint32_t datalen)
-{
- event_master_t *m;
-
- m = data;
- if (datalen != (uint32_t)sizeof(*m)) {
- logt_print(LOG_ERR, "%s: wrong size\n", __FUNCTION__);
- return 1;
- }
-
- swab_event_master_t(m);
- if (m->m_magic != EVENT_MASTER_MAGIC) {
- logt_print(LOG_ERR, "%s: wrong size\n", __FUNCTION__);
- return 1;
- }
-
- if (m->m_nodeid == (uint32_t)my_id())
- logt_print(LOG_DEBUG, "Master Commit: I am master\n");
- else
- logt_print(LOG_DEBUG, "Master Commit: %d is master\n", m->m_nodeid);
-
- pthread_mutex_lock(&mi_mutex);
- if (mi)
- free(mi);
- mi = m;
- pthread_mutex_unlock(&mi_mutex);
-
- return 0;
-}
-
-
-/**
- Read the Transition-Master key from vf if it exists. If it doesn't,
- attempt to become the transition-master.
- */
-static int
-find_master(void)
-{
- event_master_t *masterinfo = NULL;
- void *data = NULL;
- uint32_t sz;
- cluster_member_list_t *m;
- uint64_t vn;
- int master_id = -1;
-
- m = member_list();
- if (vf_read(m, "Transition-Master", &vn,
- (void **)(&data), &sz) != VFR_OK) {
- logt_print(LOG_ERR, "Unable to discover master"
- " status\n");
- masterinfo = NULL;
- } else {
- masterinfo = (event_master_t *)data;
- }
-
- free_member_list(m);
-
- if (masterinfo && (sz >= sizeof(*masterinfo))) {
- swab_event_master_t(masterinfo);
- if (masterinfo->m_magic == EVENT_MASTER_MAGIC) {
- logt_print(LOG_DEBUG, "Master Locate: %d is master\n",
- masterinfo->m_nodeid);
- pthread_mutex_lock(&mi_mutex);
- if (mi)
- free(mi);
- mi = masterinfo;
- pthread_mutex_unlock(&mi_mutex);
- master_id = masterinfo->m_nodeid;
- } else {
- free(data);
- }
- } else {
- free(data);
- masterinfo = NULL;
- }
-
- return master_id;
-}
-
-
-/**
- Return a copy of the cached event_master_t structure to the
- caller.
- */
-int
-event_master_info_cached(event_master_t *mi_out)
-{
- if (!central_events || !mi_out) {
- errno = -EINVAL;
- return -1;
- }
-
- pthread_mutex_lock(&mi_mutex);
- if (!mi) {
- pthread_mutex_unlock(&mi_mutex);
- errno = -ENOENT;
- return -1;
- }
-
- memcpy(mi_out, mi, sizeof(*mi));
- pthread_mutex_unlock(&mi_mutex);
- return 0;
-}
-
-
-/**
- Return the node ID of the master. If none exists, become
- the master and return our own node ID.
- */
-int
-event_master(void)
-{
- cluster_member_list_t *m = NULL;
- event_master_t masterinfo;
- int master_id = -1;
-
- /* We hold this forever. */
- if (_master)
- return my_id();
-
- m = member_list();
- pthread_mutex_lock(&mi_mutex);
-
- if (mi) {
- master_id = mi->m_nodeid;
- pthread_mutex_unlock(&mi_mutex);
- if (memb_online(m, master_id)) {
- //logt_print(LOG_DEBUG, "%d is master\n", mi->m_nodeid);
- goto out;
- }
- } else
- pthread_mutex_unlock(&mi_mutex);
-
- memset(&_master_lock, 0, sizeof(_master_lock));
- if (clu_lock(LKM_EXMODE, &_master_lock, LKF_NOQUEUE,
- "Transition-Master") < 0) {
- /* not us, find out who is master */
- master_id = find_master();
- goto out;
- }
-
- if (_master_lock.sb_status != 0) {
- master_id = -1;
- goto out;
- }
-
- _master = 1;
-
- memset(&masterinfo, 0, sizeof(masterinfo));
- masterinfo.m_magic = EVENT_MASTER_MAGIC;
- masterinfo.m_nodeid = my_id();
- masterinfo.m_master_time = (uint64_t)time(NULL);
- swab_event_master_t(&masterinfo);
-
- if (vf_write(m, VFF_IGN_CONN_ERRORS | VFF_RETRY,
- "Transition-Master", &masterinfo,
- sizeof(masterinfo)) < 0) {
- logt_print(LOG_ERR, "Unable to advertise master"
- " status to all nodes\n");
- }
-
- master_id = my_id();
-out:
- free_member_list(m);
- return master_id;
-}
-
-
-/**
- Event handling function. This only stays around as long as
- events are on the queue.
- */
-static void *
-_event_thread_f(void __attribute__ ((unused)) *arg)
-{
- event_t *ev;
- struct timeval now;
- struct timespec expire;
- int count = 0;
-
- while (1) {
- pthread_mutex_lock(&event_queue_mutex);
- ev = event_queue;
- if (!ev && !central_events) {
- gettimeofday(&now, NULL);
- expire.tv_sec = now.tv_sec + transition_throttling;
- expire.tv_nsec = now.tv_usec * 1000;
- pthread_cond_timedwait(&event_queue_cond,
- &event_queue_mutex,
- &expire);
- ev = event_queue;
- }
- if (!ev)
- break; /* We're outta here */
-
- list_remove(&event_queue, ev);
-
- ++count;
- pthread_mutex_unlock(&event_queue_mutex);
-
- if (ev->ev_type == EVENT_CONFIG) {
- /*
- logt_print(LOG_NOTICE, "Config Event: %d -> %d\n",
- ev->ev.config.cfg_oldversion,
- ev->ev.config.cfg_version);
- */
- init_resource_groups(1, 0);
- free(ev);
- continue;
- }
-
- if (central_events) {
- /* If the master node died or there isn't
- one yet, take the master lock. */
- if (event_master() == my_id()) {
- slang_process_event(master_event_table,
- ev);
- }
- free(ev);
- continue;
- /* ALL OF THE CODE BELOW IS DISABLED
- when using central_events */
- }
-
- if (ev->ev_type == EVENT_RG) {
- /*
- logt_print(LOG_NOTICE, "RG Event: %s %s %d\n",
- ev->ev.group.rg_name,
- rg_state_str(ev->ev.group.rg_state),
- ev->ev.group.rg_owner);
- */
- group_event(ev->ev.group.rg_name,
- ev->ev.group.rg_state,
- ev->ev.group.rg_owner);
- } else if (ev->ev_type == EVENT_NODE) {
- /*
- logt_print(LOG_NOTICE, "Node Event: %s %d %s %s\n",
- ev->ev.node.ne_local?"Local":"Remote",
- ev->ev.node.ne_nodeid,
- ev->ev.node.ne_state?"UP":"DOWN",
- ev->ev.node.ne_clean?"Clean":"Dirty")
- */
-
- node_event(ev->ev.node.ne_local,
- ev->ev.node.ne_nodeid,
- ev->ev.node.ne_state,
- ev->ev.node.ne_clean);
- }
-
- free(ev);
- }
-
- if (!central_events || _master) {
- logt_print(LOG_DEBUG, "%d events processed\n", count);
- }
- /* Mutex held */
- event_thread = 0;
- pthread_mutex_unlock(&event_queue_mutex);
- pthread_exit(NULL);
-}
-
-
-static void
-insert_event(event_t *ev)
-{
- pthread_attr_t attrs;
- pthread_mutex_lock (&event_queue_mutex);
- ev->ev_transaction = ++_xid;
- list_insert(&event_queue, ev);
- if (event_thread == 0) {
- pthread_attr_init(&attrs);
- pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED);
- pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
- pthread_attr_setstacksize(&attrs, 262144);
-
- pthread_create(&event_thread, &attrs, _event_thread_f, NULL);
- pthread_attr_destroy(&attrs);
- } else {
- pthread_cond_broadcast(&event_queue_cond);
- }
- pthread_mutex_unlock (&event_queue_mutex);
-}
-
-
-static event_t *
-new_event(void)
-{
- event_t *ev;
-
- while (1) {
- ev = malloc(sizeof(*ev));
- if (ev) {
- break;
- }
- sleep(1);
- }
- memset(ev,0,sizeof(*ev));
- ev->ev_type = EVENT_NONE;
-
- return ev;
-}
-
-
-void
-rg_event_q(char *name, uint32_t state, int owner, int last)
-{
- event_t *ev = new_event();
-
- ev->ev_type = EVENT_RG;
-
- strncpy(ev->ev.group.rg_name, name, 128);
- ev->ev.group.rg_state = state;
- ev->ev.group.rg_owner = owner;
- ev->ev.group.rg_last_owner = last;
-
- insert_event(ev);
-}
-
-
-void
-node_event_q(int local, int nodeID, int state, int clean)
-{
- event_t *ev = new_event();
-
- ev->ev_type = EVENT_NODE;
- ev->ev.node.ne_state = state;
- ev->ev.node.ne_local = local;
- ev->ev.node.ne_nodeid = nodeID;
- ev->ev.node.ne_clean = clean;
- insert_event(ev);
-}
-
-
-void
-config_event_q(void)
-{
- event_t *ev = new_event();
-
- ev->ev_type = EVENT_CONFIG;
- insert_event(ev);
-}
-
-void
-user_event_q(char *svc, int request,
- int arg1, int arg2, int target, msgctx_t *ctx)
-{
- event_t *ev = new_event();
-
- ev->ev_type = EVENT_USER;
- strncpy(ev->ev.user.u_name, svc, sizeof(ev->ev.user.u_name));
- ev->ev.user.u_request = request;
- ev->ev.user.u_arg1 = arg1;
- ev->ev.user.u_arg2 = arg2;
- ev->ev.user.u_target = target;
- ev->ev.user.u_ctx = ctx;
- insert_event(ev);
-}
-
diff --git a/rgmanager/src/daemons/rg_forward.c b/rgmanager/src/daemons/rg_forward.c
deleted file mode 100644
index 48649b8..0000000
--- a/rgmanager/src/daemons/rg_forward.c
+++ /dev/null
@@ -1,279 +0,0 @@
-//#define DEBUG
-#include <rg_types.h>
-#include <resgroup.h>
-#include <rg_queue.h>
-#include <platform.h>
-#include <msgsimple.h>
-#include <logging.h>
-#include <message.h>
-#include <members.h>
-
-
-struct fw_message {
- msgctx_t *ctx;
- SmMessageSt msg;
- int nodeid;
-};
-
-
-static void
-build_message(SmMessageSt *msgp, int action, char *svcName, int target,
- int arg1, int arg2)
-{
- msgp->sm_hdr.gh_magic = GENERIC_HDR_MAGIC;
- msgp->sm_hdr.gh_command = RG_ACTION_REQUEST;
- msgp->sm_hdr.gh_arg1 = arg1;
- msgp->sm_hdr.gh_arg2 = arg2;
- msgp->sm_hdr.gh_length = sizeof(*msgp);
- msgp->sm_data.d_action = action;
- strncpy(msgp->sm_data.d_svcName, svcName,
- sizeof(msgp->sm_data.d_svcName));
- msgp->sm_data.d_svcOwner = target;
- msgp->sm_data.d_ret = 0;
-
- swab_SmMessageSt(msgp);
-}
-
-
-static void *
-forwarding_thread(void *arg)
-{
- rg_state_t rgs;
- request_t *req = (request_t *)arg;
- struct dlm_lksb lockp;
- msgctx_t *ctx = NULL;
- cluster_member_list_t *m = NULL;
- SmMessageSt msg;
- int response_code = RG_EAGAIN, ret;
- int new_owner = 0, retries = 0;
-
- if (rg_lock(req->rr_group, &lockp) != 0) {
- logt_print(LOG_WARNING, "FW: Forwarding failed; lock unavailable for %s\n",
- req->rr_group);
- goto out_fail;
- }
- if (get_rg_state(req->rr_group, &rgs) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_WARNING, "FW: Forwarding failed; state unavailable for %s\n",
- req->rr_group);
- goto out_fail;
- }
- rg_unlock(&lockp);
-
- if (rgs.rs_owner == 0)
- rgs.rs_owner = req->rr_target;
- if (rgs.rs_owner == 0) {
- logt_print(LOG_ERR, "FW: Attempt to forward to invalid node ID\n");
- goto out_fail;
- }
- if (rgs.rs_owner == (uint32_t)my_id()) {
- logt_print(LOG_WARNING, "BUG! Attempt to forward to myself!\n");
- goto out_fail;
- }
-
- logt_print(LOG_DEBUG, "FW: Forwarding %s request to %d\n",
- rg_req_str(req->rr_request), rgs.rs_owner);
-
- ctx = msg_new_ctx();
- if (ctx == NULL) {
- logt_print(LOG_DEBUG, "FW: Failed to allocate socket context: %s\n",
- strerror(errno));
- goto out_fail;
- }
-
- /* Construct message */
- build_message(&msg, req->rr_request, req->rr_group, req->rr_target,
- req->rr_arg0, req->rr_arg1);
-
- if (msg_open(MSG_CLUSTER, rgs.rs_owner, RG_PORT, ctx, 2 * cluster_timeout) < 0) {
- logt_print(LOG_DEBUG, "FW: Failed to open channel to %d CTX: %p\n",
- rgs.rs_owner, ctx);
- goto out_fail;
- }
- if (msg_send(ctx, &msg, sizeof(msg)) < (int)sizeof(msg)) {
- logt_print(LOG_DEBUG, "FW: Failed to send message to %d CTX: %p\n",
- rgs.rs_owner, ctx);
- goto out_fail;
- }
-
- /*
- * Ok, we're forwarding a message to another node. Keep tabs on
- * the node to make sure it doesn't die. Basically, wake up every
- * now and again to make sure it's still online. If it isn't, send
- * a response back to the caller.
- */
- do {
- ret = msg_receive(ctx, &msg, sizeof(msg), 10);
- if (ret < (int)sizeof(msg)) {
- if (ret < 0 && errno == ETIMEDOUT) {
- m = member_list();
- if (!memb_online(m, rgs.rs_owner)) {
- response_code = RG_ENODE;
- goto out_fail;
- }
- free_member_list(m);
- m = NULL;
- continue;
- }
-
- if (ret == 0)
- continue;
- }
- break;
- } while(++retries < 60); /* old 600 second rule */
-
- swab_SmMessageSt(&msg);
-
- response_code = msg.sm_data.d_ret;
- new_owner = msg.sm_data.d_svcOwner;
-
-out_fail:
- send_response(response_code, new_owner, req);
- msg_close(req->rr_resp_ctx);
- msg_free_ctx(req->rr_resp_ctx);
-
- if (ctx) {
- msg_close(ctx);
- msg_free_ctx(ctx);
- }
- if (m)
- free_member_list(m);
-
- rq_free(req);
- pthread_exit(NULL);
-}
-
-
-void
-forward_request(request_t *req)
-{
- pthread_t newthread;
- pthread_attr_t attrs;
-
- pthread_attr_init(&attrs);
- pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED);
- pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
- pthread_attr_setstacksize(&attrs, 262144);
-
- pthread_create(&newthread, &attrs, forwarding_thread, req);
- pthread_attr_destroy(&attrs);
-}
-
-
-
-static void *
-forwarding_thread_v2(void *arg)
-{
- msgctx_t *ctx = NULL, *resp_ctx = NULL;
- cluster_member_list_t *m = NULL;
- SmMessageSt *msgp = NULL, msg;
- int response_code = RG_EAGAIN, ret, target = -1;
- int retries = 0;
- struct fw_message *fwmsg = (struct fw_message *)arg;
-
- msgp = &fwmsg->msg;
- resp_ctx = fwmsg->ctx;
- target = fwmsg->nodeid;
-
- logt_print(LOG_DEBUG, "FW: Forwarding SM request to %d\n",
- target);
-
- ctx = msg_new_ctx();
- if (ctx == NULL) {
- logt_print(LOG_DEBUG, "FW: Failed to allocate socket context: %s\n",
- strerror(errno));
- goto out_fail;
- }
- if (msg_open(MSG_CLUSTER, target, RG_PORT, ctx, 2 * cluster_timeout) < 0) {
- logt_print(LOG_DEBUG, "FW: Failed to open channel to %d CTX: %p\n",
- target, ctx);
- goto out_fail;
- }
-
- /* swap + send */
- swab_SmMessageSt(msgp);
- if (msg_send(ctx, msgp, sizeof(*msgp)) < (int)sizeof(*msgp)) {
- logt_print(LOG_DEBUG, "FW: Failed to send message to %d CTX: %p\n",
- target, ctx);
- goto out_fail;
- }
-
-
- /*
- * Ok, we're forwarding a message to another node. Keep tabs on
- * the node to make sure it doesn't die. Basically, wake up every
- * now and again to make sure it's still online. If it isn't, send
- * a response back to the caller.
- */
- do {
- ret = msg_receive(ctx, &msg, sizeof(msg), 10);
- if (ret < (int)sizeof(msg)) {
- if (ret < 0 && errno == ETIMEDOUT) {
- m = member_list();
- if (!memb_online(m, target)) {
- response_code = RG_ENODE;
- goto out_fail;
- }
- free_member_list(m);
- m = NULL;
- continue;
- }
-
- if (ret == 0)
- continue;
- }
- break;
- } while(++retries < 60); /* old 600 second rule */
-
- swab_SmMessageSt(&msg);
-
- response_code = msg.sm_data.d_ret;
- target = msg.sm_data.d_svcOwner;
-
-out_fail:
- free(fwmsg);
-
- if (resp_ctx) {
- send_ret(resp_ctx, msgp->sm_data.d_svcName, response_code,
- msgp->sm_data.d_action, target);
- msg_close(resp_ctx);
- msg_free_ctx(resp_ctx);
- }
-
- if (ctx) {
- msg_close(ctx);
- msg_free_ctx(ctx);
- }
- if (m)
- free_member_list(m);
-
- pthread_exit(NULL);
-}
-
-
-void
-forward_message(msgctx_t *ctx, void *msgp, int nodeid)
-{
- pthread_t newthread;
- pthread_attr_t attrs;
- struct fw_message *fwmsg;
-
- fwmsg = malloc(sizeof(struct fw_message));
- if (!fwmsg) {
- msg_close(ctx);
- msg_free_ctx(ctx);
- return;
- }
-
- memcpy(&fwmsg->msg, msgp, sizeof(fwmsg->msg));
- fwmsg->ctx = ctx;
- fwmsg->nodeid = nodeid;
-
- pthread_attr_init(&attrs);
- pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED);
- pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
- pthread_attr_setstacksize(&attrs, 262144);
-
- pthread_create(&newthread, &attrs, forwarding_thread_v2, fwmsg);
- pthread_attr_destroy(&attrs);
-}
diff --git a/rgmanager/src/daemons/rg_locks.c b/rgmanager/src/daemons/rg_locks.c
deleted file mode 100644
index 14bd241..0000000
--- a/rgmanager/src/daemons/rg_locks.c
+++ /dev/null
@@ -1,368 +0,0 @@
-#include <pthread.h>
-#include <stdio.h>
-#include <assert.h>
-#include <rg_locks.h>
-#ifdef NO_CCS
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/xpath.h>
-#include <string.h>
-#include <time.h>
-#include <list.h>
-#include <restart_counter.h>
-#include <reslist.h>
-#else
-#include <ccs.h>
-#endif
-
-static int __rg_quorate = 0;
-static int __rg_lock = 0;
-static int __rg_threadcnt = 0;
-static int __rg_initialized = 0;
-
-static int _rg_statuscnt = 0;
-static int _rg_statusmax = 5; /* XXX */
-
-static int _rg_childcnt = 0;
-static int _rg_childmax = 0; /* XXX */
-
-static pthread_cond_t unlock_cond = PTHREAD_COND_INITIALIZER;
-static pthread_cond_t zero_cond = PTHREAD_COND_INITIALIZER;
-static pthread_cond_t init_cond = PTHREAD_COND_INITIALIZER;
-
-#ifdef WRAP_LOCKS
-static pthread_mutex_t locks_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-static pthread_mutex_t _ccs_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-#else
-static pthread_mutex_t locks_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t _ccs_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
-
-#ifdef NO_CCS
-static xmlDocPtr ccs_doc = NULL;
-static const char *conffile = DEFAULT_CONFIG_DIR "/" DEFAULT_CONFIG_FILE;
-#endif
-
-int
-rg_initialized(void)
-{
- int ret;
- pthread_mutex_lock(&locks_mutex);
- ret = __rg_initialized;
- pthread_mutex_unlock(&locks_mutex);
- return ret;
-}
-
-
-int
-rg_set_initialized(int flag)
-{
- if (!flag)
- flag = ~0;
-
- pthread_mutex_lock(&locks_mutex);
- __rg_initialized |= flag;
- pthread_cond_broadcast(&init_cond);
- pthread_mutex_unlock(&locks_mutex);
- return 0;
-}
-
-
-int
-rg_clear_initialized(int flag)
-{
- if (!flag)
- flag = ~0;
- pthread_mutex_lock(&locks_mutex);
- __rg_initialized &= ~flag;
- pthread_mutex_unlock(&locks_mutex);
- return 0;
-}
-
-
-int
-rg_wait_initialized(int flag)
-{
- pthread_mutex_lock(&locks_mutex);
- if (flag) {
- while ((__rg_initialized & flag) != flag)
- pthread_cond_wait(&init_cond, &locks_mutex);
- } else {
- while (!__rg_initialized)
- pthread_cond_wait(&init_cond, &locks_mutex);
- }
- pthread_mutex_unlock(&locks_mutex);
- return 0;
-}
-
-
-/**
- not sure if ccs is thread safe or not
- */
-int
-ccs_lock(void)
-#ifndef NO_CCS
-{
- int ret;
- pthread_mutex_lock(&_ccs_mutex);
- ret = ccs_connect();
- if (ret < 0) {
- pthread_mutex_unlock(&_ccs_mutex);
- return -1;
- }
- return ret;
-}
-#else /* No ccs support */
-{
- pthread_mutex_lock(&_ccs_mutex);
- ccs_doc = xmlParseFile(conffile);
- if (!ccs_doc)
- return -1;
- return 0;
-}
-#endif
-
-
-int
-#ifndef NO_CCS
-ccs_unlock(int fd)
-{
- int ret;
-
- ret = ccs_disconnect(fd);
- pthread_mutex_unlock(&_ccs_mutex);
- if (ret < 0) {
- return -1;
- }
- return 0;
-}
-#else
-ccs_unlock(int __attribute__((unused)) fd)
-{
- xmlFreeDoc(ccs_doc);
- ccs_doc = NULL;
- pthread_mutex_unlock(&_ccs_mutex);
- return 0;
-}
-
-
-void
-conf_setconfig(const char *path)
-{
- pthread_mutex_lock(&_ccs_mutex);
- conffile = path;
- pthread_mutex_unlock(&_ccs_mutex);
-}
-
-
-int
-conf_get(const char *path, char **value)
-{
- char *foo;
- xmlXPathContextPtr ctx;
-
- ctx = xmlXPathNewContext(ccs_doc);
- foo = xpath_get_one(ccs_doc, ctx, path);
- xmlXPathFreeContext(ctx);
-
- if (foo) {
- *value = foo;
- return 0;
- }
- return 1;
-}
-#endif
-
-
-int
-rg_lockall(int flag)
-{
- pthread_mutex_lock(&locks_mutex);
- if (!__rg_lock)
- __rg_lock |= flag;
- pthread_mutex_unlock(&locks_mutex);
- return 0;
-}
-
-
-int
-rg_locked(void)
-{
- int ret;
- pthread_mutex_lock(&locks_mutex);
- ret = __rg_lock;
- pthread_mutex_unlock(&locks_mutex);
- return ret;
-}
-
-
-int
-rg_unlockall(int flag)
-{
- pthread_mutex_lock(&locks_mutex);
- if (__rg_lock)
- __rg_lock &= ~flag;
- pthread_cond_broadcast(&unlock_cond);
- pthread_mutex_unlock(&locks_mutex);
- return 0;
-}
-
-
-int
-rg_set_quorate(void)
-{
- pthread_mutex_lock(&locks_mutex);
- if (!__rg_quorate)
- __rg_quorate = 1;
- pthread_mutex_unlock(&locks_mutex);
- return 0;
-}
-
-
-int
-rg_set_inquorate(void)
-{
- pthread_mutex_lock(&locks_mutex);
- if (__rg_quorate)
- __rg_quorate = 0;
- pthread_mutex_unlock(&locks_mutex);
- return 0;
-}
-
-
-int
-rg_quorate(void)
-{
- int ret;
- pthread_mutex_lock(&locks_mutex);
- ret = __rg_quorate;
- pthread_mutex_unlock(&locks_mutex);
- return ret;
-}
-
-
-int
-rg_inc_threads(void)
-{
- pthread_mutex_lock(&locks_mutex);
- ++__rg_threadcnt;
-#ifdef DEBUG
- printf("%s: %d threads active\n", __FILE__, __rg_threadcnt);
-#endif
- pthread_mutex_unlock(&locks_mutex);
- return 0;
-}
-
-
-int
-rg_dec_threads(void)
-{
- pthread_mutex_lock(&locks_mutex);
- --__rg_threadcnt;
- if (__rg_threadcnt <= 0) {
- __rg_threadcnt = 0;
- pthread_cond_broadcast(&zero_cond);
- }
-#ifdef DEBUG
- printf("%s: %d threads active\n", __FILE__, __rg_threadcnt);
-#endif
- pthread_mutex_unlock(&locks_mutex);
- return 0;
-}
-
-
-int
-rg_set_statusmax(int max)
-{
- int old;
-
- if (max <= 3)
- max = 3;
-
- pthread_mutex_lock(&locks_mutex);
- old = _rg_statusmax;
- _rg_statusmax = max;
- pthread_mutex_unlock(&locks_mutex);
- return old;
-}
-
-
-int
-rg_inc_status(void)
-{
- pthread_mutex_lock(&locks_mutex);
- if (_rg_statuscnt >= _rg_statusmax) {
- pthread_mutex_unlock(&locks_mutex);
- return -1;
- }
- ++_rg_statuscnt;
- pthread_mutex_unlock(&locks_mutex);
- return 0;
-}
-
-
-int
-rg_dec_status(void)
-{
- pthread_mutex_lock(&locks_mutex);
- --_rg_statuscnt;
- if (_rg_statuscnt < 0)
- _rg_statuscnt = 0;
- pthread_mutex_unlock(&locks_mutex);
- return 0;
-}
-
-
-int
-rg_set_childmax(int max)
-{
- int old;
-
- if (max <= 1)
- max = 1;
-
- pthread_mutex_lock(&locks_mutex);
- old = _rg_childmax;
- _rg_childmax = max;
- pthread_mutex_unlock(&locks_mutex);
- return old;
-}
-
-
-int
-rg_inc_children(void)
-{
- pthread_mutex_lock(&locks_mutex);
- if (_rg_childmax && (_rg_childcnt >= _rg_childmax)) {
- pthread_mutex_unlock(&locks_mutex);
- return -1;
- }
- ++_rg_childcnt;
- pthread_mutex_unlock(&locks_mutex);
- return 0;
-}
-
-
-int
-rg_dec_children(void)
-{
- pthread_mutex_lock(&locks_mutex);
- --_rg_childcnt;
- if (_rg_childcnt < 0) {
- assert(0);
- _rg_childcnt = 0;
- }
- pthread_mutex_unlock(&locks_mutex);
- return 0;
-}
-
-
-int
-rg_wait_threads(void)
-{
- pthread_mutex_lock(&locks_mutex);
- if (__rg_threadcnt)
- pthread_cond_wait(&zero_cond, &locks_mutex);
- pthread_mutex_unlock(&locks_mutex);
- return 0;
-}
diff --git a/rgmanager/src/daemons/rg_queue.c b/rgmanager/src/daemons/rg_queue.c
deleted file mode 100644
index 758f5e4..0000000
--- a/rgmanager/src/daemons/rg_queue.c
+++ /dev/null
@@ -1,71 +0,0 @@
-#include <time.h>
-#include <restart_counter.h>
-#include <list.h>
-#include <reslist.h>
-#include <rg_queue.h>
-#include <malloc.h>
-#include <string.h>
-#include <stdio.h>
-#include <message.h>
-
-
-int
-_rq_queue_request(request_t **queue, char *name, uint32_t request,
- uint32_t err, uint32_t oldreq, msgctx_t *ctx, time_t when,
- uint32_t target, uint32_t arg0, uint32_t arg1,
- const char *file, int line)
-{
- request_t *req;
-
- req = malloc(sizeof(*req));
- if (!req)
- return -1;
-
- if (name && strlen(name)) {
- strncpy(req->rr_group, name, sizeof(req->rr_group));
- }
- req->rr_request = request;
- req->rr_errorcode = err;
- req->rr_orig_request = oldreq;
- req->rr_resp_ctx = ctx;
- req->rr_target = target;
- req->rr_when = when;
- req->rr_arg0 = arg0;
- req->rr_arg1 = arg1;
- req->rr_file = file;
- req->rr_line = line;
-
- list_insert(queue, req);
-
- return 0;
-}
-
-
-void
-rq_free(request_t *dead)
-{
- if (!dead)
- return;
-
- free(dead);
-}
-
-
-request_t *
-rq_next_request(request_t **queue)
-{
- request_t *req = NULL;
-
- req = *queue;
- if (req)
- list_remove(queue, req);
-
- return req;
-}
-
-
-int
-rq_queue_empty(request_t **queue)
-{
- return !(*queue);
-}
diff --git a/rgmanager/src/daemons/rg_state.c b/rgmanager/src/daemons/rg_state.c
deleted file mode 100644
index 765c3eb..0000000
--- a/rgmanager/src/daemons/rg_state.c
+++ /dev/null
@@ -1,2366 +0,0 @@
-#include <assert.h>
-#include <platform.h>
-#include <list.h>
-#include <time.h>
-#include <restart_counter.h>
-#include <reslist.h>
-#include <message.h>
-#include <members.h>
-#ifdef OPENAIS
-#include <ds.h>
-#else
-#include <vf.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <resgroup.h>
-#include <logging.h>
-#include <lock.h>
-#include <rg_locks.h>
-#include <ccs.h>
-#include <rg_queue.h>
-#include <msgsimple.h>
-#include <res-ocf.h>
-#include <event.h>
-#include <groups.h>
-#include <fo_domain.h>
-
-/* XXX - copied :( */
-#define cn_svccount cn_address.cna_address[0] /* Theses are uint8_t size */
-#define cn_svcexcl cn_address.cna_address[1]
-
-static int msvc_check_cluster(const char *svcName);
-static int handle_started_status(const char *svcName, int ret, rg_state_t *svcStatus);
-static int handle_migrate_status(const char *svcName, int ret, rg_state_t *svcStatus);
-
-static int _svc_stop_finish(const char *svcName, int failed, uint32_t newstate);
-
-void
-broadcast_event(const char *svcName, uint32_t state, int owner, int last)
-{
- SmMessageSt msgp;
- msgctx_t everyone;
-
- msgp.sm_hdr.gh_magic = GENERIC_HDR_MAGIC;
- msgp.sm_hdr.gh_command = RG_EVENT;
- msgp.sm_hdr.gh_length = sizeof(msgp);
- msgp.sm_hdr.gh_arg1 = owner;
- msgp.sm_hdr.gh_arg2 = last;
- msgp.sm_data.d_action = state;
- strncpy(msgp.sm_data.d_svcName, svcName,
- sizeof(msgp.sm_data.d_svcName));
- msgp.sm_data.d_svcOwner = owner;
- msgp.sm_data.d_ret = 0;
-
- swab_SmMessageSt(&msgp);
-
- if (msg_open(MSG_CLUSTER, 0, RG_PORT, &everyone, 0) < 0)
- return;
-
- msg_send(&everyone, &msgp, sizeof(msgp));
- msg_close(&everyone);
-}
-
-
-int
-svc_report_failure(const char *svcName)
-{
- struct dlm_lksb lockp;
- rg_state_t svcStatus;
- char *nodeName;
- cluster_member_list_t *membership;
-
- if (rg_lock(svcName, &lockp) == -1) {
- logt_print(LOG_ERR, "#41: Couldn't obtain lock for RG %s: %s\n",
- svcName, strerror(errno));
- return -1;
- }
-
- if (get_rg_state(svcName, &svcStatus) != 0) {
- logt_print(LOG_ERR, "#42: Couldn't obtain status for RG %s\n",
- svcName);
- rg_unlock(&lockp);
- return -1;
- }
- rg_unlock(&lockp);
-
- membership = member_list();
- nodeName = memb_id_to_name(membership, svcStatus.rs_last_owner);
- if (nodeName) {
- logt_print(LOG_ALERT, "#2: Service %s returned failure "
- "code. Last Owner: %s\n", svcName, nodeName);
- } else {
- logt_print(LOG_ALERT, "#3: Service %s returned failure "
- "code. Last Owner: %d\n",
- svcName, (int)svcStatus.rs_last_owner);
- }
-
- free_member_list(membership);
-
- logt_print(LOG_ALERT,
- "#4: Administrator intervention required.\n");
-
- return 0;
-}
-
-
-int
-#ifdef DEBUG
-_rg_lock(const char *name, struct dlm_lksb *p)
-#else
-rg_lock(const char *name, struct dlm_lksb *p)
-#endif
-{
- char res[256];
-
- snprintf(res, sizeof(res), "rg=\"%s\"", name);
- return clu_lock(LKM_EXMODE, p, 0, res);
-}
-
-
-#ifdef DEBUG
-int
-_rg_lock_dbg(const char *name, struct dlm_lksb *p, const char *file, int line)
-{
- dbg_printf("rg_lock(%s) @ %s:%d\n", name, file, line);
- return _rg_lock(name, p);
-}
-#endif
-
-
-int
-#ifdef DEBUG
-_rg_unlock(struct dlm_lksb *p)
-#else
-rg_unlock(struct dlm_lksb *p)
-#endif
-{
- return clu_unlock(p);
-}
-
-
-#ifdef DEBUG
-int
-_rg_unlock_dbg(struct dlm_lksb *p, const char *file, int line)
-{
- dbg_printf("rg_unlock() @ %s:%d\n", file, line);
- return _rg_unlock(p);
-}
-#endif
-
-
-void
-send_ret(msgctx_t *ctx, char *name, int ret, int orig_request, int new_owner)
-{
- SmMessageSt msg, *msgp = &msg;
- if (!ctx)
- return;
-
- msgp->sm_hdr.gh_magic = GENERIC_HDR_MAGIC;
- msgp->sm_hdr.gh_command = RG_ACTION_REQUEST;
- msgp->sm_hdr.gh_length = sizeof(*msgp);
- msgp->sm_data.d_action = orig_request;
- strncpy(msgp->sm_data.d_svcName, name,
- sizeof(msgp->sm_data.d_svcName));
- if (!new_owner)
- new_owner = my_id();
- msgp->sm_data.d_svcOwner = new_owner; /* XXX Broken */
- msgp->sm_data.d_ret = ret;
-
- swab_SmMessageSt(msgp);
- msg_send(ctx, msgp, sizeof(*msgp));
-}
-
-
-void
-send_response(int ret, int nodeid, request_t *req)
-{
- SmMessageSt msg, *msgp = &msg;
-
- if (req->rr_resp_ctx == NULL)
- return;
-
- msgp->sm_hdr.gh_magic = GENERIC_HDR_MAGIC;
- msgp->sm_hdr.gh_command = RG_ACTION_REQUEST;
- msgp->sm_hdr.gh_length = sizeof(*msgp);
- msgp->sm_data.d_action = req->rr_orig_request;
- strncpy(msgp->sm_data.d_svcName, req->rr_group,
- sizeof(msgp->sm_data.d_svcName));
- if (!nodeid)
- msgp->sm_data.d_svcOwner = my_id();
- else
- msgp->sm_data.d_svcOwner = nodeid;
- msgp->sm_data.d_ret = ret;
-
- swab_SmMessageSt(msgp);
- msg_send(req->rr_resp_ctx, msgp, sizeof(*msgp));
-}
-
-
-int
-set_rg_state(const char *name, rg_state_t *svcblk)
-{
- char res[256];
- rg_state_t svcblk_store;
-#ifndef OPENAIS
- cluster_member_list_t *membership;
- int ret, tries = 0;
-#endif
-
- if (name) {
- strncpy(svcblk->rs_name, name, sizeof(svcblk->rs_name)-1);
- svcblk->rs_name[sizeof(svcblk->rs_name)-1] = '\0';
- }
-
- snprintf(res, sizeof(res), "rg=\"%s\"", name);
-
- memcpy(&svcblk_store, svcblk, sizeof(svcblk_store));
- swab_rg_state_t(&svcblk_store);
-
-#ifdef OPENAIS
- if (ds_write(res, &svcblk_store, sizeof(svcblk_store)) < 0)
- return -1;
- return 0;
-#else
- do {
- /* Retry up to 3 times just in case members transition
- while we're trying to commit something */
- membership = member_list();
- ret = vf_write(membership, VFF_IGN_CONN_ERRORS, res,
- &svcblk_store,
- sizeof(svcblk_store));
- free_member_list(membership);
- } while (ret == VFR_TIMEOUT && ++tries < 3);
-
- return (ret==VFR_OK?0:-1);
-#endif
-}
-
-
-static int
-init_rg(const char *name, rg_state_t *svcblk)
-{
- svcblk->rs_owner = 0;
- svcblk->rs_last_owner = 0;
- svcblk->rs_state = RG_STATE_STOPPED;
- svcblk->rs_flags = 0;
- svcblk->rs_restarts = 0;
- svcblk->rs_transition = 0;
- strncpy(svcblk->rs_name, name, sizeof(svcblk->rs_name));
-
- return set_rg_state(name, svcblk);
-}
-
-
-int
-get_rg_state(const char *name, rg_state_t *svcblk)
-{
- char res[256];
- int ret;
-#ifdef OPENAIS
- char data[DS_MIN_SIZE];
- int datalen;
-#else
- uint64_t viewno;
- void *data = NULL;
- cluster_member_list_t *membership;
- uint32_t datalen = 0;
-#endif
-
- if (!name) {
- errno = EINVAL;
- return -1;
- }
-
- strncpy(svcblk->rs_name, name, sizeof(svcblk->rs_name)-1);
- svcblk->rs_name[sizeof(svcblk->rs_name)-1];
-
- snprintf(res, sizeof(res),"rg=\"%s\"", svcblk->rs_name);
-
-#ifdef OPENAIS
- while((datalen = ds_read(res, data, sizeof(data))) < 0) {
- if (errno == ENOENT) {
- ds_key_init(res, DS_MIN_SIZE, 10);
- } else {
- perror("ds_read");
- return -1;
- }
- }
-
- if (datalen <= 0) {
-
- ret = init_rg(name, svcblk);
- if (ret < 0) {
- printf("Couldn't initialize rg %s!\n", name);
- return RG_EFAIL;
- }
-
- datalen = ds_read(res, &data, sizeof(data));
- if (ret < 0) {
- printf("Couldn't reread rg %s! (%d)\n", name, ret);
- return RG_EFAIL;
- }
- }
-
- memcpy(svcblk, data, sizeof(*svcblk));
- swab_rg_state_t(svcblk);
-
- return 0;
-#else
- membership = member_list();
-
- ret = vf_read(membership, res, &viewno, &data, &datalen);
-
- if (ret != VFR_OK || datalen == 0) {
- if (data)
- free(data);
- data = NULL;
-
- ret = init_rg(name, svcblk);
- if (ret != VFR_OK) {
- free_member_list(membership);
- printf("Couldn't initialize rg %s!\n", name);
- return RG_EFAIL;
- }
-
- ret = vf_read(membership, res, &viewno, &data, &datalen);
- if (ret != VFR_OK) {
- if (data)
- free(data);
- data = NULL;
- free_member_list(membership);
- printf("Couldn't reread rg %s! (%d)\n", name, ret);
- return RG_EFAIL;
- }
- }
-
- if (datalen < sizeof(*svcblk)) {
- printf("Size mismatch; expected %d got %d\n",
- (int)sizeof(*svcblk), datalen);
- if (data)
- free(data);
- free_member_list(membership);
- return RG_EFAIL;
- }
-
- /* Copy out the data. */
- memcpy(svcblk, data, sizeof(*svcblk));
- swab_rg_state_t(svcblk);
- free(data);
- free_member_list(membership);
-
- return 0;
-#endif
-}
-
-
-int
-get_rg_state_local(const char *name, rg_state_t *svcblk)
-{
- char res[256];
- int ret;
-#ifdef OPENAIS
- char data[1024];
- int datalen;
-#else
- void *data = NULL;
- uint64_t viewno = 0;
- uint32_t datalen;
-#endif
-
- if (!name) {
- errno = EINVAL;
- return -1;
- }
- strncpy(svcblk->rs_name, name, sizeof(svcblk->rs_name)-1);
- svcblk->rs_name[sizeof(svcblk->rs_name)-1] = '\0';
-
- snprintf(res, sizeof(res),"rg=\"%s\"", svcblk->rs_name);
-
-#ifdef OPENAIS
- ret = ds_read(res, data, sizeof(data));
- if (ret <= 0) {
-#else
- ret = vf_read_local(res, &viewno, &data, &datalen);
-
- if (ret != VFR_OK || datalen == 0 ||
- datalen != sizeof(*svcblk)) {
- if (data)
- free(data);
-#endif
- svcblk->rs_owner = 0;
- svcblk->rs_last_owner = 0;
- svcblk->rs_state = RG_STATE_UNINITIALIZED;
- svcblk->rs_flags = 0;
- svcblk->rs_restarts = 0;
- svcblk->rs_transition = 0;
- strncpy(svcblk->rs_name, name, sizeof(svcblk->rs_name));
-
- return RG_EFAIL;
- }
-
- /* Copy out the data. */
- memcpy(svcblk, data, sizeof(*svcblk));
- swab_rg_state_t(svcblk);
-#ifndef OPENAIS
- free(data);
-#endif
- return 0;
-}
-
-
-/**
- * Advise service manager as to whether or not to stop a service, given
- * that we already know it's legal to run the service.
- *
- * @param svcStatus Current service status.
- * @param svcName Service name
- * @param req Specify request to perform
- * @return 0 = DO NOT stop service, return RG_EFAIL
- * 1 = STOP service - return whatever it returns.
- * 2 = DO NOT stop service, return 0 (success)
- * 3 = DO NOT stop service, return RG_EFORWARD
- * 4 = DO NOT stop service, return RG_EAGAIN
- * 5 = DO NOT stop service, return RG_EFROZEN
- * 6 = DO NOT stop service, mark stopped and return
- * RG_SUCCESS (0)
- */
-static int
-svc_advise_stop(rg_state_t *svcStatus, const char *svcName, int req)
-{
- cluster_member_list_t *membership = member_list();
- int ret = 0;
-
- if (svcStatus->rs_flags & RG_FLAG_FROZEN) {
- logt_print(LOG_DEBUG, "Service %s frozen.\n", svcName);
- free_member_list(membership);
- return 5;
- }
-
- switch(svcStatus->rs_state) {
- case RG_STATE_FAILED:
- if (req == RG_DISABLE)
- ret = 1; /* Failed services can be disabled */
- else
- ret = 0; /* Failed services may not be stopped */
- break;
-
- case RG_STATE_STOPPING:
- case RG_STATE_STARTED:
- case RG_STATE_CHECK:
- case RG_STATE_STARTING:
- case RG_STATE_RECOVER:
- case RG_STATE_MIGRATE:
- if ((svcStatus->rs_owner != (uint32_t)my_id()) &&
- memb_online(membership, svcStatus->rs_owner)) {
- /*
- Service is running and the owner is online.
- Forward the request if it's a user request
- (e.g. disable).
- */
- if (req == RG_STOP) {
- /*
- It's running somewhere, but not here,
- and it's not a user request. Toss
- it out the window.
- */
- ret = 2;
- break;
- }
-
- /* Disable or relocate request here. */
- logt_print(LOG_DEBUG, "Forwarding req. to %s.\n",
- memb_id_to_name(membership,
- svcStatus->rs_owner));
- ret = 3;
- break;
- }
-
- if (svcStatus->rs_owner == 0 ||
- (svcStatus->rs_owner == (uint32_t)my_id())) {
- /*
- Service is marked as running locally or on
- 0 (e.g. no member). Safe
- to do a full stop.
- */
- ret = 1;
- break;
- }
-
- /*
- Service is marked as running but node is down.
- Doesn't make much sense to stop it - but we need
- to mark it stopped
- */
- ret = 6;
- break;
-
- case RG_STATE_ERROR:
- /* Don't stop; return failure. */
- if (req == RG_DISABLE) {
- ret = 1;
- break;
- }
- logt_print(LOG_DEBUG,
- "Not stopping %s: service is failed\n",
- svcName);
- ret = 0;
- break;
-
- case RG_STATE_STOPPED:
- /* Allow disabling of stopped services */
- if (req == RG_DISABLE)
- ret = 1;
- else
- ret = 2; /* if it's already stopped, do nothing */
- break;
-
- case RG_STATE_DISABLED:
- case RG_STATE_UNINITIALIZED:
- if (req == RG_DISABLE) {
- logt_print(LOG_NOTICE,
- "Disabling disabled service %s\n",
- svcName);
- ret = 1;
- break;
- }
-
- ret = 2;
- logt_print(LOG_DEBUG, "Not stopping disabled service %s\n",
- svcName);
- break;
-
- default:
- logt_print(LOG_ERR,
- "#42: Cannot stop RG %s: Invalid State %d\n",
- svcName, svcStatus->rs_state);
- break;
- }
-
- free_member_list(membership);
- return ret;
-}
-
-
-/**
- * Advise service manager as to whether or not to start a service, given
- * that we already know it's legal to run the service.
- *
- * @param svcStatus Current service status.
- * @param svcName Service name
- * @param flags Specify whether or not it's legal to start a
- * disabled service, etc.
- * @return 0 = DO NOT start service, return RG_EFAIL
- * 1 = START service - return whatever it returns.
- * 2 = DO NOT start service, return 0
- * 3 = DO NOT start service, return RG_EAGAIN
- * 4 = DO NOT start service, return RG_ERUN
- * 5 = DO NOT start service, return RG_EFROZEN
- */
-static int
-svc_advise_start(rg_state_t *svcStatus, const char *svcName, int req)
-{
- cluster_member_list_t *membership = member_list();
- int ret = 0;
-
- if (svcStatus->rs_flags & RG_FLAG_FROZEN) {
- logt_print(LOG_DEBUG, "Service %s frozen.\n", svcName);
- free_member_list(membership);
- return 5;
- }
-
- switch(svcStatus->rs_state) {
- case RG_STATE_FAILED:
- logt_print(LOG_ERR,
- "#43: Service %s has failed; can not start.\n",
- svcName);
- break;
-
- case RG_STATE_MIGRATE:
- ret = 4;
- break;
-
- case RG_STATE_STOPPING:
- case RG_STATE_STARTED:
- case RG_STATE_CHECK:
- case RG_STATE_STARTING:
- if (svcStatus->rs_owner == (uint32_t)my_id()) {
- /*
- * Service is already running locally
- logt_print(LOG_DEBUG,
- "RG %s is already running locally\n", svcName);
- */
- ret = 4;
- break;
- }
-
- if (svcStatus->rs_owner != (uint32_t)my_id() &&
- memb_online(membership, svcStatus->rs_owner)) {
- /*
- * Service is running and the owner is online!
- logt_print(LOG_DEBUG, "RG %s is running on member %s.\n",
- svcName,
- memb_id_to_name(membership,svcStatus->rs_owner));
- */
- ret = 4;
- break;
- }
-
- /* We are allowed to do something with the service. Make
- sure we're not locked */
- if (svcStatus->rs_owner == 0) {
- if (rg_locked()) {
- ret = 3;
- break;
- }
-
- logt_print(LOG_NOTICE,
- "Starting stopped service%s\n",
- svcName);
- ret = 1;
- break;
- }
-
- if (rg_locked()) {
- logt_print(LOG_WARNING, "Not initiating failover of %s: "
- "Resource groups locked!\n", svcName);
- ret = 3;
- break;
- }
-
- /*
- * Service is running but owner is down -> RG_EFAILOVER
- */
- svcStatus->rs_last_owner = svcStatus->rs_owner;
- logt_print(LOG_NOTICE,
- "Taking over service %s from down member %s\n",
- svcName, memb_id_to_name(membership,
- svcStatus->rs_owner));
- ret = 1;
- break;
-
- case RG_STATE_RECOVER:
- /*
- * Starting failed service...
- */
- if (req == RG_START_RECOVER || central_events_enabled()) {
- logt_print(LOG_NOTICE,
- "Recovering failed service %s\n",
- svcName);
- /* Start! */
- ret = 1;
- break;
- }
-
- /* Don't start, but return success. */
- logt_print(LOG_DEBUG,
- "Not starting %s: recovery state\n",
- svcName);
- ret = 2;
- break;
-
- case RG_STATE_STOPPED:
- case RG_STATE_ERROR:
- /* Don't actually enable if the RG is locked! */
- if (rg_locked()) {
- ret = 3;
- break;
- }
-
- logt_print(LOG_NOTICE, "Starting stopped service %s\n",
- svcName);
- ret = 1;
- break;
-
- case RG_STATE_DISABLED:
- case RG_STATE_UNINITIALIZED:
- if (req == RG_ENABLE || req == RG_START_REMOTE) {
- /* Don't actually enable if the RG is locked! */
- if (rg_locked()) {
- ret = 3;
- break;
- }
-
- logt_print(LOG_NOTICE,
- "Starting disabled service %s\n",
- svcName);
- ret = 1;
- break;
- }
- if (req == RG_START_RECOVER) {
- ret = 1;
- break;
- }
-
- logt_print(LOG_DEBUG, "Not starting disabled RG %s\n",
- svcName);
- break;
-
- default:
- logt_print(LOG_ERR,
- "#44: Cannot start RG %s: Invalid State %d\n",
- svcName, svcStatus->rs_state);
- break;
- }
-
- free_member_list(membership);
- return ret;
-}
-
-
-/**
- * Start a cluster service.
- *
- * @param svcName Service ID to start.
- * @param flags Service-operation specific flags to take into account.
- * @see svc_advise_start
- * @return FAIL, 0
- */
-int
-svc_start(const char *svcName, int req)
-{
- struct dlm_lksb lockp;
- int ret;
- rg_state_t svcStatus;
-
- if (rg_lock(svcName, &lockp) < 0) {
- logt_print(LOG_ERR, "#45: Unable to obtain cluster lock: %s\n",
- strerror(errno));
- return RG_EFAIL;
- }
-
- if (get_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#46: Failed getting status for RG %s\n",
- svcName);
- return RG_EFAIL;
- }
-
- /* LOCK HELD */
- switch (svc_advise_start(&svcStatus, svcName, req)) {
- case 0: /* Don't start service, return RG_EFAIL */
- rg_unlock(&lockp);
- return RG_EFAIL;
- case 2: /* Don't start service, return 0 */
- rg_unlock(&lockp);
- return 0;
- case 3:
- rg_unlock(&lockp);
- return RG_EAGAIN;
- case 4:
- rg_unlock(&lockp);
- return RG_ERUN;
- case 5:
- rg_unlock(&lockp);
- return RG_EFROZEN;
- default:
- break;
- }
-
- /* LOCK HELD if we get here */
-
- svcStatus.rs_owner = my_id();
- svcStatus.rs_transition = (uint64_t)time(NULL);
-
- if (svcStatus.rs_state == RG_STATE_RECOVER) {
- svcStatus.rs_restarts++;
- } else {
- svcStatus.rs_restarts = 0;
- }
-
- svcStatus.rs_state = RG_STATE_STARTING;
-
- if (set_rg_state(svcName, &svcStatus) < 0) {
- logt_print(LOG_ERR,
- "#47: Failed changing service status\n");
- rg_unlock(&lockp);
- return RG_EFAIL;
- }
-
- rg_unlock(&lockp);
-
- ret = group_op(svcName, RG_START);
- ret = !!ret; /* Either it worked or it didn't. Ignore all the
- cute values scripts might return */
-
- if (rg_lock(svcName, &lockp) < 0) {
- logt_print(LOG_ERR, "#74: Unable to obtain cluster lock: %s\n",
- strerror(errno));
- return RG_EFAIL;
- }
-
- svcStatus.rs_state = RG_STATE_STARTED;
- if (set_rg_state(svcName, &svcStatus) != 0) {
- logt_print(LOG_ERR,
- "#75: Failed changing service status\n");
- rg_unlock(&lockp);
- return RG_EFAIL;
- }
- rg_unlock(&lockp);
-
- if (ret == 0) {
- logt_print(LOG_NOTICE,
- "Service %s started\n",
- svcName);
-
- broadcast_event(svcName, RG_STATE_STARTED, svcStatus.rs_owner,
- svcStatus.rs_last_owner);
- } else {
- logt_print(LOG_WARNING,
- "#68: Failed to start %s; return value: %d\n",
- svcName, ret);
- }
-
- return ret;
-}
-
-
-/**
- * Fix stuff
- */
-int
-svc_convalesce(const char *svcName)
-{
- struct dlm_lksb lockp;
- rg_state_t svcStatus;
- int ret;
-
- if (rg_lock(svcName, &lockp) < 0) {
- logt_print(LOG_ERR, "#451: Unable to obtain cluster lock: %s\n",
- strerror(errno));
- return RG_EFAIL;
- }
-
- if (get_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#461: Failed getting status for RG %s\n",
- svcName);
- return RG_EFAIL;
- }
-
- switch(svcStatus.rs_state) {
- case RG_STATE_STARTED:
- break;
- case RG_STATE_STARTING:
- case RG_STATE_STOPPING:
- case RG_STATE_RECOVER:
- case RG_STATE_MIGRATE:
- case RG_STATE_ERROR:
- rg_unlock(&lockp);
- return RG_EAGAIN;
- default:
- rg_unlock(&lockp);
- return RG_EINVAL;
- }
-
- if (svcStatus.rs_flags & RG_FLAG_FROZEN) {
- rg_unlock(&lockp);
- return RG_EFROZEN;
- }
-
- if (svcStatus.rs_owner != (uint32_t)my_id()) {
- rg_unlock(&lockp);
- return RG_EFORWARD;
- }
-
- if (!(svcStatus.rs_flags & RG_FLAG_PARTIAL)) {
- rg_unlock(&lockp);
- return RG_ERUN;
- }
-
- rg_unlock(&lockp);
-
- logt_print(LOG_INFO, "Repairing %s\n", svcName);
- ret = group_op(svcName, RG_CONVALESCE);
-
- switch(ret) {
- default:
- logt_print(LOG_WARNING, "Failed to repair %s\n", svcName);
- /* Fail to restart a non-critical resource
- * does not fail the service. */
- return RG_EFAIL;
- case 0:
- logt_print(LOG_INFO, "Repair of %s was successful\n", svcName);
- break;
- }
-
- /* Success - flip owner in state info */
- if (rg_lock(svcName, &lockp) < 0) {
- logt_print(LOG_ERR, "#455: Unable to obtain cluster lock: %s\n",
- strerror(errno));
- return RG_EFAIL;
- }
-
- /* No need for a 'get' here since the service is still STARTED */
- svcStatus.rs_flags &= ~RG_FLAG_PARTIAL;
-
- set_rg_state(svcName, &svcStatus);
- rg_unlock(&lockp);
-
- return 0;
-}
-
-
-/**
- * Migrate a service to another node. Relies on agent
- * operating synchronously
- */
-int
-svc_migrate(const char *svcName, int target)
-{
- struct dlm_lksb lockp;
- rg_state_t svcStatus;
- int ret;
- cluster_member_list_t *membership;
- cman_node_t *m;
-
- if (!group_migratory(svcName, 1))
- return RG_EINVAL;
-
- membership = member_list();
- m = memb_id_to_p(membership, target);
- if (!m) {
- free_member_list(membership);
- return RG_EINVAL;
- }
-
- if (m->cn_member == 0) {
- free_member_list(membership);
- return RG_ENODE;
- }
-
- if (node_should_start_safe(target, membership, svcName) == FOD_ILLEGAL) {
- free_member_list(membership);
- return RG_EDEPEND;
- }
-
- count_resource_groups_local(m);
- if (m->cn_svcexcl ||
- (m->cn_svccount && is_exclusive(svcName))) {
- free_member_list(membership);
- return RG_EDEPEND;
- }
- free_member_list(membership);
-
- if (rg_lock(svcName, &lockp) < 0) {
- logt_print(LOG_ERR, "#45: Unable to obtain cluster lock: %s\n",
- strerror(errno));
- return RG_EFAIL;
- }
-
- if (get_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#46: Failed getting status for RG %s\n",
- svcName);
- return RG_EFAIL;
- }
-
- if (svcStatus.rs_owner == (uint32_t)target) {
- rg_unlock(&lockp);
- /* Do not allow migration to its current owner! */
- return 0;
- }
-
- if (svcStatus.rs_owner != (uint32_t)my_id()) {
- rg_unlock(&lockp);
- return RG_EFORWARD;
- }
-
- switch(svcStatus.rs_state) {
- case RG_STATE_STARTED:
- break;
- case RG_STATE_STARTING:
- case RG_STATE_STOPPING:
- case RG_STATE_RECOVER:
- case RG_STATE_MIGRATE:
- case RG_STATE_ERROR:
- rg_unlock(&lockp);
- return RG_EAGAIN;
- default:
- rg_unlock(&lockp);
- return RG_EFAIL;
- }
-
- if (svcStatus.rs_flags & RG_FLAG_FROZEN) {
- rg_unlock(&lockp);
- return RG_EFROZEN;
- }
- rg_unlock(&lockp);
-
- ret = group_migrate(svcName, target);
-
- switch(ret) {
- default:
- case -1:
- case OCF_RA_ERROR:
- svc_fail(svcName);
- /* XXX run svc_status again here to see if it's still
- healthy; if it is, don't FAIL it; it could be that
- the target node simply died; in this case, set status
- back to started */
- return RG_EFAIL;
- case OCF_RA_NOT_RUNNING:
- /* For these two, the VM was either not running or
- migration is simply impossible. */
- /* Don't mark the service as failed; since it's either
- recoverable or still running. */
- return RG_EFAIL;
- case OCF_RA_NOT_CONFIGURED:
- return RG_EINVAL;
- case 150: /* see vm.sh */
- /* Migration failed; VM still running on source node */
- return RG_ERELO;
- case 0:
- break;
- }
-
- /* Success - flip owner in state info */
- if (rg_lock(svcName, &lockp) < 0) {
- logt_print(LOG_ERR, "#45b: Unable to obtain cluster lock: %s\n",
- strerror(errno));
- return RG_EFAIL;
- }
-
- /* No need for a 'get' here since the service is still STARTED */
- svcStatus.rs_last_owner = svcStatus.rs_owner;
- svcStatus.rs_owner = target;
- svcStatus.rs_state = RG_STATE_STARTED;
-
- set_rg_state(svcName, &svcStatus);
- rg_unlock(&lockp);
-
- return 0;
-}
-
-
-/**
- * Ask the other nodes if they've seen this service. This can be used
- * to allow users the ability to use non-rgmanager tools to migrate
- * a virtual machine to another node in the cluster.
- *
- * Returns the node ID of the new owner, if any. -1 if no one in the
- * cluster has seen the service.
- */
-static int
-get_new_owner(const char *svcName)
-{
- SmMessageSt msgp, response;
- msgctx_t ctx;
- cluster_member_list_t *membership;
- int x, ret = -1, me = my_id();
-
- /* Build message */
- msgp.sm_hdr.gh_magic = GENERIC_HDR_MAGIC;
- msgp.sm_hdr.gh_command = RG_ACTION_REQUEST;
- msgp.sm_hdr.gh_arg1 = RG_STATUS_INQUIRY;
- msgp.sm_hdr.gh_length = sizeof(msgp);
- msgp.sm_data.d_action = RG_STATUS_INQUIRY;
- strncpy(msgp.sm_data.d_svcName, svcName,
- sizeof(msgp.sm_data.d_svcName));
- msgp.sm_data.d_svcOwner = 0;
- msgp.sm_data.d_ret = 0;
-
- swab_SmMessageSt(&msgp);
-
- membership = member_list();
- for (x = 0; x < membership->cml_count && ret < 0; x++) {
-
- /* don't query down members */
- if (!membership->cml_members[x].cn_member)
- continue;
- /* don't query self */
- if (membership->cml_members[x].cn_nodeid == me)
- continue;
-
- if (msg_open(MSG_CLUSTER, membership->cml_members[x].cn_nodeid,
- RG_PORT, &ctx, 2 * cluster_timeout) < 0) {
- /* failed to open: better to claim false successful
- status rather than claim a failure and possibly
- end up with a service on >1 node */
- goto out;
- }
-
- msg_send(&ctx, &msgp, sizeof(msgp));
- if (msg_receive(&ctx, &response, sizeof (response), 10) !=
- sizeof(response))
- goto cont;
-
- swab_SmMessageSt(&response);
- if (response.sm_data.d_ret == RG_SUCCESS)
- ret = response.sm_data.d_svcOwner;
- else
- ret = -1;
-
-cont:
- msg_close(&ctx);
- }
-
-out:
- free_member_list(membership);
-
- return ret;
-}
-
-
-/**
- If a service is 'migratory' - that is, it has the 'migratory' attribute
- and has no children, this will query other nodes in the cluster, checking
- to see if the service has migrated to that node using a status inquiry
- message. Note that this is a very inefficient thing to do; it would be
- much, much better to simply use the cluster tools to migrate rather than
- using the standard management tools for the service/virtual machine.
- */
-static int
-msvc_check_cluster(const char *svcName)
-{
- struct dlm_lksb lockp;
- int newowner;
- rg_state_t svcStatus;
-
- if (!group_migratory(svcName, 1))
- return -1;
-
- newowner = get_new_owner(svcName);
- if (newowner < 0) {
- logt_print(LOG_DEBUG, "No other nodes have seen %s\n", svcName);
- return -1;
- }
-
- /* New owner found */
- logt_print(LOG_NOTICE, "Migration: %s is running on %d\n", svcName, newowner);
-
- /* If the check succeeds (returns 0), then flip the state back to
- 'started' - with a new owner */
- if (rg_lock(svcName, &lockp) < 0) {
- logt_print(LOG_ERR, "#451: Unable to obtain cluster lock: %s\n",
- strerror(errno));
- return -1;
- }
-
- if (get_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#452: Failed getting status for RG %s\n",
- svcName);
- return -1;
- }
-
- svcStatus.rs_state = RG_STATE_STARTED;
- svcStatus.rs_owner = newowner;
-
- if (set_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#453: Failed setting status for RG %s\n",
- svcName);
- return -1;
- }
- rg_unlock(&lockp);
-
- return newowner;
-}
-
-
-/**
- * Check status of a cluster service
- *
- * @param svcName Service name to check.
- * @return RG_EFORWARD, RG_EFAIL, 0
- */
-int
-svc_status(const char *svcName)
-{
- struct dlm_lksb lockp;
- rg_state_t svcStatus;
- int ret;
-
- if (rg_lock(svcName, &lockp) < 0) {
- logt_print(LOG_ERR, "#48: Unable to obtain cluster lock: %s\n",
- strerror(errno));
- return RG_EFAIL;
- }
-
- if (get_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#49: Failed getting status for RG %s\n",
- svcName);
- return RG_EFAIL;
- }
- rg_unlock(&lockp);
-
- if (svcStatus.rs_flags & RG_FLAG_FROZEN)
- /* Don't check status if the service is frozen */
- return 0;
-
- if (svcStatus.rs_owner != (uint32_t)my_id())
- /* Don't check status for anything not owned */
- return 0;
-
- if (svcStatus.rs_state == RG_STATE_STARTED) {
- /* Running locally and not migrating = normal status
- * check
- */
- ret = group_op(svcName, RG_STATUS);
- } else if (svcStatus.rs_state == RG_STATE_MIGRATE) {
- /* Migrating resources need an inquiry check to avoid
- * setting NEEDSTOP/NEEDSTART in the resource tree.
- */
- ret = group_op(svcName, RG_STATUS_INQUIRY);
- } else {
- /* Not-running RGs should not be checked either. */
- return 0;
- }
-
- /* For running services, if the return code is 0, we're done*/
- if (svcStatus.rs_state == RG_STATE_STARTED) {
- ret = handle_started_status(svcName, ret, &svcStatus);
-
- if (ret & SFL_PARTIAL) {
- ret &= ~SFL_PARTIAL;
- svcStatus.rs_flags |= RG_FLAG_PARTIAL;
- if (rg_lock(svcName, &lockp) < 0) {
- logt_print(LOG_ERR,
- "#481: Unable to obtain cluster lock: %s\n",
- strerror(errno));
- return RG_EFAIL;
- }
-
- if (set_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR,
- "#482: Failed setting status for RG %s\n",
- svcName);
- return RG_EFAIL;
- }
- rg_unlock(&lockp);
- }
-
- return ret;
- }
-
- return handle_migrate_status(svcName, ret, &svcStatus);
-}
-
-
-static int
-handle_started_status(const char *svcName, int ret,
- rg_state_t __attribute__((unused)) *svcStatus)
-{
- int newowner, ret2;
-
- if (ret & SFL_FAILURE) {
- newowner = msvc_check_cluster(svcName);
- if (newowner >= 0)
- return 0; /* running but not here */
- return ret; /* not running anymore */
- }
-
- /* Ok, we have a recoverable service. Try to perform
- inline recovery */
- if (ret & SFL_RECOVERABLE) {
-
- logt_print(LOG_WARNING, "Some independent resources in %s failed; "
- "Attempting inline recovery\n", svcName);
-
- ret2 = group_op(svcName, RG_CONDSTOP);
- if (ret2 & SFL_PARTIAL) {
- ret |= SFL_PARTIAL;
- ret2 &= ~SFL_PARTIAL;
- }
-
- if (!(ret2 & SFL_FAILURE)) {
- ret2 = group_op(svcName, RG_CONDSTART);
- } else {
- logt_print(LOG_WARNING, "Inline recovery of %s failed\n",
- svcName);
- return ret;
- }
-
- logt_print(LOG_NOTICE, "Inline recovery of %s complete\n",
- svcName);
- if (ret & SFL_PARTIAL) {
- logt_print(LOG_NOTICE, "Note: Some non-critical "
- "resources were stopped during recovery.\n");
- logt_print(LOG_NOTICE, "Run 'clusvcadm -c %s' to "
- "restore them to operation.\n", svcName);
- return SFL_PARTIAL;
- }
-
- return 0;
- }
-
- return ret;
-}
-
-
-static int
-handle_migrate_status(const char *svcName, int ret, rg_state_t *svcStatus)
-{
- struct dlm_lksb lockp;
- /* For service(s) migrating to the local node, ignore invalid
- return codes.
- XXX Should put a timeout on migrating services */
- if (ret != 0)
- return 0;
-
- /* If the check succeeds (returns 0), then flip the state back to
- 'started' - we now own the service */
- if (rg_lock(svcName, &lockp) < 0) {
- logt_print(LOG_ERR, "#45: Unable to obtain cluster lock: %s\n",
- strerror(errno));
- return RG_EFAIL;
- }
-
- svcStatus->rs_state = RG_STATE_STARTED;
- if (set_rg_state(svcName, svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#46: Failed getting status for RG %s\n",
- svcName);
- return RG_EFAIL;
- }
- rg_unlock(&lockp);
-
- logt_print(LOG_NOTICE, "%s is now running locally\n", svcName);
-
- return 0;
-}
-
-
-int
-svc_status_inquiry(const char *svcName)
-{
- rg_state_t svcStatus;
-
- if (get_rg_state_local(svcName, &svcStatus) != 0) {
- logt_print(LOG_ERR, "Failed getting local status for RG %s\n",
- svcName);
- return RG_EFAIL;
- }
-
- if (svcStatus.rs_flags & RG_FLAG_FROZEN)
- return 0;
-
- return group_op(svcName, RG_STATUS_INQUIRY);
-}
-
-
-/**
- * Stop a cluster service.
- *
- * @param svcName Service ID to stop.
- * @param flags Service-operation specific flags to take into account.
- * @see svc_advise_stop
- * @return FAIL, 0
- */
-static int
-_svc_stop(const char *svcName, int req, int recover, uint32_t newstate)
-{
- struct dlm_lksb lockp;
- rg_state_t svcStatus;
- int ret = 0;
- int old_state;
-
- if (!rg_quorate()) {
- logt_print(LOG_WARNING, "#69: Unclean %s of %s\n",
- rg_req_str(req), svcName);
- return group_op(svcName, RG_STOP);
- }
-
- if (rg_lock(svcName, &lockp) == RG_EFAIL) {
- logt_print(LOG_ERR, "#50: Unable to obtain cluster lock: %s\n",
- strerror(errno));
- return RG_EFAIL;
- }
-
- if (get_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#51: Failed getting status for RG %s\n",
- svcName);
- return RG_EFAIL;
- }
-
- switch (svc_advise_stop(&svcStatus, svcName, req)) {
- case 0:
- rg_unlock(&lockp);
- logt_print(LOG_DEBUG, "Unable to stop RG %s in %s state\n",
- svcName, rg_state_str(svcStatus.rs_state));
- return RG_EFAIL;
- case 6:
- /* Mark stopped, but do not do anything */
- svcStatus.rs_last_owner = svcStatus.rs_owner;
- svcStatus.rs_owner = 0;
- svcStatus.rs_state = RG_STATE_STOPPED;
- svcStatus.rs_flags = 0;
- if (set_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- return RG_EFAIL;
- }
- rg_unlock(&lockp);
- broadcast_event(svcName, RG_STATE_STOPPED,
- -1, svcStatus.rs_last_owner);
- return RG_ESUCCESS;
- case 2:
- rg_unlock(&lockp);
- return RG_ESUCCESS;
- case 3:
- rg_unlock(&lockp);
- return RG_EFORWARD;
- case 4:
- rg_unlock(&lockp);
- return RG_EAGAIN;
- case 5:
- rg_unlock(&lockp);
- return RG_EFROZEN;
- default:
- break;
- }
-
- old_state = svcStatus.rs_state;
-
- if (old_state == RG_STATE_RECOVER) {
- logt_print(LOG_DEBUG, "%s is clean; skipping double-stop\n",
- svcName);
- svcStatus.rs_state = newstate;
- svcStatus.rs_flags = 0;
-
- if (set_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#52: Failed changing RG status\n");
- return RG_EFAIL;
- }
- }
-
- logt_print(LOG_NOTICE, "Stopping service %s\n", svcName);
-
- if (recover)
- svcStatus.rs_state = RG_STATE_ERROR;
- else
- svcStatus.rs_state = RG_STATE_STOPPING;
- svcStatus.rs_transition = (uint64_t)time(NULL);
-
- //printf("rg state = %s\n", rg_state_str(svcStatus.rs_state));
-
- if (set_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#52: Failed changing RG status\n");
- return RG_EFAIL;
- }
- rg_unlock(&lockp);
-
- ret = group_op(svcName, RG_STOP);
-
- /* fix up return code on failure during disable */
- if (ret)
- ret = RG_EFAIL;
-
- if ((old_state == RG_STATE_FAILED ||
- old_state == RG_STATE_DISABLED) &&
- newstate == RG_STATE_DISABLED) {
- if (ret) {
- /*
- * Return warning on disable-after-fail.
- * (mark it disabled anyway)
- */
- logt_print(LOG_ALERT, "Marking %s as 'disabled', "
- "but some resources may still be allocated!\n",
- svcName);
- ret = RG_EWARNING;
- }
- _svc_stop_finish(svcName, 0, newstate);
- } else {
- _svc_stop_finish(svcName, ret, newstate);
- }
-
- return ret;
-}
-
-
-static int
-_svc_stop_finish(const char *svcName, int failed, uint32_t newstate)
-{
- rg_state_t svcStatus;
- struct dlm_lksb lockp;
-
- if (rg_lock(svcName, &lockp) == RG_EFAIL) {
- logt_print(LOG_ERR, "#53: Unable to obtain cluster lock: %s\n",
- strerror(errno));
- return RG_EFAIL;
- }
-
- if (get_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#54: Failed getting status for RG %s\n",
- svcName);
- return RG_EFAIL;
- }
-
- if ((svcStatus.rs_state != RG_STATE_STOPPING) &&
- (svcStatus.rs_state != RG_STATE_ERROR) &&
- (svcStatus.rs_state != RG_STATE_RECOVER)) {
- rg_unlock(&lockp);
- return 0;
- }
-
- if (svcStatus.rs_owner != 0) {
- svcStatus.rs_last_owner = svcStatus.rs_owner;
- svcStatus.rs_owner = 0;
- }
-
- if (failed) {
- logt_print(LOG_CRIT, "#12: RG %s failed to stop; intervention "
- "required\n", svcName);
- newstate = RG_STATE_FAILED;
- } else if (svcStatus.rs_state == RG_STATE_ERROR) {
- svcStatus.rs_state = RG_STATE_RECOVER;
- newstate = RG_STATE_RECOVER;
- }
-
- svcStatus.rs_state = newstate;
- /* If host fails, we need to remember frozen flag */
- svcStatus.rs_flags &= RG_FLAG_FROZEN;
-
- logt_print(LOG_NOTICE, "Service %s is %s\n", svcName,
- rg_state_str(svcStatus.rs_state));
- //printf("rg state = %s\n", rg_state_str(svcStatus.rs_state));
-
- svcStatus.rs_transition = (uint64_t)time(NULL);
- if (set_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#55: Failed changing RG status\n");
- return RG_EFAIL;
- }
- rg_unlock(&lockp);
-
- broadcast_event(svcName, newstate, -1, svcStatus.rs_last_owner);
-
- return 0;
-}
-
-
-/**
- * Disable a cluster service. Services in the disabled state are never
- * automatically started by the service manager - one must send a SVC_START
- * message.
- *
- * @param svcName Service ID to stop.
- * @return FAIL, 0
- */
-int
-svc_disable(const char *svcName)
-{
- return _svc_stop(svcName, RG_DISABLE, 0, RG_STATE_DISABLED);
-}
-
-
-int
-svc_stop(const char *svcName, int req)
-{
- return _svc_stop(svcName, req, (req == RG_STOP_RECOVER),
- RG_STATE_STOPPED);
-}
-
-
-/**
- * Mark a cluster service as failed. User intervention required.
- *
- * @param svcName Service ID to stop.
- * @return FAIL, 0
- */
-int
-svc_fail(const char *svcName)
-{
- struct dlm_lksb lockp;
- rg_state_t svcStatus;
-
- if (rg_lock(svcName, &lockp) == RG_EFAIL) {
- logt_print(LOG_ERR, "#55: Unable to obtain cluster lock: %s\n",
- strerror(errno));
- return RG_EFAIL;
- }
-
- logt_print(LOG_DEBUG, "Handling failure request for RG %s\n", svcName);
-
- if (get_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#56: Failed getting status for RG %s\n",
- svcName);
- return RG_EFAIL;
- }
-
- if ((svcStatus.rs_state == RG_STATE_STARTED) &&
- (svcStatus.rs_owner != (uint32_t)my_id())) {
- rg_unlock(&lockp);
- logt_print(LOG_DEBUG, "Unable to disable RG %s in %s state\n",
- svcName, rg_state_str(svcStatus.rs_state));
- return RG_EFAIL;
- }
-
- /*
- * Leave a bread crumb so we can debug the problem with the service!
- */
- if (svcStatus.rs_owner != 0) {
- svcStatus.rs_last_owner = svcStatus.rs_owner;
- svcStatus.rs_owner = 0;
- }
- svcStatus.rs_state = RG_STATE_FAILED;
- svcStatus.rs_transition = (uint64_t)time(NULL);
- svcStatus.rs_restarts = 0;
- if (set_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#57: Failed changing RG status\n");
- return RG_EFAIL;
- }
- rg_unlock(&lockp);
-
- broadcast_event(svcName, RG_STATE_FAILED, -1,
- svcStatus.rs_last_owner);
-
- return 0;
-}
-
-/**
- * Flag/Unflag a cluster service as frozen.
- *
- * @param svcName Service ID to flag/unflag as frozen.
- * @return FAIL, 0
- */
-static int
-_svc_freeze(const char *svcName, int enabled)
-{
- struct dlm_lksb lockp;
- rg_state_t svcStatus;
-
- if (rg_lock(svcName, &lockp) == RG_EFAIL) {
- logt_print(LOG_ERR, "#55: Unable to obtain cluster lock: %s\n",
- strerror(errno));
- return RG_EFAIL;
- }
-
- logt_print(LOG_DEBUG, "Handling %s request for RG %s\n", enabled?"freeze":"unfreeze",
- svcName);
-
- if (get_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#56: Failed getting status for RG %s\n",
- svcName);
- return RG_EFAIL;
- }
-
- switch(svcStatus.rs_state) {
- case RG_STATE_STOPPED:
- case RG_STATE_STARTED:
- case RG_STATE_DISABLED:
-
- if (enabled == 1) {
- logt_print(LOG_DEBUG, "Freezing RG %s\n", svcName);
- svcStatus.rs_flags |= RG_FLAG_FROZEN;
- } else {
- logt_print(LOG_DEBUG, "Unfreezing RG %s\n", svcName);
- svcStatus.rs_flags &= ~RG_FLAG_FROZEN;
- }
-
- if (set_rg_state(svcName, &svcStatus) != 0) {
- rg_unlock(&lockp);
- logt_print(LOG_ERR, "#57: Failed changing RG status\n");
- return RG_EFAIL;
- }
- break;
-
- default:
- rg_unlock(&lockp);
- return RG_EAGAIN;
- break;
- }
-
- rg_unlock(&lockp);
-
- return 0;
-}
-
-int
-svc_freeze(const char *svcName)
-{
- return _svc_freeze(svcName, 1);
-}
-
-int
-svc_unfreeze(const char *svcName)
-{
- return _svc_freeze(svcName, 0);
-}
-
-
-/*
- * Send a message to the target node to start the service.
- */
-int
-svc_start_remote(const char *svcName, int request, uint32_t target)
-{
- SmMessageSt msg_relo;
- int msg_ret;
- cluster_member_list_t *ml;
- msgctx_t ctx;
-
- /* Build the message header */
- msg_relo.sm_hdr.gh_magic = GENERIC_HDR_MAGIC;
- msg_relo.sm_hdr.gh_command = RG_ACTION_REQUEST;
- /* XXX XXX */
- msg_relo.sm_hdr.gh_arg1 = RG_ACTION_MASTER;
- msg_relo.sm_hdr.gh_length = sizeof (SmMessageSt);
- msg_relo.sm_data.d_action = request;
- strncpy(msg_relo.sm_data.d_svcName, svcName,
- sizeof(msg_relo.sm_data.d_svcName));
- msg_relo.sm_data.d_ret = 0;
- msg_relo.sm_data.d_svcOwner = target;
- /* Open a connection to the other node */
-
- if (msg_open(MSG_CLUSTER, target, RG_PORT, &ctx, 2 * cluster_timeout)< 0) {
- logt_print(LOG_ERR,
- "#58: Failed opening connection to member #%d\n",
- target);
- return -1;
- }
-
- /* Encode */
- swab_SmMessageSt(&msg_relo);
-
- /* Send relocate message to the other node */
- if (msg_send(&ctx, &msg_relo, sizeof (SmMessageSt)) <
- (int)sizeof (SmMessageSt)) {
- logt_print(LOG_ERR,
- "#59: Error sending remote-start request to member #%d\n",
- target);
- msg_close(&ctx);
- return -1;
- }
-
- logt_print(LOG_DEBUG, "Sent remote-start request to %d\n", (int)target);
-
- /* Check the response */
- do {
- msg_ret = msg_receive(&ctx, &msg_relo,
- sizeof (SmMessageSt), 10);
-
- if ((msg_ret == -1 && errno != ETIMEDOUT) ||
- (msg_ret > 0)) {
- break;
- }
-
- /* Check to see if resource groups are locked for local
- shutdown */
- if (rg_locked()) {
- logt_print(LOG_WARNING,
- "#XX: Cancelling relocation: Shutting down\n");
- msg_close(&ctx);
- return RG_NO;
- }
-
- /* Check for node transition in the middle of a relocate */
- ml = member_list();
- if (memb_online(ml, target)) {
- free_member_list(ml);
- continue;
- }
- logt_print(LOG_WARNING,
- "#XX: Cancelling relocation: Target node down\n");
- free_member_list(ml);
- msg_close(&ctx);
- return RG_EFAIL;
- } while (1);
-
- if (msg_ret != sizeof (SmMessageSt)) {
- /*
- * In this case, we don't restart the service, because the
- * service state is actually unknown to us at this time.
- */
- logt_print(LOG_ERR, "#60: Mangled reply from member #%d during RG "
- "relocate\n", target);
- msg_close(&ctx);
- return 0; /* XXX really UNKNOWN */
- }
-
- /* Got a valid response from other node. */
- msg_close(&ctx);
-
- /* Decode */
- swab_SmMessageSt(&msg_relo);
-
- return msg_relo.sm_data.d_ret;
-}
-
-
-/**
- * handle_relocate_req - Relocate a service. This seems like a huge
- * deal, except it really isn't.
- *
- * @param svcID Service ID in question.
- * @param flags If (flags & SVCF_PENDING), we were called from
- * handle_start_req - and so we should ignore all local
- * restarts/stops - since handle_start_req does this
- * for us.
- * @param preferred_target When sent a relocate message from the
- * management software, a destination node
- * is sent as well. This causes us to try
- * starting the service on that node *first*,
- * but does NOT GUARANTEE that the service
- * will end up on that node. It will end up
- * on whatever node actually successfully
- * starts it.
- * @param new_owner Member who actually ends up owning the service.
- */
-int
-handle_relocate_req(char *svcName, int orig_request, int preferred_target,
- int *new_owner)
-{
- cluster_member_list_t *allowed_nodes = NULL, *backup = NULL;
- cman_node_t *m;
- rg_state_t svcStatus;
- int target = preferred_target, me = my_id();
- int ret, x, request = orig_request;
- int retries;
-
- get_rg_state_local(svcName, &svcStatus);
- if (svcStatus.rs_state == RG_STATE_DISABLED ||
- svcStatus.rs_state == RG_STATE_UNINITIALIZED)
- return RG_EINVAL;
-
- if (preferred_target > 0) {
- /* TODO: simplify this and don't keep alloc/freeing
- member lists */
- allowed_nodes = member_list();
-
- m = memb_id_to_p(allowed_nodes, preferred_target);
- if (m && m->cn_member) {
- count_resource_groups_local(m);
- if (m->cn_svcexcl ||
- (m->cn_svccount && is_exclusive(svcName))) {
- free_member_list(allowed_nodes);
- return RG_EDEPEND;
- }
- } else {
- target = preferred_target = -1;
- }
- free_member_list(allowed_nodes);
- }
-
- /*
- * Stop the service - if we haven't already done so.
- */
- if (request != RG_START_RECOVER) {
- ret = _svc_stop(svcName, request, 0, RG_STATE_STOPPED);
- if (ret == RG_EFAIL) {
- svc_fail(svcName);
- return RG_EABORT;
- }
- if (ret == RG_EFROZEN) {
- return RG_EFROZEN;
- }
- if (ret == RG_EFORWARD)
- return RG_EFORWARD;
- }
-
- if (preferred_target > 0) {
-
- allowed_nodes = member_list();
- /*
- Mark everyone except me and the preferred target DOWN for now
- If we can't start it on the preferred target, then we'll try
- other nodes.
- */
- //count_resource_groups(allowed_nodes);
- backup = member_list_dup(allowed_nodes);
-
- for (x = 0; x < allowed_nodes->cml_count; x++) {
- if (allowed_nodes->cml_members[x].cn_nodeid == me ||
- allowed_nodes->cml_members[x].cn_nodeid ==
- preferred_target)
- continue;
- allowed_nodes->cml_members[x].cn_member = 0;
- }
-
- /*
- * First, see if it's legal to relocate to the target node.
- * Legal means: the node is online and is in the
- * [restricted] failover domain of the service, or the
- * service has no failover domain.
- */
- target = best_target_node(allowed_nodes, me, svcName, 1);
-
- free_member_list(allowed_nodes);
-
- /*
- * I am the ONLY one capable of running this service,
- * PERIOD...
- */
- if (target == me && me != preferred_target) {
- free_member_list(backup);
- goto exhausted;
- }
-
- if (target == me) {
- /*
- Relocate to self. Don't send a network request
- to do it; it would block.
- */
- if (svc_start(svcName, RG_START) == 0) {
- *new_owner = me;
- free_member_list(backup);
- return 0;
- }
- } else if (target == preferred_target) {
- /*
- * It's legal to start the service on the given
- * node. Try to do so.
- */
- if (svc_start_remote(svcName, request, target) == 0) {
- *new_owner = target;
- /*
- * Great! We're done...
- */
- free_member_list(backup);
- return 0;
- }
-
- /*
- * Failed to start on that node.
- * Use the START_RECOVER operation on subsequent
- * attempts.
- */
- request = RG_START_RECOVER;
- }
- }
-
- /*
- * Ok, so, we failed to send it to the preferred target node.
- * Try to start it on all other nodes.
- */
- if (backup) {
- allowed_nodes = backup;
- } else {
- allowed_nodes = member_list();
- //count_resource_groups(allowed_nodes);
- }
- member_list_shuffle(allowed_nodes);
-
- if (preferred_target > 0)
- memb_mark_down(allowed_nodes, preferred_target);
- memb_mark_down(allowed_nodes, me);
-
- while (memb_count(allowed_nodes)) {
- target = best_target_node(allowed_nodes, me, svcName, 1);
- if (target == me) {
- free_member_list(allowed_nodes);
- goto exhausted;
- }
-
- retries = 0;
-retry:
- ret = svc_start_remote(svcName, request, target);
- switch (ret) {
- case RG_ERUN:
- /* Someone stole the service while we were
- trying to relo it */
- get_rg_state_local(svcName, &svcStatus);
- *new_owner = svcStatus.rs_owner;
- free_member_list(allowed_nodes);
- return 0;
- case RG_ENOSERVICE:
- /*
- * Configuration update pending on remote node? Give it
- * a few seconds to sync up. rhbz#568126
- *
- * Configuration updates are synchronized in later releases
- * of rgmanager; this should not be needed.
- */
- if (retries++ < 4) {
- sleep(3);
- goto retry;
- }
- logt_print(LOG_WARNING, "Member #%d has a different "
- "configuration than I do; trying next "
- "member.", target);
- /* Deliberate */
- case RG_EDEPEND:
- case RG_EFAIL:
- case RG_EDEADLCK:
- /* Uh oh - we failed to relocate to this node.
- ensure that we tell the next node to start it from
- the 'recovering' state. */
- request = RG_START_RECOVER;
- memb_mark_down(allowed_nodes, target);
- continue;
- case RG_EABORT:
- svc_report_failure(svcName);
- free_member_list(allowed_nodes);
- return RG_EFAIL;
- default:
- /* deliberate fallthrough */
- logt_print(LOG_ERR,
- "#61: Invalid reply from member %d during"
- " relocate operation!\n", target);
- case RG_NO:
- /* state uncertain */
- free_member_list(allowed_nodes);
- logt_print(LOG_CRIT, "State Uncertain: svc:%s "
- "nid:%d req:%s ret:%d\n", svcName,
- target, rg_req_str(request), ret);
- return 0;
- case 0:
- *new_owner = target;
- logt_print(LOG_NOTICE, "Service %s is now running "
- "on member %d\n", svcName, (int)target);
- free_member_list(allowed_nodes);
- return 0;
- }
- }
- free_member_list(allowed_nodes);
-
- /*
- * We got sent here from handle_start_req.
- * We're DONE.
- */
- if (orig_request == RG_START_RECOVER) {
- _svc_stop_finish(svcName, 0, RG_STATE_STOPPED);
- return RG_EFAIL;
- }
-
- /*
- * All potential places for the service to start have been exhausted.
- * We're done.
- */
-exhausted:
- if (!rg_locked()) {
- logt_print(LOG_WARNING,
- "#70: Failed to relocate %s; restarting locally\n",
- svcName);
- if (svc_start(svcName, RG_START_RECOVER) == 0) {
- *new_owner = me;
- return RG_ERELO;
- }
- }
-
- if (svc_stop(svcName, RG_STOP) != 0) {
- svc_fail(svcName);
- svc_report_failure(svcName);
- }
-
- return RG_EFAIL;
-}
-
-
-pthread_mutex_t exclusive_mutex = PTHREAD_MUTEX_INITIALIZER;
-/**
- * handle_start_req - Handle a generic start request from a user or during
- * service manager boot.
- *
- * @param svcID Service ID to start.
- * @param flags
- * @param new_owner Owner which actually started the service.
- * @return FAIL - Failure.
- * 0 - The service is running.
- */
-int
-handle_start_req(char *svcName, int req, int *new_owner)
-{
- int ret, tolerance = FOD_BEST;
- cluster_member_list_t *membership;
- int need_check, actual_failure = 0;
-
- /* When we get an enable req. for a migratory service,
- check other nodes to see if they are already running
- said service - and ignore failover domain constraints
- */
- if ((ret = msvc_check_cluster(svcName)) >= 0) {
- *new_owner = ret;
- return RG_SUCCESS;
- }
-
- need_check = have_exclusive_resources();
- membership = member_list();
-
- /*
- * When a service request is from a user application (eg, clusvcadm),
- * accept FOD_GOOD instead of FOD_BEST
- */
- if (req == RG_ENABLE)
- tolerance = FOD_GOOD;
- if (req != RG_RESTART &&
- req != RG_START_RECOVER &&
- (node_should_start_safe(my_id(), membership, svcName) <
- tolerance)) {
- free_member_list(membership);
- return RG_EFAIL;
- }
- if (need_check) {
- pthread_mutex_lock(&exclusive_mutex);
- ret = check_exclusive_resources(membership, svcName);
- if (ret != 0) {
- free_member_list(membership);
- pthread_mutex_unlock(&exclusive_mutex);
- if (ret > 0)
- goto relocate;
- else
- return RG_EFAIL;
- }
- }
- free_member_list(membership);
-
- /* Check for dependency. We cannot start unless our
- dependency is met */
- if (check_depend_safe(svcName) == 0) {
- if (req == RG_START_RECOVER) {
- logt_print(LOG_INFO, "Dependency for %s missing "
- "during recovery; marking as stopped",
- svcName);
-
- _svc_stop_finish(svcName, 0, RG_STATE_STOPPED);
- }
- if (need_check)
- pthread_mutex_unlock(&exclusive_mutex);
- return RG_EDEPEND;
- }
-
- /*
- * This is a 'root' start request. We need to clear out our failure
- * mask here - so that we can try all nodes if necessary.
- */
- ret = svc_start(svcName, req);
- if (need_check)
- pthread_mutex_unlock(&exclusive_mutex);
-
- /*
- If services are locked, return the error
- */
- if (ret == RG_EAGAIN || ret == RG_ERUN || ret == RG_EFROZEN)
- return ret;
-
- /*
- * If we succeeded, then we're done.
- */
- if (ret == RG_ESUCCESS) {
- *new_owner = my_id();
- return RG_ESUCCESS;
- }
-
- /* Already running? */
- if (ret == RG_NO) {
- return RG_ESUCCESS;
- }
-
- /*
- * Keep the state open so the other nodes don't try to start
- * it. This allows us to be the 'root' of a given service.
- */
- logt_print(LOG_DEBUG, "Stopping failed service %s\n", svcName);
- if (svc_stop(svcName, RG_STOP_RECOVER) != 0) {
- logt_print(LOG_CRIT,
- "#13: Service %s failed to stop cleanly\n",
- svcName);
- (void) svc_fail(svcName);
-
- /*
- * If we failed to stop the service, we're done. At this
- * point, we can't determine the service's status - so
- * trying to start it on other nodes is right out.
- */
- return RG_EABORT;
- }
- actual_failure = 1;
-
-relocate:
- /*
- * OK, it failed to start - but succeeded to stop. Now,
- * we should relocate the service.
- */
- if (actual_failure)
- logt_print(LOG_WARNING, "#71: Relocating failed service %s\n",
- svcName);
- ret = handle_relocate_req(svcName, RG_START_RECOVER, -1, new_owner);
-
- /* If we leave the service stopped, instead of disabled, someone
- will try to start it after the next node transition */
- if (ret == RG_EFAIL) {
- if (svc_stop(svcName, RG_STOP) != 0) {
- svc_fail(svcName);
- svc_report_failure(svcName);
- }
- }
-
- return ret;
-}
-
-
-/**
- * handle_start_remote_req - Handle a remote start request.
- *
- * @param svcID Service ID to start.
- * @param flags Flags to use to determine start behavior.
- * @return FAIL - Local failure. ABORT - Unrecoverable error:
- * the service didn't start, nor stop cleanly. 0
- * - We started the service.
- */
-int
-handle_start_remote_req(char *svcName, int req)
-{
- int tolerance = FOD_BEST;
- int x;
- uint32_t me = my_id();
- cluster_member_list_t *membership;
- int need_check;
-
- if (rg_locked()) {
- /* don't even calc if rg's locked */
- return RG_EFAIL;
- }
-
- need_check = have_exclusive_resources();
- membership = member_list();
-
- /* XXX ok, so we need to say "should I start this if I was the
- only cluster member online */
- for (x = 0; x < (int)membership->cml_count; x++) {
- if (membership->cml_members[x].cn_nodeid == (int)me)
- continue;
-
- membership->cml_members[x].cn_member = 0;
- }
-
- if (req == RG_ENABLE)
- tolerance = FOD_GOOD;
-
- /*
- * See if we agree with our ability to start the given service.
- */
- if (node_should_start_safe(me, membership, svcName) < tolerance){
- free_member_list(membership);
- return RG_EFAIL;
- }
- if (need_check) {
- pthread_mutex_lock(&exclusive_mutex);
- if (check_exclusive_resources(membership, svcName) != 0) {
- free_member_list(membership);
- pthread_mutex_unlock(&exclusive_mutex);
- return RG_EEXCL;
- }
- }
- free_member_list(membership);
-
- x = svc_start(svcName, req);
-
- if ((x == 0) || (x == RG_ERUN) || (x == RG_EFROZEN)) {
- if (need_check)
- pthread_mutex_unlock(&exclusive_mutex);
- return x;
- }
- if (need_check)
- pthread_mutex_unlock(&exclusive_mutex);
-
- if (svc_stop(svcName, central_events_enabled() ?
- RG_STATE_STOPPED : RG_STOP_RECOVER) == 0)
- return RG_EFAIL;
-
- svc_fail(svcName);
- return RG_EABORT;
-}
-
-
-/**
- handle_recover_req
- */
-int
-handle_recover_req(char *svcName, int *new_owner)
-{
- char policy[20];
-
- get_recovery_policy(svcName, policy, sizeof(policy));
-
- if (!strcasecmp(policy, "disable")) {
- clear_restart(svcName);
- return svc_disable(svcName);
- } else if (!strcasecmp(policy, "relocate")) {
- clear_restart(svcName);
- return handle_relocate_req(svcName, RG_START_RECOVER, -1,
- new_owner);
- }
-
- /* Check restart counter/timer for this resource */
- if (check_restart(svcName) > 0) {
- clear_restart(svcName);
-
- if (strstr(policy, "disable")) {
- logt_print(LOG_NOTICE,
- "Restart threshold for %s exceeded; "
- "disabling\n", svcName);
- return svc_disable(svcName);
- }
- logt_print(LOG_NOTICE, "Restart threshold for %s exceeded; "
- "attempting to relocate\n", svcName);
- return handle_relocate_req(svcName, RG_START_RECOVER, -1,
- new_owner);
- }
-
- add_restart(svcName);
-
- return handle_start_req(svcName, RG_START_RECOVER, new_owner);
-}
-
-
-int
-handle_fd_start_req(char *svcName, int request, int *new_owner)
-{
- cluster_member_list_t *allowed_nodes;
- int target, me = my_id();
- int ret = RG_EFAIL;
-
- /* When we get an enable req. for a migratory service,
- check other nodes to see if they are already running
- said service - and ignore failover domain constraints
- */
- if ((ret = msvc_check_cluster(svcName)) >= 0) {
- *new_owner = ret;
- return RG_SUCCESS;
- }
-
- allowed_nodes = member_list();
-
- while (memb_count(allowed_nodes)) {
- target = best_target_node(allowed_nodes, 0,
- svcName, 1);
- if (target == me) {
- ret = handle_start_remote_req(svcName,
- (request==RG_ENABLE?RG_START_RECOVER:request));
- if (ret == RG_EAGAIN)
- goto out;
- } else if (!(target > 0)) {
- goto out;
- } else {
- ret = svc_start_remote(svcName,
- (request==RG_ENABLE?
- RG_START_RECOVER:RG_START_REMOTE),
- target);
- }
-
- switch(ret) {
- case RG_ESUCCESS:
- *new_owner = target;
- ret = RG_ESUCCESS;
- goto out;
- case RG_ERUN:
- ret = RG_ERUN;
- goto out;
- case RG_EFAIL:
- memb_mark_down(allowed_nodes, target);
- continue;
- case RG_EABORT:
- svc_report_failure(svcName);
- ret = RG_EFAIL;
- goto out;
- default:
- logt_print(LOG_ERR,
- "#6X: Invalid reply [%d] from member %d during"
- " relocate operation!\n", ret, target);
- }
- }
-
-out:
- free_member_list(allowed_nodes);
- return ret;
-}
diff --git a/rgmanager/src/daemons/rg_thread.c b/rgmanager/src/daemons/rg_thread.c
deleted file mode 100644
index 1d7b1fb..0000000
--- a/rgmanager/src/daemons/rg_thread.c
+++ /dev/null
@@ -1,770 +0,0 @@
-#include <time.h>
-#include <list.h>
-#include <restart_counter.h>
-#include <reslist.h>
-#include <message.h>
-#include <resgroup.h>
-#include <rg_locks.h>
-#include <gettid.h>
-#include <rg_queue.h>
-#include <assert.h>
-#include <members.h>
-#include <liblogthread.h>
-
-
-/**
- * Resource thread list entry.
- */
-typedef struct __resthread {
- list_head();
- pthread_t rt_thread; /** Thread identifier */
- int rt_request; /** Current pending operation */
- int rt_status; /** Used for init */
- char rt_name[256]; /** RG name */
- request_t **rt_queue; /** RG event queue */
- pthread_mutex_t *rt_queue_mutex; /** Mutex for event queue */
- pthread_cond_t *rt_queue_cond; /** pthread cond */
-} resthread_t;
-
-
-/**
- * Resource thread queue head.
- */
-static resthread_t *resthread_list = NULL;
-
-#ifdef WRAP_LOCKS
-static pthread_mutex_t reslist_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
-#else
-static pthread_mutex_t reslist_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
-
-static resthread_t *find_resthread_byname(const char *resgroupname);
-static int spawn_if_needed(const char *resgroupname);
-
-int central_events_enabled(void);
-
-
-/**
- SIGUSR1 output
- */
-void
-dump_threads(FILE *fp)
-{
- resthread_t *rt;
- request_t *req;
- int x = 0, y = 0;
-
- fprintf(fp, "Resource Group Threads \n");
- pthread_mutex_lock(&reslist_mutex);
- list_for(&resthread_list, rt, x) {
- fprintf(fp, " %s id:%d (@ %p) processing %s request (%d)\n",
- rt->rt_name,
- (unsigned)rt->rt_thread,
- rt,
- rg_req_str(rt->rt_request),
- rt->rt_request);
- if (rt->rt_queue) {
- fprintf(fp, " Pending requests: \n");
- list_for(rt->rt_queue, req, y) {
- fprintf(fp, " %s tgt:%d ctx:%p a0:%d a1:%d\n",
- rg_req_str(req->rr_request),
- req->rr_target,
- req->rr_resp_ctx,
- req->rr_arg0,
- req->rr_arg1);
- }
- }
- }
-
- x = !!resthread_list;
- pthread_mutex_unlock(&reslist_mutex);
- if (!x)
- fprintf(fp, " (none)\n");
- fprintf(fp, "\n");
-}
-
-
-static int
-wait_initialize(const char *name)
-{
- resthread_t *t;
-
- while (1) {
- pthread_mutex_lock(&reslist_mutex);
- t = find_resthread_byname(name);
-
- if (!t) {
- pthread_mutex_unlock(&reslist_mutex);
- return -1;
- }
-
- if (t->rt_status != RG_STATE_UNINITIALIZED) {
- pthread_mutex_unlock(&reslist_mutex);
- return 0;
- }
-
- pthread_mutex_unlock(&reslist_mutex);
- usleep(50000);
- }
-
- assert(0);
-}
-
-
-static void
-rg_sighandler_setup(void)
-{
- block_all_signals();
- unblock_signal(SIGCHLD);
-}
-
-
-static void
-purge_status_checks(request_t **list)
-{
- request_t *curr;
- int found;
-
- if (!list)
- return;
-
- do {
- found = 0;
- list_do(list, curr) {
- if (curr->rr_request == RG_STATUS) {
- list_remove(list, curr);
- rq_free(curr);
- found = 1;
- break;
- }
- } while (!list_done(list, curr));
- } while (found);
-}
-
-
-static void
-purge_all(request_t **list)
-{
- request_t *curr;
-
- if (!list)
- return;
-
- if (!*list)
- return;
-
- while((curr = *list)) {
-
- list_remove(list, curr);
- dbg_printf("Removed request %d\n", curr->rr_request);
- if (curr->rr_resp_ctx) {
- send_response(RG_EABORT, 0, curr);
- msg_close(curr->rr_resp_ctx);
- msg_free_ctx(curr->rr_resp_ctx);
- }
- rq_free(curr);
- }
-}
-
-
-static void *
-resgroup_thread_main(void *arg)
-{
- pthread_mutex_t my_queue_mutex;
- pthread_cond_t my_queue_cond;
- request_t *my_queue = NULL;
- int newowner = 0;
- char myname[256];
- resthread_t *myself;
- request_t *req;
- int ret = RG_EFAIL, error = 0, mystatus;
-
- rg_inc_threads();
-
- strncpy(myname, arg, sizeof(myname)-1);
- myname[sizeof(myname)-1] = '\0';
- dbg_printf("Thread %s (tid %d) starting\n",myname,gettid());
-
- pthread_mutex_init(&my_queue_mutex, NULL);
- pthread_mutex_lock(&my_queue_mutex);
- pthread_cond_init(&my_queue_cond, NULL);
-
- /*
- * Wait until we're inserted. The code herein should never be
- * reached.
- */
- while (1) {
- pthread_mutex_lock(&reslist_mutex);
-
- myself = find_resthread_byname(myname);
- if (myself)
- break;
-
- pthread_mutex_unlock(&reslist_mutex);
- usleep(250000);
- }
-
- myself->rt_queue = &my_queue;
- myself->rt_queue_mutex = &my_queue_mutex;
- myself->rt_queue_cond = &my_queue_cond;
- myself->rt_status = RG_STATE_STARTED; /* Ok, we're ready to go */
- rg_sighandler_setup();
-
- /* Wait for first event */
- pthread_mutex_unlock(&reslist_mutex);
-
- /* My mutex is still held */
- pthread_cond_wait(&my_queue_cond, &my_queue_mutex);
- pthread_mutex_unlock(&my_queue_mutex);
-
- while(1) {
- pthread_mutex_lock(&reslist_mutex);
- pthread_mutex_lock(&my_queue_mutex);
- if ((req = rq_next_request(&my_queue)) == NULL) {
- /* We're done. No more requests.
- We're about to kill our thread, so exit the
- loop with the lock held. */
- break;
- }
- pthread_mutex_unlock(&my_queue_mutex);
- pthread_mutex_unlock(&reslist_mutex);
-
- ret = RG_FAIL;
- error = 0;
-
- dbg_printf("Processing request %s, resource group %s\n",
- rg_req_str(req->rr_request), myname);
-
- /* find ourselves. */
- pthread_mutex_lock(&reslist_mutex);
- myself = find_resthread_byname(myname);
- assert(myself);
- myself->rt_request = req->rr_request;
- if (req->rr_request == RG_STOP_EXITING)
- myself->rt_status = RG_STATE_STOPPING;
- pthread_mutex_unlock(&reslist_mutex);
-
- switch(req->rr_request) {
- case RG_START_REMOTE:
- case RG_START_RECOVER:
- error = handle_start_remote_req(myname,
- req->rr_request);
- break;
-
- case RG_ENABLE:
- if (req->rr_target != 0 &&
- req->rr_target != (unsigned)my_id()) {
- error = RG_EFORWARD;
- ret = RG_NONE;
- break;
- }
- case RG_START:
- if (req->rr_arg0) {
- error = handle_fd_start_req(myname,
- req->rr_request,
- &newowner);
- } else {
- error = handle_start_req(myname,
- req->rr_request,
- &newowner);
- }
- break;
-
- case RG_RELOCATE:
- /* Relocate requests are user requests and must be
- forwarded */
- error = handle_relocate_req(myname, RG_START_REMOTE,
- req->rr_target,
- &newowner);
- if (error == RG_EFORWARD)
- ret = RG_NONE;
- break;
-
- case RG_CONVALESCE:
- error = svc_convalesce(myname);
-
- if (error == 0) {
- ret = RG_SUCCESS;
-
- pthread_mutex_lock(&my_queue_mutex);
- purge_status_checks(&my_queue);
- pthread_mutex_unlock(&my_queue_mutex);
- } else if (error == RG_EFORWARD) {
- ret = RG_NONE;
- break;
- } else {
- /*
- * Bad news.
- */
- ret = RG_EFAIL;
- }
- break;
-
- case RG_MIGRATE:
- error = svc_migrate(myname, req->rr_target);
-
- if (error == 0) {
- ret = RG_SUCCESS;
-
- pthread_mutex_lock(&my_queue_mutex);
- purge_status_checks(&my_queue);
- pthread_mutex_unlock(&my_queue_mutex);
- } else if (error == RG_EFORWARD) {
- ret = RG_NONE;
- break;
- } else {
- /*
- * Bad news.
- */
- ret = RG_EFAIL;
- }
- break;
-
- case RG_INIT:
- /* Stop without changing shared state of it */
- error = group_op(myname, RG_STOP);
-
- pthread_mutex_lock(&my_queue_mutex);
- purge_all(&my_queue);
- pthread_mutex_unlock(&my_queue_mutex);
-
- if (error == 0)
- ret = RG_SUCCESS;
- else
- ret = RG_EFAIL;
- break;
-
- case RG_CONDSTOP:
- /* CONDSTOP doesn't change RG state by itself */
- group_op(myname, RG_CONDSTOP);
- break;
-
- case RG_CONDSTART:
- /* CONDSTART doesn't change RG state by itself */
- group_op(myname, RG_CONDSTART);
- break;
-
- case RG_STOP:
- case RG_STOP_USER:
- /* Disable and user stop requests need to be
- forwarded; they're user requests */
- error = svc_stop(myname, req->rr_request);
-
- if (error == 0) {
- ret = RG_SUCCESS;
-
- pthread_mutex_lock(&my_queue_mutex);
- purge_status_checks(&my_queue);
- pthread_mutex_unlock(&my_queue_mutex);
- } else if (error == RG_EFORWARD) {
- ret = RG_NONE;
- break;
- } else {
- /*
- * Bad news.
- */
- ret = RG_EFAIL;
- }
-
- break;
-
- case RG_STOP_EXITING:
- /* We're out of here. Don't allow starts anymore */
- error = svc_stop(myname, RG_STOP);
-
- if (error == 0) {
- ret = RG_SUCCESS;
-
- } else if (error == RG_EFORWARD) {
- ret = RG_NONE;
- break;
- } else {
- /*
- * Bad news.
- */
- ret = RG_EFAIL;
- }
-
- pthread_mutex_lock(&my_queue_mutex);
- purge_all(&my_queue);
- pthread_mutex_unlock(&my_queue_mutex);
-
- break;
-
-
- case RG_DISABLE:
- /* Disable and user stop requests need to be
- forwarded; they're user requests */
- error = svc_disable(myname);
-
- if (error == 0) {
- ret = RG_SUCCESS;
-
- pthread_mutex_lock(&my_queue_mutex);
- purge_status_checks(&my_queue);
- pthread_mutex_unlock(&my_queue_mutex);
- } else if (error == RG_EFORWARD) {
- ret = RG_NONE;
- break;
- } else {
- /*
- * Bad news.
- */
- ret = RG_EFAIL;
- }
-
- break;
-
- case RG_RESTART:
- error = svc_stop(myname, RG_STOP_USER);
-
- if (error == 0) {
- pthread_mutex_lock(&my_queue_mutex);
- purge_status_checks(&my_queue);
- pthread_mutex_unlock(&my_queue_mutex);
-
- error = handle_start_req(myname,
- req->rr_request,
- &newowner);
- break;
-
- } else if (error == RG_EFORWARD) {
- ret = RG_NONE;
- break;
- } else {
- /*
- * Bad news.
- */
- ret = RG_EFAIL;
- }
-
- break;
-
- case RG_STATUS:
- if (!(rg_initialized()&FL_CONFIG)) {
- ret = RG_SUCCESS;
- break;
- }
- /* Need to make sure we don't check status of
- resource groups we don't own */
- error = svc_status(myname);
-
- /* Recover dead service */
- if (error == 0) {
- ret = RG_SUCCESS;
- break;
- }
-
- error = svc_stop(myname, RG_STOP_RECOVER);
- if (error == 0) {
- /* Stop generates an event - whatever the
- result. If central events are enabled
- don't bother trying to recover */
- if (central_events_enabled())
- break;
- error = handle_recover_req(myname, &newowner);
- if (error == 0)
- ret = RG_SUCCESS;
- }
-
- break;
-
- case RG_FREEZE:
- error = svc_freeze(myname);
- if (error != 0)
- ret = RG_EFAIL;
- break;
-
- case RG_UNFREEZE:
- error = svc_unfreeze(myname);
- if (error != 0)
- ret = RG_EFAIL;
- break;
-
- case RG_STATUS_INQUIRY:
- error = svc_status_inquiry(myname);
-
- if (error == 0) {
- ret = RG_SUCCESS;
- newowner = my_id();
- } else {
- ret = RG_EFAIL;
- newowner = -1;
- }
-
- break;
-
- default:
- printf("Unhandled request %d\n", req->rr_request);
- ret = RG_NONE;
- break;
- }
-
- pthread_mutex_lock(&reslist_mutex);
- myself = find_resthread_byname(myname);
- myself->rt_request = RG_NONE;
- pthread_mutex_unlock(&reslist_mutex);
-
- if (error == RG_EFORWARD) {
- /* Forward_request frees this and closes the
- file descriptor, so we can just move on
- with life. */
- forward_request(req);
- continue;
- }
-
- if (ret != RG_NONE && rg_initialized() &&
- (req->rr_resp_ctx)) {
- send_response(error, newowner, req);
- msg_close(req->rr_resp_ctx);
- msg_free_ctx(req->rr_resp_ctx);
- }
-
- rq_free(req);
- }
-
- /* reslist_mutex and my_queue_mutex held */
- myself = find_resthread_byname(myname);
-
- /* Not reached...
- if (!myself) {
- dbg_printf("I don't exist...\n");
- raise(SIGSEGV);
- }
- */
-
- pthread_mutex_unlock(&my_queue_mutex);
- mystatus = pthread_mutex_destroy(&my_queue_mutex);
- if (mystatus != 0) {
- fprintf(stderr, "mutex_destroy=%d err=%d %p\n",
- mystatus, errno, &my_queue_mutex);
- fflush (stderr);
- }
-
- list_remove(&resthread_list, myself);
- free(myself);
-
- pthread_mutex_unlock(&reslist_mutex);
-
- dbg_printf("RGth %s (tid %d): No more requests"
- "; exiting.\n", myname, gettid());
-
- /* Thread's outta here */
- rg_dec_threads();
- pthread_exit((void *)NULL);
-}
-
-
-/**
- * Start a resgroup thread.
- */
-static int
-spawn_resgroup_thread(const char *name)
-{
- pthread_attr_t attrs;
- resthread_t *newthread = NULL;
- int ret = 0;
-
- pthread_attr_init(&attrs);
- pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED);
- pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
-
- newthread = malloc(sizeof(*newthread));
- if (!newthread)
- return -1;
- memset(newthread, 0, sizeof(*newthread));
-
- newthread->rt_status = RG_STATE_UNINITIALIZED;
- strncpy(newthread->rt_name, name, sizeof(newthread->rt_name));
-
- ret = pthread_create(&newthread->rt_thread, &attrs,
- resgroup_thread_main, (void *)name);
- pthread_attr_destroy(&attrs);
-
- if (ret != 0) {
- free(newthread);
- return ret;
- }
-
- list_insert(&resthread_list, newthread);
-
- return 0;
-}
-
-
-/**
- Spawn a resource group thread if necessary
- */
-int
-spawn_if_needed(const char *resgroupname)
-{
- int ret;
- resthread_t *resgroup = NULL;
-
-retry:
- resgroup = NULL;
- pthread_mutex_lock(&reslist_mutex);
- while (resgroup == NULL) {
- resgroup = find_resthread_byname(resgroupname);
- if (resgroup != NULL)
- break;
-
- ret = spawn_resgroup_thread(resgroupname);
- if (ret == 0)
- continue;
- pthread_mutex_unlock(&reslist_mutex);
-
- return ret;
- }
-
- ret = (resgroup->rt_status == RG_STATE_STOPPING);
-
- pthread_mutex_unlock(&reslist_mutex);
- if (!ret && wait_initialize(resgroupname) < 0) {
- goto retry;
- }
-
- return ret;
-}
-
-
-/**
- * Call with mutex locked.
- */
-static resthread_t *
-find_resthread_byname(const char *resgroupname)
-{
- resthread_t *curr = NULL;
-
- if (!resthread_list)
- return NULL;
-
- list_do(&resthread_list, curr) {
- if (!strncmp(resgroupname, curr->rt_name,
- sizeof(curr->rt_name)))
- return curr;
- } while (!list_done(&resthread_list, curr));
-
- return NULL;
-}
-
-
-/**
- * queues a request for a resgroup.
- *
- * @param resgroupname Service name to perform operations on
- * @param request Request to perform
- * @param response_ctx Send response to this file descriptor when
- * this request completes.
- * @param max Don't insert this request if there already
- * are this many requests of this type in the
- * queue.
- * @param arg Argument to the decoder.
- * @param arglen Length of argument.
- * @return -1 on failure, 0 on success, or 1 if
- * the request was dropped.
- * @see rq_queue_request
- */
-int
-rt_enqueue_request(const char *resgroupname, int request,
- msgctx_t *response_ctx,
- int max, uint32_t target, int arg0, int arg1)
-{
- request_t *curr;
- int count = 0, ret;
- resthread_t *resgroup;
-
- if (spawn_if_needed(resgroupname) != 0) {
- /* Usually, we get here if the thread is killing
- stuff. This prevents us from queueing START requests
- while we're exiting */
- return -1;
- }
-
- pthread_mutex_lock(&reslist_mutex);
- resgroup = find_resthread_byname(resgroupname);
- if (resgroup == NULL) {
- /* DOOOOM */
- pthread_mutex_unlock(&reslist_mutex);
- return -1;
- }
-
- /* Main mutex held */
- if (resgroup->rt_request == request)
- count++;
-
- pthread_mutex_lock(resgroup->rt_queue_mutex);
-
- if (request == RG_INIT) {
- /* If we're initializing it, zap the queue if there
- is one */
- purge_all(resgroup->rt_queue);
- } else {
- if (max) {
- list_do(resgroup->rt_queue, curr) {
- if ((int)curr->rr_request == request)
- count++;
- } while (!list_done(resgroup->rt_queue, curr));
-
- if (count >= max) {
- pthread_mutex_unlock(resgroup->rt_queue_mutex);
- pthread_mutex_unlock(&reslist_mutex);
- /*
- * Maximum reached.
- */
- return 1;
- }
- }
- }
-
- if (resgroup->rt_request == RG_RELOCATE) {
- ret = -1;
- switch(request) {
- case RG_RELOCATE:
- case RG_START_REMOTE:
- case RG_START_RECOVER:
- case RG_START:
- case RG_ENABLE:
- send_ret(response_ctx, resgroup->rt_name, RG_EDEADLCK,
- request, 0);
- msg_close(response_ctx);
- msg_free_ctx(response_ctx);
- ret = 0;
- break;
- }
- /* EWOULDBLOCK */
- pthread_mutex_unlock(resgroup->rt_queue_mutex);
- pthread_mutex_unlock(&reslist_mutex);
- logt_print(LOG_DEBUG,
- "Failed to queue %d request for %s: Would block\n",
- request, resgroupname);
- return ret;
- }
-
- if (resgroup->rt_request == RG_START &&
- (request == RG_START_REMOTE || request == RG_START_RECOVER)) {
- send_ret(response_ctx, resgroup->rt_name, RG_EDEADLCK,
- request, 0);
- msg_free_ctx(response_ctx);
- pthread_mutex_unlock(resgroup->rt_queue_mutex);
- pthread_mutex_unlock(&reslist_mutex);
- logt_print(LOG_DEBUG,
- "Failed to queue %d request for %s: Would block\n",
- request, resgroupname);
- return 0;
- }
-
- ret = rq_queue_request(resgroup->rt_queue, resgroup->rt_name,
- request, 0, 0, response_ctx, 0, target,
- arg0, arg1);
- pthread_cond_broadcast(resgroup->rt_queue_cond);
- pthread_mutex_unlock(resgroup->rt_queue_mutex);
- pthread_mutex_unlock(&reslist_mutex);
-
- if (ret < 0)
- return ret;
-
- dbg_printf("Queued request for %d for %s\n", request, resgroupname);
-
- return 0;
-}
diff --git a/rgmanager/src/daemons/sbuf.c b/rgmanager/src/daemons/sbuf.c
deleted file mode 100644
index d98617f..0000000
--- a/rgmanager/src/daemons/sbuf.c
+++ /dev/null
@@ -1,85 +0,0 @@
-#include <string.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <errno.h>
-
-struct _retbuf {
- char *data;
- ssize_t maxsize;
- ssize_t cursize;
- char magic[8];
-};
-
-static char _x_buf_magic[]="m461kz31";
-
-void *
-buf_init(void *buf, size_t len)
-{
- struct _retbuf *b = (struct _retbuf *)buf;
-
- errno = EINVAL;
- if (!len || !buf)
- return NULL;
- if (len < sizeof(*b) + 16)
- return NULL;
-
- memset(b, 0, len);
- b->data = buf + sizeof(*b);
- b->maxsize = len - sizeof (*b);
- b->cursize = 0;
- memcpy(b->magic, _x_buf_magic, sizeof(b->magic));
-
- return buf;
-}
-
-ssize_t
-buf_append(void *buf, char *info)
-{
- struct _retbuf *b = (struct _retbuf *)buf;
- ssize_t len;
-
- errno = EINVAL;
- if (!buf)
- return -1;
- if (memcmp(b->magic, _x_buf_magic, sizeof(b->magic)))
- return -1;
- if (!info)
- return 0;
- len = strlen(info);
- if (!len)
- return 0;
-
- errno = ENOSPC;
- if (b->maxsize - b->cursize < len)
- return -1;
-
- memcpy(&(b->data[b->cursize]), info, len);
- b->cursize += len;
- return len;
-}
-
-char *
-buf_data(void *buf)
-{
- struct _retbuf *b = (struct _retbuf *)buf;
- errno = EINVAL;
- if (!buf)
- return NULL;
- if (memcmp(b->magic, _x_buf_magic, sizeof(b->magic)))
- return NULL;
- return ((struct _retbuf *)buf)->data;
-}
-
-
-int
-buf_finished(void *buf)
-{
- struct _retbuf *b = (struct _retbuf *)buf;
- errno = EINVAL;
- if (!buf)
- return -1;
- if (memcmp(b->magic, _x_buf_magic, sizeof(b->magic)))
- return -1;
- memset(b->magic, 0, sizeof(b->magic));
- return 0;
-}
diff --git a/rgmanager/src/daemons/service_op.c b/rgmanager/src/daemons/service_op.c
deleted file mode 100644
index 4b74427..0000000
--- a/rgmanager/src/daemons/service_op.c
+++ /dev/null
@@ -1,359 +0,0 @@
-#include <assert.h>
-#include <platform.h>
-#include <time.h>
-#include <list.h>
-#include <restart_counter.h>
-#include <reslist.h>
-#include <message.h>
-#include <members.h>
-#include <stdio.h>
-#include <string.h>
-#include <resgroup.h>
-#include <logging.h>
-#include <lock.h>
-#include <rg_locks.h>
-#include <ccs.h>
-#include <rg_queue.h>
-#include <msgsimple.h>
-#include <res-ocf.h>
-#include <event.h>
-
-
-/**
- * Send a message to the target node list, one at a time, to start
- * the service. Of course, the target list can be just 1 node.
- */
-int
-service_op_start(char *svcName,
- int *target_list,
- int target_list_len,
- int *new_owner)
-{
- int target;
- int ret, x;
- int excl = 0, dep = 0, fail = 0;
- rg_state_t svcStatus;
-
- if (get_service_state_internal(svcName, &svcStatus) < 0) {
- return RG_EFAIL;
- }
-
- if (svcStatus.rs_state == RG_STATE_FAILED ||
- svcStatus.rs_state == RG_STATE_UNINITIALIZED)
- return RG_EINVAL;
-
- for (x = 0; x < target_list_len; x++) {
-
- target = target_list[x];
- ret = svc_start_remote(svcName, RG_START_REMOTE,
- target);
- switch (ret) {
- case RG_ERUN:
- /* Someone stole the service while we were
- trying to start it */
- get_rg_state_local(svcName, &svcStatus);
- if (new_owner)
- *new_owner = svcStatus.rs_owner;
- return 0;
- case RG_EEXCL:
- ++excl;
- continue;
- case RG_EDEPEND:
- ++dep;
- continue;
- case RG_EFAIL:
- case RG_EDEADLCK:
- ++fail;
- continue;
- case RG_EABORT:
- svc_report_failure(svcName);
- return RG_EFAIL;
- default:
- /* deliberate fallthrough */
- logt_print(LOG_ERR,
- "#61: Invalid reply from member %d during"
- " start operation!\n", target);
- case RG_NO:
- /* state uncertain */
- logt_print(LOG_CRIT, "State Uncertain: svc:%s "
- "nid:%d req:%s ret:%d\n", svcName,
- target, rg_req_str(RG_START_REMOTE), ret);
- return 0;
- case 0:
- if (new_owner)
- *new_owner = target;
- logt_print(LOG_NOTICE, "Service %s is now running "
- "on member %d\n", svcName, (int)target);
- return 0;
- }
- }
-
- ret = RG_EFAIL;
- if (excl == target_list_len)
- ret = RG_EEXCL;
- else if (dep == target_list_len)
- ret = RG_EDEPEND;
-
- logt_print(LOG_INFO, "Start failed; node reports: %d failures, "
- "%d exclusive, %d dependency errors\n", fail, excl, dep);
- return ret;
-}
-
-
-int
-service_op_stop(char *svcName, int do_disable, int event_type)
-{
- SmMessageSt msg;
- int msg_ret;
- msgctx_t ctx;
- rg_state_t svcStatus;
- int msgtarget = my_id();
-
- /* Build the message header */
- msg.sm_hdr.gh_magic = GENERIC_HDR_MAGIC;
- msg.sm_hdr.gh_command = RG_ACTION_REQUEST;
- msg.sm_hdr.gh_arg1 = RG_ACTION_MASTER;
- msg.sm_hdr.gh_length = sizeof (SmMessageSt);
-
- msg.sm_data.d_action = ((!do_disable) ? RG_STOP:RG_DISABLE);
-
- if (msg.sm_data.d_action == RG_STOP && event_type == EVENT_USER)
- msg.sm_data.d_action = RG_STOP_USER;
-
- strncpy(msg.sm_data.d_svcName, svcName,
- sizeof(msg.sm_data.d_svcName));
- msg.sm_data.d_ret = 0;
- msg.sm_data.d_svcOwner = 0;
-
- /* Open a connection to the local node - it will decide what to
- do in this case. XXX inefficient; should queue requests
- locally and immediately forward requests otherwise */
-
- if (get_service_state_internal(svcName, &svcStatus) < 0)
- return RG_EFAIL;
- if (svcStatus.rs_owner > 0) {
- if (member_online(svcStatus.rs_owner)) {
- msgtarget = svcStatus.rs_owner;
- } else {
- /* If the owner is not online,
- mark the service as 'stopped' but
- otherwise, do nothing.
- */
- return svc_stop(svcName, RG_STOP);
- }
- }
-
- if (msg_open(MSG_CLUSTER, msgtarget, RG_PORT, &ctx, 2 * cluster_timeout)< 0) {
- logt_print(LOG_ERR,
- "#58: Failed opening connection to member #%d\n",
- my_id());
- return -1;
- }
-
- /* Encode */
- swab_SmMessageSt(&msg);
-
- /* Send stop message to the other node */
- if (msg_send(&ctx, &msg, sizeof (SmMessageSt)) <
- (int)sizeof (SmMessageSt)) {
- logt_print(LOG_ERR, "Failed to send complete message\n");
- msg_close(&ctx);
- return -1;
- }
-
- /* Check the response */
- do {
- msg_ret = msg_receive(&ctx, &msg,
- sizeof (SmMessageSt), 10);
- if ((msg_ret == -1 && errno != ETIMEDOUT) ||
- (msg_ret > 0)) {
- break;
- }
- } while(1);
-
- if (msg_ret != sizeof (SmMessageSt)) {
- logt_print(LOG_WARNING, "Strange response size: %d vs %d\n",
- msg_ret, (int)sizeof(SmMessageSt));
- return 0; /* XXX really UNKNOWN */
- }
-
- /* Got a valid response from other node. */
- msg_close(&ctx);
-
- /* Decode */
- swab_SmMessageSt(&msg);
-
- return msg.sm_data.d_ret;
-}
-
-
-int
-service_op_convalesce(const char *svcName)
-{
- SmMessageSt msg;
- int msg_ret;
- msgctx_t ctx;
- rg_state_t svcStatus;
- int msgtarget = my_id();
-
- /* Build the message header */
- msg.sm_hdr.gh_magic = GENERIC_HDR_MAGIC;
- msg.sm_hdr.gh_command = RG_ACTION_REQUEST;
- msg.sm_hdr.gh_arg1 = RG_ACTION_MASTER;
- msg.sm_hdr.gh_length = sizeof (SmMessageSt);
-
- msg.sm_data.d_action = RG_CONVALESCE;
-
- strncpy(msg.sm_data.d_svcName, svcName,
- sizeof(msg.sm_data.d_svcName));
- msg.sm_data.d_ret = 0;
- msg.sm_data.d_svcOwner = 0;
-
- /* Open a connection to the local node - it will decide what to
- do in this case. XXX inefficient; should queue requests
- locally and immediately forward requests otherwise */
-
- if (get_service_state_internal(svcName, &svcStatus) < 0)
- return RG_EFAIL;
- if (svcStatus.rs_owner > 0) {
- if (member_online(svcStatus.rs_owner)) {
- msgtarget = svcStatus.rs_owner;
- } else {
- /* If the owner is not online,
- mark the service as 'stopped' but
- otherwise, do nothing.
- */
- return svc_stop(svcName, RG_STOP);
- }
- }
-
- if (msg_open(MSG_CLUSTER, msgtarget, RG_PORT, &ctx, 2 * cluster_timeout)< 0) {
- logt_print(LOG_ERR,
- "#58: Failed opening connection to member #%d\n",
- my_id());
- return -1;
- }
-
- /* Encode */
- swab_SmMessageSt(&msg);
-
- /* Send stop message to the other node */
- if (msg_send(&ctx, &msg, sizeof (SmMessageSt)) <
- (int)sizeof (SmMessageSt)) {
- logt_print(LOG_ERR, "Failed to send complete message\n");
- msg_close(&ctx);
- return -1;
- }
-
- /* Check the response */
- do {
- msg_ret = msg_receive(&ctx, &msg,
- sizeof (SmMessageSt), 10);
- if ((msg_ret == -1 && errno != ETIMEDOUT) ||
- (msg_ret > 0)) {
- break;
- }
- } while(1);
-
- if (msg_ret != sizeof (SmMessageSt)) {
- logt_print(LOG_WARNING, "Strange response size: %d vs %d\n",
- msg_ret, (int)sizeof(SmMessageSt));
- return 0; /* XXX really UNKNOWN */
- }
-
- /* Got a valid response from other node. */
- msg_close(&ctx);
-
- /* Decode */
- swab_SmMessageSt(&msg);
-
- return msg.sm_data.d_ret;
-}
-
-
-/*
- service_op_migrate() - send a virtual machine to another host
- in the cluster
- */
-int
-service_op_migrate(char *svcName,
- int target_node)
-{
- SmMessageSt msg;
- int msg_ret;
- msgctx_t ctx;
- rg_state_t svcStatus;
- int msgtarget = my_id();
-
- /* Build the message header */
- msg.sm_hdr.gh_magic = GENERIC_HDR_MAGIC;
- msg.sm_hdr.gh_command = RG_ACTION_REQUEST;
- msg.sm_hdr.gh_arg1 = RG_ACTION_MASTER;
- msg.sm_hdr.gh_length = sizeof (SmMessageSt);
-
- msg.sm_data.d_action = RG_MIGRATE;
-
- strncpy(msg.sm_data.d_svcName, svcName,
- sizeof(msg.sm_data.d_svcName));
-
- msg.sm_data.d_ret = 0;
- msg.sm_data.d_svcOwner = target_node;
-
- /* Open a connection to the local node - it will decide what to
- do in this case. XXX inefficient; should queue requests
- locally and immediately forward requests otherwise */
-
- if (get_service_state_internal(svcName, &svcStatus) < 0)
- return RG_EFAIL;
- if (svcStatus.rs_owner > 0) {
- if (member_online(svcStatus.rs_owner)) {
- msgtarget = svcStatus.rs_owner;
- }
-
- if (msgtarget <= 0) {
- return RG_EFAIL;
- }
- }
-
- if (msg_open(MSG_CLUSTER, msgtarget, RG_PORT, &ctx, 2)< 0) {
- logt_print(LOG_ERR,
- "#58: Failed opening connection to member #%d\n",
- my_id());
- return -1;
- }
-
- /* Encode */
- swab_SmMessageSt(&msg);
-
- /* Send stop message to the other node */
- if (msg_send(&ctx, &msg, sizeof (SmMessageSt)) <
- (int)sizeof (SmMessageSt)) {
- logt_print(LOG_ERR, "Failed to send complete message\n");
- msg_close(&ctx);
- return -1;
- }
-
- /* Check the response */
- do {
- msg_ret = msg_receive(&ctx, &msg,
- sizeof (SmMessageSt), 10);
- if ((msg_ret == -1 && errno != ETIMEDOUT) ||
- (msg_ret > 0)) {
- break;
- }
- } while(1);
-
- if (msg_ret != sizeof (SmMessageSt)) {
- logt_print(LOG_WARNING, "Strange response size: %d vs %d\n",
- msg_ret, (int)sizeof(SmMessageSt));
- return 0; /* XXX really UNKNOWN */
- }
-
- /* Got a valid response from other node. */
- msg_close(&ctx);
-
- /* Decode */
- swab_SmMessageSt(&msg);
-
- return msg.sm_data.d_ret;
-}
diff --git a/rgmanager/src/daemons/slang_event.c b/rgmanager/src/daemons/slang_event.c
deleted file mode 100644
index 45110a3..0000000
--- a/rgmanager/src/daemons/slang_event.c
+++ /dev/null
@@ -1,1468 +0,0 @@
-/**
- @file S/Lang event handling & intrinsic functions + vars
- */
-#include <platform.h>
-#include <resgroup.h>
-#include <list.h>
-#include <restart_counter.h>
-#include <reslist.h>
-#include <logging.h>
-#include <members.h>
-#include <assert.h>
-#include <event.h>
-#include <groups.h>
-#include <fo_domain.h>
-
-#include <stdio.h>
-#include <string.h>
-#define HAVE_LONG_LONG
-#include <slang.h>
-#include <sys/syslog.h>
-#include <malloc.h>
-#include <logging.h>
-#include <sets.h>
-
-static int __sl_initialized = 0;
-
-static char **_service_list = NULL;
-static int _service_list_len = 0;
-
-char **get_service_names(int *len); /* from groups.c */
-void push_int_array(int *stuff, int len);
-
-
-/* ================================================================
- * Node states
- * ================================================================ */
-static const int
- _ns_online = 1,
- _ns_offline = 0;
-
-/* ================================================================
- * Event information
- * ================================================================ */
-static const int
- _ev_none = EVENT_NONE,
- _ev_node = EVENT_NODE,
- _ev_service = EVENT_RG,
- _ev_config = EVENT_CONFIG,
- _ev_user = EVENT_USER;
-
-static const int
- _rg_fail = RG_EFAIL,
- _rg_success = RG_ESUCCESS,
- _rg_edomain = RG_EDOMAIN,
- _rg_edepend = RG_EDEPEND,
- _rg_eabort = RG_EABORT,
- _rg_einval = RG_EINVAL,
- _rg_erun = RG_ERUN;
-
-static int
- _stop_processing = 0,
- _my_node_id = 0,
- _node_state = 0,
- _node_id = 0,
- _node_clean = 0,
- _service_owner = 0,
- _service_last_owner = 0,
- _service_restarts_exceeded = 0,
- _user_request = 0,
- _user_arg1 = 0,
- _user_arg2 = 0,
- _user_return = 0,
- _rg_err = 0,
- _event_type = 0;
-
-static char
- *_node_name = NULL,
- *_service_name = NULL,
- *_service_state = NULL,
- *_rg_err_str = (char *)"No Error";
-
-static int
- _user_enable = RG_ENABLE,
- _user_disable = RG_DISABLE,
- _user_stop = RG_STOP_USER, /* From clusvcadm */
- _user_relo = RG_RELOCATE,
- _user_restart = RG_RESTART,
- _user_migrate = RG_MIGRATE,
- _user_freeze = RG_FREEZE,
- _user_unfreeze = RG_UNFREEZE,
- _user_convalesce = RG_CONVALESCE;
-
-
-SLang_Intrin_Var_Type rgmanager_vars[] =
-{
- /* Log levels (constants) */
-
- /* Node state information */
- MAKE_VARIABLE((char *)"NODE_ONLINE", &_ns_online, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"NODE_OFFLINE", &_ns_offline, SLANG_INT_TYPE, 1),
-
- /* Node event information */
- MAKE_VARIABLE((char *)"node_self", &_my_node_id, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"node_state", &_node_state, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"node_id", &_node_id, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"node_name", &_node_name, SLANG_STRING_TYPE,1),
- MAKE_VARIABLE((char *)"node_clean", &_node_clean, SLANG_INT_TYPE, 1),
-
- /* Service event information */
- MAKE_VARIABLE((char *)"service_name", &_service_name, SLANG_STRING_TYPE,1),
- MAKE_VARIABLE((char *)"service_state", &_service_state,SLANG_STRING_TYPE,1),
- MAKE_VARIABLE((char *)"service_owner", &_service_owner,SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"service_last_owner", &_service_last_owner,
- SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"service_restarts_exceeded", &_service_restarts_exceeded,
- SLANG_INT_TYPE, 1),
-
- /* User event information */
- MAKE_VARIABLE((char *)"user_request", &_user_request, SLANG_INT_TYPE,1),
- MAKE_VARIABLE((char *)"user_arg1", &_user_arg1, SLANG_INT_TYPE,1),
- MAKE_VARIABLE((char *)"user_arg2", &_user_arg2, SLANG_INT_TYPE,1),
- MAKE_VARIABLE((char *)"user_service", &_service_name, SLANG_STRING_TYPE,1),
- MAKE_VARIABLE((char *)"user_target", &_service_owner,SLANG_INT_TYPE, 1),
- /* Return code to user requests; i.e. clusvcadm */
- MAKE_VARIABLE((char *)"user_return", &_user_return, SLANG_INT_TYPE, 0),
-
- /* General event information */
- MAKE_VARIABLE((char *)"event_type", &_event_type, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"EVENT_NONE", &_ev_none, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"EVENT_NODE", &_ev_node, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"EVENT_CONFIG", &_ev_config, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"EVENT_SERVICE", &_ev_service, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"EVENT_USER", &_ev_user, SLANG_INT_TYPE, 1),
-
- /* User request constants */
- MAKE_VARIABLE((char *)"USER_ENABLE", &_user_enable, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"USER_DISABLE", &_user_disable, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"USER_STOP", &_user_stop, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"USER_RELOCATE", &_user_relo, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"USER_RESTART", &_user_restart, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"USER_MIGRATE", &_user_migrate, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"USER_FREEZE", &_user_freeze, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"USER_UNFREEZE", &_user_unfreeze,SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"USER_CONVALESCE",&_user_convalesce,SLANG_INT_TYPE, 1),
-
- /* Errors */
- MAKE_VARIABLE((char *)"rg_error", &_rg_err, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"rg_error_string",&_rg_err_str, SLANG_STRING_TYPE,1),
-
- /* From constants.c */
- MAKE_VARIABLE((char *)"FAIL", &_rg_fail, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"SUCCESS", &_rg_success, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"ERR_ABORT", &_rg_eabort, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"ERR_INVALID", &_rg_einval, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"ERR_DEPEND", &_rg_edepend, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"ERR_DOMAIN", &_rg_edomain, SLANG_INT_TYPE, 1),
- MAKE_VARIABLE((char *)"ERR_RUNNING", &_rg_erun, SLANG_INT_TYPE, 1),
-
- SLANG_END_INTRIN_VAR_TABLE
-};
-
-
-#define rg_error(errortype) \
-do { \
- _rg_err = errortype; \
- _rg_err_str = ##errortype; \
-} while(0)
-
-
-int
-get_service_state_internal(const char *svcName, rg_state_t *svcStatus)
-{
- struct dlm_lksb lock;
- char buf[32];
-
- get_rg_state_local(svcName, svcStatus);
- if (svcStatus->rs_state == RG_STATE_UNINITIALIZED) {
- if (rg_lock(svcName, &lock) < 0) {
- errno = ENOLCK;
- return -1;
- }
-
- if (get_rg_state(svcName, svcStatus) < 0) {
- errno = ENOENT;
- rg_unlock(&lock);
- return -1;
- }
-
- if (get_service_property(svcName, "autostart",
- buf, sizeof(buf)) == 0) {
- if (buf[0] == '0' || !strcasecmp(buf, "no")) {
- svcStatus->rs_state = RG_STATE_DISABLED;
- } else {
- svcStatus->rs_state = RG_STATE_STOPPED;
- }
- }
-
- set_rg_state(svcName, svcStatus);
-
- rg_unlock(&lock);
- }
-
- return 0;
-}
-
-
-/*
- (rte, restarts, last_owner, owner, state) =
- service_status(servicename)
-
-For extra information (flags, transition time)
- (transition_time, flags, rte, restarts, last_owner,
- owner, state) =
- service_status(servicename, 1);
- */
-static void
-sl_service_status(void)
-{
- char *svcName = NULL;
- char *state_str;
- rg_state_t svcStatus;
- int restarts_exceeded = 0;
- int nargs = 0, t = 0, extra = 0, flags = 0;
- unsigned long long mtime;
-
- nargs = SLang_Num_Function_Args;
-
- /* Takes one or two args */
- if (nargs <= 0 || nargs > 2) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: Wrong # of args (%d), must be 1 or 2\n",
- __FUNCTION__,
- nargs);
- return;
- }
-
- if (nargs == 2) {
- t = SLang_peek_at_stack();
- if (t != SLANG_INT_TYPE) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: expected type %d got %d\n",
- __FUNCTION__, SLANG_INT_TYPE, t);
- return;
- }
-
- if (SLang_pop_integer(&extra) < 0) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: Failed to pop integer from stack!\n",
- __FUNCTION__);
- return;
- }
- }
-
- t = SLang_peek_at_stack();
- if (t != SLANG_STRING_TYPE) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: expected type %d got %d\n",
- __FUNCTION__,
- SLANG_STRING_TYPE, t);
- return;
- }
-
- if (SLpop_string(&svcName) < 0) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: Failed to pop string from stack!\n",
- __FUNCTION__);
- return;
- }
-
- /* Ok, got our parameters */
-
- if (get_service_state_internal(svcName, &svcStatus) < 0) {
- SLang_verror(SL_RunTime_Error,
- (char *)"%s: Failed to get status for %s",
- __FUNCTION__,
- svcName);
- goto out_free;
- }
-
- if (extra) {
- /* push transition time and flags on to the stack */
-
- mtime = (unsigned long long)svcStatus.rs_transition;
- if (SLang_push_ulong_long(mtime) < 0) {
- SLang_verror(SL_RunTime_Error,
- (char *)"%s: Failed to push mtime %s",
- __FUNCTION__,
- svcName);
- goto out_free;
- }
-
- flags = (int)svcStatus.rs_flags;
- if (SLang_push_integer(flags) < 0) {
- SLang_verror(SL_RunTime_Error,
- (char *)"%s: Failed to push flags %s",
- __FUNCTION__,
- svcName);
- goto out_free;
- }
- }
-
- restarts_exceeded = check_restart(svcName);
- if (SLang_push_integer(restarts_exceeded) < 0) {
- SLang_verror(SL_RunTime_Error,
- (char *)"%s: Failed to push restarts_exceeded %s",
- __FUNCTION__,
- svcName);
- goto out_free;
- }
-
- if (SLang_push_integer(svcStatus.rs_restarts) < 0) {
- SLang_verror(SL_RunTime_Error,
- (char *)"%s: Failed to push restarts for %s",
- __FUNCTION__,
- svcName);
- goto out_free;
- }
-
- if (SLang_push_integer(svcStatus.rs_last_owner) < 0) {
- SLang_verror(SL_RunTime_Error,
- (char *)"%s: Failed to push last owner of %s",
- __FUNCTION__,
- svcName);
- goto out_free;
- }
-
- switch(svcStatus.rs_state) {
- case RG_STATE_DISABLED:
- case RG_STATE_STOPPED:
- case RG_STATE_FAILED:
- case RG_STATE_RECOVER:
- case RG_STATE_ERROR:
- /* There is no owner for these states. Ever. */
- svcStatus.rs_owner = -1;
- }
-
- if (SLang_push_integer(svcStatus.rs_owner) < 0) {
- SLang_verror(SL_RunTime_Error,
- (char *)"%s: Failed to push owner of %s",
- __FUNCTION__,
- svcName);
- goto out_free;
- }
-
- if (svcStatus.rs_flags & RG_FLAG_FROZEN) {
- /* Special case: "frozen" is a flag, but user scripts should
- treat it as a state. */
- state_str = strdup(rg_flag_str(RG_FLAG_FROZEN));
- } else {
- state_str = strdup(rg_state_str(svcStatus.rs_state));
- }
-
- if (!state_str) {
- SLang_verror(SL_RunTime_Error,
- (char *)"%s: Failed to duplicate state of %s",
- __FUNCTION__,
- svcName);
- goto out_free;
- }
-
- if (SLang_push_malloced_string(state_str) < 0) {
- SLang_verror(SL_RunTime_Error,
- (char *)"%s: Failed to push state of %s",
- __FUNCTION__,
- svcName);
- free(state_str);
- }
-
-out_free:
- if (svcName)
- free(svcName);
-}
-
-
-/* These can be done by the master node */
-static int
-sl_service_freeze(char *svcName)
-{
- return svc_freeze(svcName);
-}
-
-
-static int
-sl_service_unfreeze(const char *svcName)
-{
- return svc_unfreeze(svcName);
-}
-
-
-/**
- (nofailback, restricted, ordered, nodelist) = service_domain_info(svcName);
- */
-static void
-sl_domain_info(const char *svcName)
-{
- int *nodelist = NULL, listlen;
- char buf[64];
- int flags = 0;
-
- if (get_service_property(svcName, "domain", buf, sizeof(buf)) < 0) {
- /* no nodes */
- SLang_push_integer(0);
-
- /* no domain? */
-/*
- str = strdup("none");
- if (SLang_push_malloced_string(str) < 0) {
- free(state_str);
- return;
- }
-*/
-
- /* not ordered */
- SLang_push_integer(0);
- /* not restricted */
- SLang_push_integer(0);
- /* nofailback not set */
- SLang_push_integer(0);
- }
-
- if (node_domain_set_safe(buf, &nodelist, &listlen, &flags) < 0) {
- SLang_push_integer(0);
- SLang_push_integer(0);
- SLang_push_integer(0);
- SLang_push_integer(0);
- return;
- }
-
- SLang_push_integer(!!(flags & FOD_NOFAILBACK));
- SLang_push_integer(!!(flags & FOD_RESTRICTED));
- SLang_push_integer(!!(flags & FOD_ORDERED));
-
- push_int_array(nodelist, listlen);
- free(nodelist);
-
-/*
- str = strdup(buf);
- if (SLang_push_malloced_string(str) < 0) {
- free(state_str);
- return;
- }
-*/
-}
-
-
-static int
-get_int_array(int **nodelist, int *len)
-{
- SLang_Array_Type *a = NULL;
- SLindex_Type i;
- int *nodes = NULL, t, ret = -1;
-
- if (!nodelist || !len)
- return -1;
-
- t = SLang_peek_at_stack();
- if (t == SLANG_INT_TYPE) {
-
- nodes = malloc(sizeof(int) * 1);
- if (!nodes)
- goto out;
- if (SLang_pop_integer(&nodes[0]) < 0)
- goto out;
-
- *len = 1;
- ret = 0;
-
- } else if (t == SLANG_ARRAY_TYPE) {
- if (SLang_pop_array_of_type(&a, SLANG_INT_TYPE) < 0)
- goto out;
- if (a->num_dims > 1)
- goto out;
- if (a->dims[0] < 0)
- goto out;
- nodes = malloc(sizeof(int) * a->dims[0]);
- if (!nodes)
- goto out;
- for (i = 0; i < a->dims[0]; i++)
- SLang_get_array_element(a, &i, &nodes[i]);
-
- *len = a->dims[0];
- ret = 0;
- }
-
-out:
- if (a)
- SLang_free_array(a);
- if (ret == 0) {
- *nodelist = nodes;
- } else {
- if (nodes)
- free(nodes);
- }
-
- return ret;
-}
-
-
-/**
- get_service_property(service_name, property)
- */
-static void
-sl_service_property(char *svcName, char *prop)
-{
- char buf[96];
- char *ret;
-
- if (get_service_property(svcName, prop, buf, sizeof(buf)) < 0)
- return;
-
- ret = strdup(buf);
- if (!ret) {
- SLang_verror(SL_RunTime_Error,
- (char *)"%s: Failed to duplicate %s property of %s",
- __FUNCTION__, prop, svcName);
- return;
- }
-
- if (SLang_push_malloced_string(ret) < 0) {
- SLang_verror(SL_RunTime_Error,
- (char *)"%s: Failed to push %s property of %s",
- __FUNCTION__, prop, svcName);
- free(ret);
- }
-}
-
-
-/**
- usage:
-
- service_convalesce(name);
- */
-static int
-sl_convalesce_service(const char *svcname)
-{
- return service_op_convalesce(svcname);
-}
-
-
-/**
- usage:
-
- stop_service(name, disable_flag);
- */
-static int
-sl_stop_service(void)
-{
- char *svcname = NULL;
- int nargs, t, ret = -1;
- int do_disable = 0;
-
- nargs = SLang_Num_Function_Args;
-
- /* Takes one or two args */
- if (nargs <= 0 || nargs > 2) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: Wrong # of args (%d), must be 1 or 2\n",
- __FUNCTION__,
- nargs);
- return -1;
- }
-
- if (nargs == 2) {
- t = SLang_peek_at_stack();
- if (t != SLANG_INT_TYPE) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: expected type %d got %d\n",
- __FUNCTION__, SLANG_INT_TYPE, t);
- goto out;
- }
-
- if (SLang_pop_integer(&do_disable) < 0) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: Failed to pop integer from stack!\n",
- __FUNCTION__);
- goto out;
- }
-
- --nargs;
- }
-
- if (nargs == 1) {
- t = SLang_peek_at_stack();
- if (t != SLANG_STRING_TYPE) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: expected type %d got %d\n",
- __FUNCTION__,
- SLANG_STRING_TYPE, t);
- goto out;
- }
-
- if (SLpop_string(&svcname) < 0) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: Failed to pop string from stack!\n",
- __FUNCTION__);
- goto out;
- }
- }
-
- /* TODO: Meat of function goes here */
- ret = service_op_stop(svcname, do_disable, _event_type);
-out:
- if (svcname)
- free(svcname);
- _user_return = ret;
- return ret;
-}
-
-
-/**
- usage:
-
- start_service(name, <array>ordered_node_list_allowed,
- <array>node_list_illegal)
- */
-static int
-sl_start_service(void)
-{
- char *svcname = NULL;
- int *pref_list = NULL, pref_list_len = 0;
- int *illegal_list = NULL, illegal_list_len = 0;
- int nargs, t, newowner = 0, ret = -1;
-
- nargs = SLang_Num_Function_Args;
-
- /* Takes one, two, or three */
- if (nargs <= 0 || nargs > 3) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: Wrong # of args (%d), must be 1 or 2\n",
- __FUNCTION__, nargs);
- return -1;
- }
-
- if (nargs == 3) {
- if (get_int_array(&illegal_list, &illegal_list_len) < 0)
- goto out;
- --nargs;
- }
-
- if (nargs == 2) {
- if (get_int_array(&pref_list, &pref_list_len) < 0)
- goto out;
- --nargs;
- }
-
- if (nargs == 1) {
- /* Just get the service name */
- t = SLang_peek_at_stack();
- if (t != SLANG_STRING_TYPE) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: expected type %d got %d\n",
- __FUNCTION__,
- SLANG_STRING_TYPE, t);
- goto out;
- }
-
- if (SLpop_string(&svcname) < 0)
- goto out;
- }
-
- /* TODO: Meat of function goes here */
- ret = service_op_start(svcname, pref_list,
- pref_list_len, &newowner);
-
- if (ret == 0 && newowner > 0)
- ret = newowner;
-out:
- if (svcname)
- free(svcname);
- if (illegal_list)
- free(illegal_list);
- if (pref_list)
- free(pref_list);
- _user_return = ret;
- return ret;
-}
-
-
-static int
-sl_migrate_service(void)
-{
- char *svcname = NULL;
- int target_node = 0;
- int nargs, t, ret = -1;
-
- nargs = SLang_Num_Function_Args;
-
- /* Takes one, two, or three */
- if (nargs != 2) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: Wrong # of args (%d), must be 2: service_name target_node\n",
- __FUNCTION__, nargs);
- return -1;
- }
-
- t = SLang_peek_at_stack();
- if (t != SLANG_INT_TYPE) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: expected type %d got %d\n",
- __FUNCTION__, SLANG_INT_TYPE, t);
- goto out;
- }
-
- if (SLang_pop_integer(&target_node) < 0) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: Failed to pop integer from stack!\n",
- __FUNCTION__);
- goto out;
- }
-
- t = SLang_peek_at_stack();
- if (t != SLANG_STRING_TYPE) {
- SLang_verror(SL_Syntax_Error,
- (char *)"%s: expected type %d got %d\n",
- __FUNCTION__,
- SLANG_STRING_TYPE, t);
- goto out;
- }
-
- if (SLpop_string(&svcname) < 0) {
- goto out;
- }
-
- ret = service_op_migrate(svcname, target_node);
-
- if (ret == 0)
- ret = target_node;
-out:
- if (svcname)
- free(svcname);
- _user_return = ret;
- return ret;
-}
-
-
-/* Take an array of integers given its length and
- push it on to the S/Lang stack */
-void
-push_int_array(int *stuff, int len)
-{
- SLindex_Type arrlen, x;
- SLang_Array_Type *arr;
- int i;
-
- arrlen = len;
- arr = SLang_create_array(SLANG_INT_TYPE, 0, NULL, &arrlen, 1);
- if (!arr)
- return;
-
- x = 0;
- for (x = 0; x < len; x++) {
- i = stuff[x];
- SLang_set_array_element(arr, &x, &i);
- }
- SLang_push_array(arr, 1);
-}
-
-
-/*
- Returns an array of rgmanager-visible nodes online. How cool is that?
- */
-static void
-sl_nodes_online(void)
-{
- int x, *nodes = NULL, nodecount = 0;
-
- x = member_online_set(&nodes, &nodecount);
- if (x < 0 || !nodes || !nodecount)
- return;
-
- push_int_array(nodes, nodecount);
- free(nodes);
-}
-
-
-/*
- Returns an array of rgmanager-defined services, in type:name format
- We allocate/kill this list *once* per event to ensure we don't leak
- memory
- */
-static void
-sl_service_list(void)
-{
- SLindex_Type svccount = _service_list_len, x = 0;
- SLang_Array_Type *svcarray;
-
- svcarray = SLang_create_array(SLANG_STRING_TYPE, 0, NULL, &svccount, 1);
- if (!svcarray)
- return;
-
- for (; x < _service_list_len; x++)
- SLang_set_array_element(svcarray, &x, &_service_list[x]);
-
- SLang_push_array(svcarray, 1);
-}
-
-
-/* s_union hook (see sets.c) */
-static void
-sl_union(void)
-{
- int *arr1 = NULL, a1len = 0;
- int *arr2 = NULL, a2len = 0;
- int *ret = NULL, retlen = 0;
- int nargs = SLang_Num_Function_Args;
-
- if (nargs != 2)
- return;
-
- /* Remember: args on the stack are reversed */
- get_int_array(&arr2, &a2len);
- get_int_array(&arr1, &a1len);
- s_union(arr1, a1len, arr2, a2len, &ret, &retlen);
- push_int_array(ret, retlen);
- if (arr1)
- free(arr1);
- if (arr2)
- free(arr2);
- if (ret)
- free(ret);
- return;
-}
-
-
-/* s_intersection hook (see sets.c) */
-static void
-sl_intersection(void)
-{
- int *arr1 = NULL, a1len = 0;
- int *arr2 = NULL, a2len = 0;
- int *ret = NULL, retlen = 0;
- int nargs = SLang_Num_Function_Args;
-
- if (nargs != 2)
- return;
-
- /* Remember: args on the stack are reversed */
- get_int_array(&arr2, &a2len);
- get_int_array(&arr1, &a1len);
- s_intersection(arr1, a1len, arr2, a2len, &ret, &retlen);
- push_int_array(ret, retlen);
- if (arr1)
- free(arr1);
- if (arr2)
- free(arr2);
- if (ret)
- free(ret);
- return;
-}
-
-
-/* s_delta hook (see sets.c) */
-static void
-sl_delta(void)
-{
- int *arr1 = NULL, a1len = 0;
- int *arr2 = NULL, a2len = 0;
- int *ret = NULL, retlen = 0;
- int nargs = SLang_Num_Function_Args;
-
- if (nargs != 2)
- return;
-
- /* Remember: args on the stack are reversed */
- get_int_array(&arr2, &a2len);
- get_int_array(&arr1, &a1len);
- s_delta(arr1, a1len, arr2, a2len, &ret, &retlen);
- push_int_array(ret, retlen);
- if (arr1)
- free(arr1);
- if (arr2)
- free(arr2);
- if (ret)
- free(ret);
- return;
-}
-
-
-/* s_subtract hook (see sets.c) */
-static void
-sl_subtract(void)
-{
- int *arr1 = NULL, a1len = 0;
- int *arr2 = NULL, a2len = 0;
- int *ret = NULL, retlen = 0;
- int nargs = SLang_Num_Function_Args;
-
- if (nargs != 2)
- return;
-
- /* Remember: args on the stack are reversed */
- get_int_array(&arr2, &a2len);
- get_int_array(&arr1, &a1len);
- s_subtract(arr1, a1len, arr2, a2len, &ret, &retlen);
- push_int_array(ret, retlen);
- if (arr1)
- free(arr1);
- if (arr2)
- free(arr2);
- if (ret)
- free(ret);
- return;
-}
-
-
-/* Shuffle array (see sets.c) */
-static void
-sl_shuffle(void)
-{
- int *arr1 = NULL, a1len = 0;
- int nargs = SLang_Num_Function_Args;
-
- if (nargs != 1)
- return;
-
- /* Remember: args on the stack are reversed */
- get_int_array(&arr1, &a1len);
- s_shuffle(arr1, a1len);
- push_int_array(arr1, a1len);
- if (arr1)
- free(arr1);
- return;
-}
-
-
-/* Converts an int array to a string so we can log it in one shot */
-static int
-array_to_string(char *buf, int buflen, int *array, int arraylen)
-{
- char intbuf[16];
- int x, len, remain = buflen;
-
- memset(intbuf, 0, sizeof(intbuf));
- memset(buf, 0, buflen);
- len = snprintf(buf, buflen - 1, "[ ");
- if (len == buflen)
- return -1;
-
- remain -= len;
- for (x = 0; x < arraylen; x++) {
- len = snprintf(intbuf, sizeof(intbuf) - 1, "%d ", array[x]);
- remain -= len;
- if (remain > 0) {
- strncat(buf, intbuf, len);
- } else {
- return -1;
- }
- }
-
- len = snprintf(intbuf, sizeof(intbuf) - 1 , "]");
- remain -= len;
- if (remain > 0) {
- strncat(buf, intbuf, len);
- } else {
- return -1;
- }
- return (buflen - remain);
-}
-
-
-/**
- Start at the end of the arg list and work backwards, prepending a string.
- This does not support standard logt_print / printf formattting; rather, we
- just allow integers / strings to be mixed on the stack, figure out the
- type, convert it to the right type, and prepend it on to our log message
-
- The last must be a log level, as specified above:
- LOG_DEBUG
- ...
- LOG_EMERG
-
- This matches up with logt_print / syslog mappings in the var table; the above
- are constants in the S/Lang interpreter. Any number of arguments may
- be provided. Examples are:
-
- log(LOG_INFO, "String", 1, "string2");
-
- Result: String1string2
-
- log(LOG_INFO, "String ", 1, " string2");
-
- Result: String 1 string2
-
- */
-static void
-sl_logt_print(int level)
-{
- unsigned long long s_ullval;
- unsigned long s_ulval;
- int t, nargs, len;
- //int level;
- int s_intval;
- char *s_strval;
- int *nodes = 0, nlen = 0;
- char logbuf[512];
- char tmp[256];
- int need_free;
- int remain = sizeof(logbuf)-2;
- SLang_Any_Type *stuff = NULL;
-
- nargs = SLang_Num_Function_Args;
- if (nargs < 1)
- return;
-
- memset(logbuf, 0, sizeof(logbuf));
- memset(tmp, 0, sizeof(tmp));
- logbuf[sizeof(logbuf)-1] = 0;
- logbuf[sizeof(logbuf)-2] = '\n';
-
- while (nargs && (t = SLang_peek_at_stack()) >= 0 && remain) {
- switch(t) {
- case SLANG_ARRAY_TYPE:
- if (get_int_array(&nodes, &nlen) < 0)
- return;
- len = array_to_string(tmp, sizeof(tmp),
- nodes, nlen);
- if (len < 0) {
- free(nodes);
- return;
- }
- free(nodes);
- break;
- case SLANG_ULONG_TYPE:
- if (SLang_pop_ulong(&s_ulval) < 0)
- return;
- len=snprintf(tmp, sizeof(tmp) - 1, "%lu", s_ulval);
- break;
- case SLANG_ULLONG_TYPE:
- if (SLang_pop_ulong_long(&s_ullval) < 0)
- return;
- len=snprintf(tmp, sizeof(tmp) - 1, "%llu", s_ullval);
- break;
- case SLANG_INT_TYPE:
- if (SLang_pop_integer(&s_intval) < 0)
- return;
- len=snprintf(tmp, sizeof(tmp) - 1, "%d", s_intval);
- break;
- case SLANG_STRING_TYPE:
- need_free = 0;
- if (SLpop_string(&s_strval) < 0)
- return;
- len=snprintf(tmp, sizeof(tmp) - 1, "%s", s_strval);
- SLfree(s_strval);
- break;
- default:
- need_free = 0;
- len=snprintf(tmp, sizeof(tmp) - 1,
- "{UnknownType %d}", t);
- SLang_pop_anytype(&stuff);
- if (stuff) {
- SLang_free_anytype(stuff);
- stuff = NULL;
- }
- break;
- }
-
- --nargs;
-
- if (len > remain)
- return;
- remain -= len;
-
- memcpy(&logbuf[remain], tmp, len);
- }
-
-#if 0
- printf("<%d> %s\n", level, &logbuf[remain]);
-#endif
- logt_print(level, "%s", &logbuf[remain]);
- return;
-}
-
-
-/* Logging functions */
-static void
-sl_log_debug(void)
-{
- sl_logt_print(LOG_DEBUG);
-}
-
-
-static void
-sl_log_info(void)
-{
- sl_logt_print(LOG_INFO);
-}
-
-
-static void
-sl_log_notice(void)
-{
- sl_logt_print(LOG_NOTICE);
-}
-
-
-static void
-sl_log_warning(void)
-{
- sl_logt_print(LOG_WARNING);
-}
-
-
-static void
-sl_log_err(void)
-{
- sl_logt_print(LOG_ERR);
-}
-
-
-static void
-sl_log_crit(void)
-{
- sl_logt_print(LOG_CRIT);
-}
-
-
-static void
-sl_log_alert(void)
-{
- sl_logt_print(LOG_ALERT);
-}
-
-
-static void
-sl_log_emerg(void)
-{
- sl_logt_print(LOG_EMERG);
-}
-
-
-static void
-sl_die(void)
-{
- _stop_processing = 1;
- return;
-}
-
-
-static SLang_Intrin_Fun_Type rgmanager_slang[] =
-{
- MAKE_INTRINSIC_0((char *)"nodes_online", sl_nodes_online,
- SLANG_VOID_TYPE),
- MAKE_INTRINSIC_0((char *)"service_list", sl_service_list,
- SLANG_VOID_TYPE),
- MAKE_INTRINSIC_SS((char *)"service_property", sl_service_property,
- SLANG_VOID_TYPE),
- MAKE_INTRINSIC_S((char *)"service_domain_info", sl_domain_info,
- SLANG_VOID_TYPE),
- MAKE_INTRINSIC_0((char *)"service_stop", sl_stop_service,
- SLANG_INT_TYPE),
- MAKE_INTRINSIC_S((char *)"service_convalesce", sl_convalesce_service,
- SLANG_INT_TYPE),
- MAKE_INTRINSIC_0((char *)"service_start", sl_start_service,
- SLANG_INT_TYPE),
- MAKE_INTRINSIC_0((char *)"service_migrate", sl_migrate_service,
- SLANG_INT_TYPE),
- MAKE_INTRINSIC_0((char *)"service_status", sl_service_status,
- SLANG_VOID_TYPE),
- MAKE_INTRINSIC_S((char *)"service_freeze", sl_service_freeze,
- SLANG_INT_TYPE),
- MAKE_INTRINSIC_S((char *)"service_unfreeze", sl_service_unfreeze,
- SLANG_INT_TYPE),
-
- /* Node list manipulation */
- MAKE_INTRINSIC_0((char *)"union", sl_union, SLANG_VOID_TYPE),
- MAKE_INTRINSIC_0((char *)"intersection", sl_intersection,
- SLANG_VOID_TYPE),
- MAKE_INTRINSIC_0((char *)"delta", sl_delta, SLANG_VOID_TYPE),
- MAKE_INTRINSIC_0((char *)"subtract", sl_subtract, SLANG_VOID_TYPE),
- MAKE_INTRINSIC_0((char *)"shuffle", sl_shuffle, SLANG_VOID_TYPE),
-
- /* Logging */
- MAKE_INTRINSIC_0((char *)"debug", sl_log_debug, SLANG_VOID_TYPE),
- MAKE_INTRINSIC_0((char *)"info", sl_log_info, SLANG_VOID_TYPE),
- MAKE_INTRINSIC_0((char *)"notice", sl_log_notice, SLANG_VOID_TYPE),
- MAKE_INTRINSIC_0((char *)"warning", sl_log_warning, SLANG_VOID_TYPE),
- MAKE_INTRINSIC_0((char *)"err", sl_log_err, SLANG_VOID_TYPE),
- MAKE_INTRINSIC_0((char *)"crit", sl_log_crit, SLANG_VOID_TYPE),
- MAKE_INTRINSIC_0((char *)"alert", sl_log_alert, SLANG_VOID_TYPE),
- MAKE_INTRINSIC_0((char *)"emerg", sl_log_emerg, SLANG_VOID_TYPE),
-
- MAKE_INTRINSIC_0((char *)"stop_processing", sl_die, SLANG_VOID_TYPE),
-
- SLANG_END_INTRIN_FUN_TABLE
-};
-
-
-/* Hook for when we generate a script error */
-static void
-rgmanager_slang_error_hook(char *errstr)
-{
- /* Don't just send errstr, because it might contain
- "%s" for example which would result in a crash!
- plus, we like the newline :) */
- logt_print(LOG_ERR, "[S/Lang] %s\n", errstr);
-}
-
-
-
-/* ================================================================
- * S/Lang initialization
- * ================================================================ */
-static int
-do_init_slang(void)
-{
- SLang_init_slang();
- SLang_init_slfile();
-
- if (SLadd_intrin_fun_table(rgmanager_slang, NULL) < 0)
- return 1;
- if (SLadd_intrin_var_table (rgmanager_vars, NULL) < 0)
- return 1;
-
- /* TODO: Make rgmanager S/Lang conformant. Though, it
- might be a poor idea to provide access to all the
- S/Lang libs */
- SLpath_set_load_path((char *)RESOURCE_ROOTDIR);
-
- _my_node_id = my_id();
- __sl_initialized = 1;
-
- SLang_Error_Hook = rgmanager_slang_error_hook;
-
- return 0;
-}
-
-
-/*
- Execute a script / file and return the result to the caller
- Log an error if we receive one.
- */
-static int
-do_slang_run(const char *file, const char *script)
-{
- int ret = 0;
-
- if (file)
- ret = SLang_load_file((char *)file);
- else
- ret = SLang_load_string((char *)script);
-
- if (ret < 0) {
- logt_print(LOG_ERR, "[S/Lang] Script Execution Failure\n");
- SLang_restart(1);
- }
-
- return ret;
-}
-
-
-static int
-S_node_event(const char *file, const char *script, int nodeid,
- int state, int clean)
-{
- int ret;
- cluster_member_list_t *membership = member_list();
-
- _node_name = strdup(memb_id_to_name(membership, nodeid));
- _node_state = state;
- _node_clean = clean;
- _node_id = nodeid;
- free_member_list(membership);
-
- ret = do_slang_run(file, script);
-
- _node_state = 0;
- _node_clean = 0;
- _node_id = 0;
- if (_node_name)
- free(_node_name);
- _node_name = NULL;
-
- return ret;
-}
-
-
-static int
-S_service_event(const char *file, const char *script, char *name,
- int state, int owner, int last_owner)
-{
- char policy[20];
- int ret;
-
- _service_name = name;
- _service_state = (char *)rg_state_str(state);
- _service_owner = owner;
- _service_last_owner = last_owner;
- _service_restarts_exceeded = 0;
-
- switch(state) {
- case RG_STATE_DISABLED:
- case RG_STATE_STOPPED:
- case RG_STATE_FAILED:
- case RG_STATE_ERROR:
- /* There is no owner for these states. Ever. */
- _service_owner = -1;
- break;
- case RG_STATE_RECOVER:
- get_recovery_policy(name, policy, sizeof(policy));
- if (!strcasecmp(policy, "restart")) {
- _service_restarts_exceeded = check_restart(name);
- add_restart(name);
- } else if (!strcasecmp(policy, "relocate")) {
- /* Restart threshold is always exceeded
- * with 'relocate' recovery policy */
- _service_restarts_exceeded = 1;
- }
- _service_owner = -1;
- }
-
- if (_service_restarts_exceeded) {
- clear_restart(name);
- }
-
- ret = do_slang_run(file, script);
-
- _service_name = NULL;
- _service_state = 0;
- _service_owner = 0;
- _service_last_owner = 0;
- _service_restarts_exceeded = 0;
-
- return ret;
-}
-
-
-static int
-S_user_event(const char *file, const char *script, char *name,
- int request, int arg1, int arg2, int target, msgctx_t **ctx)
-{
- int ret = RG_SUCCESS;
-
- _service_name = name;
- _service_owner = target;
- _user_request = request;
- _user_arg1 = arg1;
- _user_arg2 = arg2;
- _user_return = 0;
-
- ret = do_slang_run(file, script);
- if (ret < 0) {
- _user_return = RG_ESCRIPT;
- }
-
- _service_name = NULL;
- _service_owner = 0;
- _user_request = 0;
- _user_arg1 = 0;
- _user_arg2 = 0;
-
- /* XXX Send response code to caller - that 0 should be the
- new service owner, if there is one */
- if (*ctx) {
- if (_user_return > 0) {
- /* sl_start_service() squashes return code and
- node ID into one value. <0 = error, >0 =
- success, return-value == node id running
- service */
- send_ret(*ctx, name, 0, request, _user_return);
- } else {
- /* return value < 0 ... pass directly back;
- don't transpose */
- send_ret(*ctx, name, _user_return, request, 0);
- }
- msg_close(*ctx);
- msg_free_ctx(*ctx);
- *ctx = NULL;
- }
- _user_return = 0;
- return ret;
-}
-
-
-static int
-slang_do_script(event_t *pattern, event_t *ev)
-{
- int ret = 0;
-
- _event_type = ev->ev_type;
-
- switch(ev->ev_type) {
- case EVENT_NODE:
- ret = S_node_event(
- pattern->ev_script_file,
- pattern->ev_script,
- ev->ev.node.ne_nodeid,
- ev->ev.node.ne_state,
- ev->ev.node.ne_clean);
- break;
- case EVENT_RG:
- ret = S_service_event(
- pattern->ev_script_file,
- pattern->ev_script,
- ev->ev.group.rg_name,
- ev->ev.group.rg_state,
- ev->ev.group.rg_owner,
- ev->ev.group.rg_last_owner);
- break;
- case EVENT_USER:
- ret = S_user_event(
- pattern->ev_script_file,
- pattern->ev_script,
- ev->ev.user.u_name,
- ev->ev.user.u_request,
- ev->ev.user.u_arg1,
- ev->ev.user.u_arg2,
- ev->ev.user.u_target,
- &ev->ev.user.u_ctx);
- break;
- default:
- break;
- }
-
- _event_type = EVENT_NONE;
- return ret;
-}
-
-
-
-/**
- Process an event given our event table and the event that
- occurred. Note that the caller is responsible for freeing the
- event - do not free (ev) ...
- */
-int
-slang_process_event(event_table_t *event_table, event_t *ev)
-{
- int x, y;
- event_t *pattern;
-
- if (!__sl_initialized)
- do_init_slang();
-
- /* Get the service list once before processing events */
- if (!_service_list || !_service_list_len)
- _service_list = get_service_names(&_service_list_len);
-
- _stop_processing = 0;
- for (x = 1; x <= event_table->max_prio; x++) {
- list_for(&event_table->entries[x], pattern, y) {
- if (event_match(pattern, ev))
- slang_do_script(pattern, ev);
- if (_stop_processing)
- goto out;
- }
- }
-
- /* Default level = 0 */
- list_for(&event_table->entries[0], pattern, y) {
- if (event_match(pattern, ev))
- slang_do_script(pattern, ev);
- if (_stop_processing)
- goto out;
- }
-
-out:
- /* Free the service list */
- if (_service_list) {
- for(x = 0; x < _service_list_len; x++) {
- free(_service_list[x]);
- }
- free(_service_list);
- _service_list = NULL;
- _service_list_len = 0;
- }
-
- return 0;
-}
diff --git a/rgmanager/src/daemons/test-expand-time.c b/rgmanager/src/daemons/test-expand-time.c
deleted file mode 100644
index 0a15452..0000000
--- a/rgmanager/src/daemons/test-expand-time.c
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <stdio.h>
-#include <time.h>
-
-/* XXX "list_head()", reslist.h should include on its own? */
-#include "list.h"
-/* XXX "restart_counter_t", dtto */
-#include "restart_counter.h"
-
-#include "reslist.h"
-
-int main(int argc, char *argv[])
-{
- char buffer[255];
- char *aux;
- for (;;) {
- printf("Time string: ");
- if (!fgets(buffer, sizeof(buffer), stdin) && feof(stdin))
- break;
- aux = strchr(buffer,'\n');
- if (aux)
- *aux = '\0';
- printf("Expanded : %d\n", expand_time(buffer));
- }
- return EXIT_SUCCESS;
-}
diff --git a/rgmanager/src/daemons/test.c b/rgmanager/src/daemons/test.c
deleted file mode 100644
index b0e326f..0000000
--- a/rgmanager/src/daemons/test.c
+++ /dev/null
@@ -1,450 +0,0 @@
-#include <libxml/parser.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/xpath.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <list.h>
-#include <restart_counter.h>
-#include <reslist.h>
-#include <resgroup.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <pthread.h>
-#include <libgen.h>
-#include <event.h>
-#include <groups.h>
-#include <fo_domain.h>
-
-#ifndef NO_CCS
-#error "Can not be built with CCS support."
-#endif
-
-void res_build_name(char *, size_t, resource_t *);
-
-
-/**
- Tells us if a resource group can be migrated w/o the group.c definition
- XXX replace!
- */
-static int
-test_group_migratory(resource_t **resources, resource_node_t **tree,
- char *groupname)
-{
- resource_node_t *rn;
- resource_t *res;
- int migrate = 0, x, ret = 0;
-
- res = find_root_by_ref(resources, groupname);
- if (!res) {
- /* Nonexistent or non-TL RG cannot be migrated */
- return 0;
- }
-
- for (x = 0; res->r_rule->rr_actions[x].ra_name; x++) {
- if (!strcmp(res->r_rule->rr_actions[x].ra_name,
- "migrate")) {
- migrate = 1;
- break;
- }
- }
-
- if (!migrate)
- goto out_unlock;
-
- list_do(tree, rn) {
- if (rn->rn_resource == res && rn->rn_child) {
- /* TL service w/ children cannot be migrated */
- goto out_unlock;
- }
- } while (!list_done(tree, rn));
-
-
- /* Ok, we have a migrate option to the resource group,
- the resource group has no children, and the resource
- group exists. We're all good */
- ret = 1;
-
-out_unlock:
- return ret;
-}
-
-#define shift() {++argv; --argc;}
-
-#define USAGE_TEST \
- "\ttest <configfile> [args..]\n" \
- "\t\tstart <type> <resource>\n" \
- "\t\tstatus <type> <resource>\n" \
- "\t\tstop <type> <resource>\n" \
- "\n"
-
-#define USAGE_DELTA \
- "\tdelta <configfile1> <configfile2>\n\n"
-
-#define USAGE_RULES \
- "\trules\n\n"
-
-
-void _no_op_mode(int);
-char *agentpath = (char *)RESOURCE_ROOTDIR;
-
-
-static int
-rules_func(int __attribute__((unused)) argc,
- char __attribute__((unused)) **argv)
-{
- resource_rule_t *rulelist = NULL, *currule;
- int rules = 0;
-
- fprintf(stderr,"Running in rules mode.\n");
-
- load_resource_rules(agentpath, &rulelist);
- list_do(&rulelist, currule) {
- ++rules;
- } while (!list_done(&rulelist, currule));
- fprintf(stderr, "Loaded %d resource rules\n",
- rules);
-
- print_resource_rules(&rulelist);
-
- destroy_resource_rules(&rulelist);
-
- return 0;
-}
-
-
-static int
-test_func(int argc, char **argv)
-{
- fod_t *domains = NULL;
- resource_rule_t *rulelist = NULL, *currule;
- resource_t *reslist = NULL, *curres;
- resource_node_t *tree = NULL, *tmp, *rn = NULL;
- int ccsfd, ret = 0, rules = 0;
- event_table_t *events = NULL;
-
- fprintf(stderr,"Running in test mode.\n");
-
- conf_setconfig(argv[1]);
- ccsfd = ccs_lock();
- if (ccsfd < 0) {
- printf("Error parsing %s\n", argv[1]);
- goto out;
- }
-
- load_resource_rules(agentpath, &rulelist);
- load_resource_defaults(ccsfd, &rulelist);
- construct_domains(ccsfd, &domains);
- construct_events(ccsfd, &events);
- load_resources(ccsfd, &reslist, &rulelist);
- build_resource_tree(ccsfd, &tree, &rulelist, &reslist);
-
- shift();
-
- if (argc == 1) {
- /*
- printf("=== Resource XML Rules ===\n");
- list_do(&rulelist, currule) {
- print_resource_rule(currule);
- } while (!list_done(&rulelist, currule));
- */
- list_do(&rulelist, currule) {
- ++rules;
- } while (!list_done(&rulelist, currule));
- fprintf(stderr, "Loaded %d resource rules\n",
- rules);
-
- if (reslist) {
- printf("=== Resources List ===\n");
- print_resources(&reslist);
- }
-
- if (tree) {
- printf("=== Resource Tree ===\n");
- print_resource_tree(&tree);
- }
-
- if (domains) {
- printf("=== Failover Domains ===\n");
- print_domains(&domains);
- }
-
- if (events) {
- printf("=== Event Triggers ===\n");
- print_events(events);
- }
- }
-
- ccs_unlock(ccsfd);
-
- if (argc < 4)
- goto out;
-
- curres = find_resource_by_ref(&reslist, argv[2], argv[3]);
- if (!curres) {
- printf("No resource %s of type %s found\n",
- argv[3], argv[2]);
- goto out;
- }
-
- list_do(&tree, tmp) {
- if (tmp->rn_resource == curres) {
- rn = tmp;
- break;
- }
- } while (!list_done(&tree, tmp));
-
- if (!strcmp(argv[1], "start")) {
- printf("Starting %s...\n", argv[3]);
-
- if (res_start(&tree, curres, NULL)) {
- printf("Failed to start %s\n", argv[3]);
- ret = -1;
- goto out;
- }
- printf("Start of %s complete\n", argv[3]);
- goto out;
- } else if (!strcmp(argv[1], "stop")) {
- printf("Stopping %s...\n", argv[3]);
-
- if (res_stop(&tree, curres, NULL)) {
- ret = -1;
- goto out;
- }
- printf("Stop of %s complete\n", argv[3]);
- goto out;
- } else if (!strcmp(argv[1], "migrate") && rn != NULL) {
- printf("Migrating %s to %s...\n", argv[3], argv[4]);
-
- #if 0
- if (!group_migratory(curres)) {
- printf("No can do\n");
- ret = -1;
- goto out;
- }
- #endif
-
- if (res_exec(rn, RS_MIGRATE, argv[4], 0)) {
- ret = -1;
- goto out;
- }
- printf("Migration of %s complete\n", argv[3]);
- goto out;
- } else if (!strcmp(argv[1], "status")) {
- printf("Checking status of %s...\n", argv[3]);
-
- ret = res_status(&tree, curres, NULL);
- if (ret) {
- printf("Status check of %s failed\n", argv[3]);
- goto out;
- }
- printf("Status of %s is good\n", argv[3]);
- goto out;
- }
-
-out:
- deconstruct_events(&events);
- deconstruct_domains(&domains);
- destroy_resource_tree(&tree);
- destroy_resources(&reslist);
- destroy_resource_rules(&rulelist);
-
- return ret;
-}
-
-
-static int
-tree_delta_test(int argc, char **argv)
-{
- resource_rule_t *rulelist = NULL, *currule, *rulelist2 = NULL;
- resource_t *reslist = NULL, *curres, *reslist2 = NULL;
- resource_node_t *tree = NULL, *tree2 = NULL;
- resource_node_t *tn;
- int ccsfd, ret = 0, need_init, need_kill;
- char rg[64];
-
- if (argc < 2) {
- printf("Operation requires two arguments\n");
- printf(USAGE_DELTA);
- return -1;
- }
-
- currule = NULL;
- curres = NULL;
-
- fprintf(stderr,"Running in resource tree delta test mode.\n");
-
- conf_setconfig(argv[1]);
-
- ccsfd = ccs_lock();
- if (ccsfd < 0) {
- printf("Error parsing %s\n", argv[1]);
- ret = 1;
- goto out;
- }
-
- load_resource_rules(agentpath, &rulelist);
- load_resource_defaults(ccsfd, &rulelist);
- load_resources(ccsfd, &reslist, &rulelist);
- build_resource_tree(ccsfd, &tree, &rulelist, &reslist);
- ccs_unlock(ccsfd);
-
- conf_setconfig(argv[2]);
-
- ccsfd = ccs_lock();
- if (ccsfd < 0) {
- printf("Error parsing %s\n", argv[2]);
- ret = 1;
- goto out;
- }
-
- load_resource_rules(agentpath, &rulelist2);
- load_resource_defaults(ccsfd, &rulelist);
- load_resources(ccsfd, &reslist2, &rulelist2);
- build_resource_tree(ccsfd, &tree2, &rulelist2, &reslist2);
- ccs_unlock(ccsfd);
-
- resource_delta(&reslist, &reslist2);
-
- printf("=== Old Resource List ===\n");
- print_resources(&reslist);
-
- printf("=== New Resource List ===\n");
- print_resources(&reslist2);
-
- resource_tree_delta(&tree, &tree2);
- printf("=== Old Resource Tree ===\n");
- print_resource_tree(&tree);
- printf("=== New Resource Tree ===\n");
- print_resource_tree(&tree2);
- printf("=== Operations (down-phase) ===\n");
- list_do(&tree, tn) {
- res_build_name(rg, sizeof(rg), tn->rn_resource);
- /* Set state to uninitialized if we're killing a RG */
- need_init = 0;
-
- /* Set state to uninitialized if we're killing a RG */
- need_kill = 0;
- if (tn->rn_resource->r_flags & RF_NEEDSTOP) {
- need_kill = 1;
- printf("[kill] ");
- }
-
- if (!tn->rn_child && ((tn->rn_resource->r_rule->rr_flags &
- RF_DESTROY) == 0) && test_group_migratory(&reslist, &tree,
- rg) &&
- need_kill == 1) {
- /* Do something smart here: flip state? */
- printf("[no-op] %s was removed from the config, but I am not stopping it.\n",
- rg);
- continue;
- }
-
- res_condstop(&tn, tn->rn_resource, NULL);
- } while (!list_done(&tree, tn));
- printf("=== Operations (up-phase) ===\n");
- list_do(&tree2, tn) {
- res_build_name(rg, sizeof(rg), tn->rn_resource);
- /* New RG. We'll need to initialize it. */
- need_init = 0;
- if (!(tn->rn_resource->r_flags & RF_RECONFIG) &&
- (tn->rn_resource->r_flags & RF_NEEDSTART))
- need_init = 1;
-
- if (need_init) {
- printf("[init] ");
- }
-
- if (!tn->rn_child && ((tn->rn_resource->r_rule->rr_flags &
- RF_INIT) == 0) && test_group_migratory(&reslist2, &tree2, rg) &&
- need_init == 1) {
- /* Do something smart here? */
- printf("[noop] %s was added, but I am not initializing it\n", rg);
- continue;
- }
-
- if (need_init) {
- res_stop(&tn, tn->rn_resource, NULL);
- } else {
- res_condstart(&tn, tn->rn_resource, NULL);
- }
- } while (!list_done(&tree2, tn));
-
-out:
- destroy_resource_tree(&tree2);
- destroy_resources(&reslist2);
- destroy_resource_rules(&rulelist2);
-
- destroy_resource_tree(&tree);
- destroy_resources(&reslist);
- destroy_resource_rules(&rulelist);
-
- return ret;
-}
-
-
-static int
-usage(char *arg0)
-{
- printf("usage: %s [agent_path] <args..>\n\n", arg0);
- printf(USAGE_TEST);
- printf(USAGE_DELTA);
- printf(USAGE_RULES);
-
- exit(1);
-}
-
-
-int
-main(int argc, char **argv)
-{
- char *arg0 = basename(argv[0]);
- int ret;
- struct stat st;
-
- if (argc < 2) {
- usage(arg0);
- return 1;
- }
-
- xmlInitParser();
- while (argc > 1) {
- if (!strcmp(argv[1], "test")) {
- shift();
- ret = test_func(argc, argv);
- goto out;
- } else if (!strcmp(argv[1], "noop")) {
- shift();
- _no_op_mode(1);
- ret = test_func(argc, argv);
- goto out;
- } else if (!strcmp(argv[1], "rules")) {
- shift();
- ret = rules_func(argc, argv);
- goto out;
- } else if (!strcmp(argv[1], "delta")) {
- shift();
- _no_op_mode(1);
- ret = tree_delta_test(argc, argv);
- goto out;
- } else {
- ret = stat(argv[1], &st);
- if (ret == -1 || !S_ISDIR(st.st_mode)) {
- break;
- }
- fprintf(stderr,
- "Using %s as resource agent path\n",
- argv[1]);
- agentpath = argv[1];
- shift();
- }
- }
-
- usage(arg0);
- xmlCleanupParser();
- return 1;
-
-out:
- xmlCleanupParser();
- return ret;
-}
diff --git a/rgmanager/src/daemons/tests/delta-test001-test002.expected b/rgmanager/src/daemons/tests/delta-test001-test002.expected
deleted file mode 100644
index 5e35839..0000000
--- a/rgmanager/src/daemons/tests/delta-test001-test002.expected
+++ /dev/null
@@ -1,22 +0,0 @@
-=== Old Resource List ===
-Resource type: service [INLINE]
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
-}
-=== New Resource Tree ===
-service {
- name = "test1";
-}
diff --git a/rgmanager/src/daemons/tests/delta-test002-test003.expected b/rgmanager/src/daemons/tests/delta-test002-test003.expected
deleted file mode 100644
index 28de03f..0000000
--- a/rgmanager/src/daemons/tests/delta-test002-test003.expected
+++ /dev/null
@@ -1,34 +0,0 @@
-=== Old Resource List ===
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: script [NEEDSTART]
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/httpd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
-}
-=== New Resource Tree ===
-service {
- name = "test1";
- script [ NEEDSTART ] {
- name = "initscript";
- file = "/etc/init.d/httpd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/delta-test003-test004.expected b/rgmanager/src/daemons/tests/delta-test003-test004.expected
deleted file mode 100644
index 6280a48..0000000
--- a/rgmanager/src/daemons/tests/delta-test003-test004.expected
+++ /dev/null
@@ -1,46 +0,0 @@
-=== Old Resource List ===
-Resource type: script [NEEDSTOP]
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/httpd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: script [NEEDSTART]
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
- script [ NEEDSTOP ] {
- name = "initscript";
- file = "/etc/init.d/httpd";
- service_name = "test1";
- }
-}
-=== New Resource Tree ===
-service {
- name = "test1";
- script [ NEEDSTART ] {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/delta-test004-test005.expected b/rgmanager/src/daemons/tests/delta-test004-test005.expected
deleted file mode 100644
index b50c1a8..0000000
--- a/rgmanager/src/daemons/tests/delta-test004-test005.expected
+++ /dev/null
@@ -1,58 +0,0 @@
-=== Old Resource List ===
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: ip [NEEDSTART]
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.2 [ primary unique ]
- monitor_link = 1
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-=== New Resource Tree ===
-service {
- name = "test1";
- ip [ NEEDSTART ] {
- address = "192.168.1.2";
- monitor_link = "1";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/delta-test005-test006.expected b/rgmanager/src/daemons/tests/delta-test005-test006.expected
deleted file mode 100644
index 8a77765..0000000
--- a/rgmanager/src/daemons/tests/delta-test005-test006.expected
+++ /dev/null
@@ -1,70 +0,0 @@
-=== Old Resource List ===
-Resource type: ip [NEEDSTOP]
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.2 [ primary unique ]
- monitor_link = 1
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: ip [NEEDSTART]
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.2 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
- ip [ NEEDSTOP ] {
- address = "192.168.1.2";
- monitor_link = "1";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-=== New Resource Tree ===
-service {
- name = "test1";
- ip [ NEEDSTART ] {
- address = "192.168.1.2";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/delta-test006-test007.expected b/rgmanager/src/daemons/tests/delta-test006-test007.expected
deleted file mode 100644
index dd99fef..0000000
--- a/rgmanager/src/daemons/tests/delta-test006-test007.expected
+++ /dev/null
@@ -1,70 +0,0 @@
-=== Old Resource List ===
-Resource type: ip [NEEDSTOP]
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.2 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: ip [NEEDSTART]
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
- ip [ NEEDSTOP ] {
- address = "192.168.1.2";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-=== New Resource Tree ===
-service {
- name = "test1";
- ip [ NEEDSTART ] {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/delta-test007-test008.expected b/rgmanager/src/daemons/tests/delta-test007-test008.expected
deleted file mode 100644
index f9c93b1..0000000
--- a/rgmanager/src/daemons/tests/delta-test007-test008.expected
+++ /dev/null
@@ -1,80 +0,0 @@
-=== Old Resource List ===
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: fs [NEEDSTART]
-Instances: 0/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-=== New Resource Tree ===
-service {
- name = "test1";
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/delta-test008-test009.expected b/rgmanager/src/daemons/tests/delta-test008-test009.expected
deleted file mode 100644
index 2a8b568..0000000
--- a/rgmanager/src/daemons/tests/delta-test008-test009.expected
+++ /dev/null
@@ -1,96 +0,0 @@
-=== Old Resource List ===
-Resource type: fs
-Instances: 0/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-=== New Resource Tree ===
-service {
- name = "test1";
- fs [ NEEDSTART ] {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/delta-test009-test010.expected b/rgmanager/src/daemons/tests/delta-test009-test010.expected
deleted file mode 100644
index 15b06db..0000000
--- a/rgmanager/src/daemons/tests/delta-test009-test010.expected
+++ /dev/null
@@ -1,110 +0,0 @@
-=== Old Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsexport [NEEDSTART]
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-=== New Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/delta-test010-test011.expected b/rgmanager/src/daemons/tests/delta-test010-test011.expected
deleted file mode 100644
index 8ae5a44..0000000
--- a/rgmanager/src/daemons/tests/delta-test010-test011.expected
+++ /dev/null
@@ -1,180 +0,0 @@
-=== Old Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient [NEEDSTART]
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = ro
-
-Resource type: nfsclient [NEEDSTART]
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient [NEEDSTART]
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient [NEEDSTART]
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient [NEEDSTART]
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-=== New Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport [ NEEDSTART ] {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "ro";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/delta-test011-test012.expected b/rgmanager/src/daemons/tests/delta-test011-test012.expected
deleted file mode 100644
index f08d30d..0000000
--- a/rgmanager/src/daemons/tests/delta-test011-test012.expected
+++ /dev/null
@@ -1,248 +0,0 @@
-=== Old Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = ro
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient [NEEDSTOP]
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = ro
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient [NEEDSTART]
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = ro
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "ro";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-=== New Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "ro";
- }
- nfsclient [ NEEDSTART ] {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "ro";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/delta-test012-test013.expected b/rgmanager/src/daemons/tests/delta-test012-test013.expected
deleted file mode 100644
index b704e40..0000000
--- a/rgmanager/src/daemons/tests/delta-test012-test013.expected
+++ /dev/null
@@ -1,254 +0,0 @@
-=== Old Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = ro
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient [NEEDSTOP]
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = ro
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = ro
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient [NEEDSTART]
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "ro";
- }
- nfsclient [ NEEDSTOP ] {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "ro";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-=== New Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "ro";
- }
- nfsclient [ NEEDSTART ] {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/delta-test013-test014.expected b/rgmanager/src/daemons/tests/delta-test013-test014.expected
deleted file mode 100644
index 9e9504a..0000000
--- a/rgmanager/src/daemons/tests/delta-test013-test014.expected
+++ /dev/null
@@ -1,319 +0,0 @@
-=== Old Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = ro
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: fs [NEEDSTART]
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount2 [ primary ]
- mountpoint = /mnt/cluster2 [ unique required ]
- device = /dev/sdb9 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: ip [NEEDSTART]
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.4 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = ro
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-Resource type: service [NEEDSTART]
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test2 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "ro";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-=== New Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "ro";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-service [ NEEDSTART ] {
- name = "test2";
- fs {
- name = "mount2";
- mountpoint = "/mnt/cluster2";
- device = "/dev/sdb9";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb9";
- path = "/mnt/cluster2";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster2";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster2";
- options = "ro";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster2";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.4";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test2";
- }
-}
diff --git a/rgmanager/src/daemons/tests/delta-test014-test015.expected b/rgmanager/src/daemons/tests/delta-test014-test015.expected
deleted file mode 100644
index 931d4a4..0000000
--- a/rgmanager/src/daemons/tests/delta-test014-test015.expected
+++ /dev/null
@@ -1,384 +0,0 @@
-=== Old Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount2 [ primary ]
- mountpoint = /mnt/cluster2 [ unique required ]
- device = /dev/sdb9 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.4 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient [NEEDSTOP]
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = ro
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test2 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount2 [ primary ]
- mountpoint = /mnt/cluster2 [ unique required ]
- device = /dev/sdb9 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.4 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient [NEEDSTART]
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,sync
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test2 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient [ NEEDSTOP ] {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "ro";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-service {
- name = "test2";
- fs {
- name = "mount2";
- mountpoint = "/mnt/cluster2";
- device = "/dev/sdb9";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb9";
- path = "/mnt/cluster2";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster2";
- options = "rw";
- }
- nfsclient [ NEEDSTOP ] {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster2";
- options = "ro";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster2";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.4";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test2";
- }
-}
-=== New Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient [ NEEDSTART ] {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-service {
- name = "test2";
- fs {
- name = "mount2";
- mountpoint = "/mnt/cluster2";
- device = "/dev/sdb9";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb9";
- path = "/mnt/cluster2";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster2";
- options = "rw";
- }
- nfsclient [ NEEDSTART ] {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster2";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster2";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.4";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test2";
- }
-}
diff --git a/rgmanager/src/daemons/tests/delta-test015-test016.expected b/rgmanager/src/daemons/tests/delta-test015-test016.expected
deleted file mode 100644
index 4239fc3..0000000
--- a/rgmanager/src/daemons/tests/delta-test015-test016.expected
+++ /dev/null
@@ -1,385 +0,0 @@
-Warning: Max references exceeded for resource address (type ip)
-=== Old Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount2 [ primary ]
- mountpoint = /mnt/cluster2 [ unique required ]
- device = /dev/sdb9 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.4 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,sync
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test2 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount2 [ primary ]
- mountpoint = /mnt/cluster2 [ unique required ]
- device = /dev/sdb9 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.4 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,sync
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test2 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-service {
- name = "test2";
- fs {
- name = "mount2";
- mountpoint = "/mnt/cluster2";
- device = "/dev/sdb9";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb9";
- path = "/mnt/cluster2";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster2";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster2";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster2";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.4";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test2";
- }
-}
-=== New Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-service {
- name = "test2";
- fs {
- name = "mount2";
- mountpoint = "/mnt/cluster2";
- device = "/dev/sdb9";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb9";
- path = "/mnt/cluster2";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster2";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster2";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster2";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.4";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test2";
- }
-}
diff --git a/rgmanager/src/daemons/tests/delta-test016-test017.expected b/rgmanager/src/daemons/tests/delta-test016-test017.expected
deleted file mode 100644
index 06abbff..0000000
--- a/rgmanager/src/daemons/tests/delta-test016-test017.expected
+++ /dev/null
@@ -1,408 +0,0 @@
-Warning: Max references exceeded for resource address (type ip)
-=== Old Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount2 [ primary ]
- mountpoint = /mnt/cluster2 [ unique required ]
- device = /dev/sdb9 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.4 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,sync
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test2 [ primary unique required ]
-
-=== New Resource List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount2 [ primary ]
- mountpoint = /mnt/cluster2 [ unique required ]
- device = /dev/sdb9 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.4 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,sync
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: script [NEEDSTART]
-Agent: script.sh
-Attributes:
- name = script2 [ primary unique ]
- file = /etc/init.d/script2 [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: script [NEEDSTART]
-Agent: script.sh
-Attributes:
- name = script3 [ primary unique ]
- file = /etc/init.d/script3 [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test2 [ primary unique required ]
-
-=== Old Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "rw";
- }
- }
- }
- ip [ NEEDSTOP ] {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-service {
- name = "test2";
- fs [ NEEDSTOP ] {
- name = "mount2";
- mountpoint = "/mnt/cluster2";
- device = "/dev/sdb9";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb9";
- path = "/mnt/cluster2";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster2";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster2";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster2";
- options = "rw";
- }
- }
- }
- ip [ NEEDSTOP ] {
- address = "192.168.1.4";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test2";
- }
-}
-=== New Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "rw";
- }
- }
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-service {
- name = "test2";
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test2";
- ip [ NEEDSTART ] {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- fs [ NEEDSTART ] {
- name = "mount2";
- mountpoint = "/mnt/cluster2";
- device = "/dev/sdb9";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb9";
- path = "/mnt/cluster2";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster2";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster2";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster2";
- options = "rw";
- }
- }
- }
- script [ NEEDSTART ] {
- name = "script2";
- file = "/etc/init.d/script2";
- }
- ip [ NEEDSTART ] {
- address = "192.168.1.4";
- monitor_link = "yes";
- }
- }
- script [ NEEDSTART ] {
- name = "script3";
- file = "/etc/init.d/script3";
- service_name = "test2";
- }
-}
diff --git a/rgmanager/src/daemons/tests/deptest1.conf b/rgmanager/src/daemons/tests/deptest1.conf
deleted file mode 100644
index c520134..0000000
--- a/rgmanager/src/daemons/tests/deptest1.conf
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0"?>
-<!--
- Basic "whiteboard" case:
-
- * 4 nodes
- * 2 restricted failover domains:
- * A is allowed to run on {1 4}
- * B is allowed to run on {3 4}
- * 3 services
- * A requires B to operate
- * B requires C to operate
- * A must NEVER run on the same node as B.
-
- Setup:
- * Start service C on node 2
- * Start service B on node 4
- * Start service A on node 1
- * Nothing is running on node 3
-
- Introduce a failure:
- * Kill off node 1
-
- Solution:
- * A must be moved to the stopped state (its owner is dead)
- * B must be stopped on node 4, and started on node 3
- * A must be started on node 4, since that is the only legal target
- of service A
-
- try: ../dtest ../../resources deptest1.conf < deptest1.in
--->
-<cluster>
- <clusternodes>
- <clusternode name="node1" nodeid="1"/>
- <clusternode name="node2" nodeid="2"/>
- <clusternode name="node3" nodeid="3"/>
- <clusternode name="node4" nodeid="4"/>
- </clusternodes>
- <rm>
- <dependencies>
- <dependency name="service:a">
- <target name="service:b" require="always" colocate="never"/>
- </dependency>
- <dependency name="service:b">
- <target name="service:c" require="always" />
- </dependency>
- </dependencies>
- <failoverdomains>
- <failoverdomain name="nodes-14" restricted="1">
- <failoverdomainnode name="node1" priority="1"/>
- <failoverdomainnode name="node4" priority="1"/>
- </failoverdomain>
- <failoverdomain name="nodes-34" restricted="1">
- <failoverdomainnode name="node3" priority="1"/>
- <failoverdomainnode name="node4" priority="1"/>
- </failoverdomain>
- </failoverdomains>
- <resources/>
- <service name="a" domain="nodes-14" />
- <service name="b" domain="nodes-34" />
- <service name="c" />
- </rm>
- <fence_daemon post_fail_delay="0" post_join_delay="3"/>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/deptest1.in b/rgmanager/src/daemons/tests/deptest1.in
deleted file mode 100644
index b10bd44..0000000
--- a/rgmanager/src/daemons/tests/deptest1.in
+++ /dev/null
@@ -1,11 +0,0 @@
-dep
-online 1 2 3 4
-start a 1
-start c 2
-start b 4
-state
-online 2 3 4
-check
-calc
-apply
-state
diff --git a/rgmanager/src/daemons/tests/deptest2.conf b/rgmanager/src/daemons/tests/deptest2.conf
deleted file mode 100644
index 7ce7c82..0000000
--- a/rgmanager/src/daemons/tests/deptest2.conf
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0"?>
-<!--
-
- * 4 nodes
- * 3 services
- * A requires colocation with B to operate
- * C requires colocation with B to operate
-
- Setup:
- * Start service B on node 1
- * Start service A on node 1
- * Start service C on node 1
-
- Introduce a failure:
- * Stop service B
-
- Solution:
- * Stop A (or C)
- * Stop C (or A)
- * Stop B
- * start B
- * start A (or C)
- * start C (or A)
-
- try: ../dtest ../../resources deptest2.conf < deptest2.in
--->
-<cluster>
- <clusternodes>
- <clusternode name="node1" nodeid="1"/>
- <clusternode name="node2" nodeid="2"/>
- <clusternode name="node3" nodeid="3"/>
- <clusternode name="node4" nodeid="4"/>
- </clusternodes>
- <rm>
- <dependencies>
- <dependency name="service:a">
- <target name="service:b" require="always" colocate="always"/>
- </dependency>
- <dependency name="service:c">
- <target name="service:b" require="always" colocate="always" />
- </dependency>
- </dependencies>
- <failoverdomains>
- </failoverdomains>
- <resources/>
- <service name="a" />
- <service name="b" />
- <service name="c" />
- </rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/deptest2.in b/rgmanager/src/daemons/tests/deptest2.in
deleted file mode 100644
index cb5e12c..0000000
--- a/rgmanager/src/daemons/tests/deptest2.in
+++ /dev/null
@@ -1,11 +0,0 @@
-dep
-online 1 2 3 4
-start b 1
-start a 1
-start c 1
-state
-check
-stop b
-calc
-apply
-state
diff --git a/rgmanager/src/daemons/tests/gentests.sh b/rgmanager/src/daemons/tests/gentests.sh
deleted file mode 100644
index e55bbbc..0000000
--- a/rgmanager/src/daemons/tests/gentests.sh
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/bin/sh
-
-LANG=C
-LC_ALL=C
-LOCALE=C
-export LANG LC_ALL LOCALE
-
-. testlist
-
-echo "WARNING:"
-echo " You will need to MANUALLY verify these test cases after generation!"
-echo " Do NOT commit them to CVS without first hand-checking each and"
-echo " every one! These are meant to help determine possible regressions"
-echo " in the tree handling code and the resource code."
-echo ""
-
-echo -n "Are you sure [y/N] ?"
-read foo
-if [ "$foo" != "y" ]; then
- echo "Ok, aborting..."
- exit 0
-fi
-
-#
-# Basic config tests.
-#
-for t in $TESTS; do
- echo -n "Generating $t..."
- ../rg_test ../../resources test $t.conf > $t.expected 2> /dev/null
- if grep "Error" $t.expected; then
- echo "FAILED"
- exit 1
- fi
- echo OK
-done
-
-
-#
-# Start/stop tests (noop)
-#
-for t in $TESTS; do
- declare SERVICES=$(echo "xpath /cluster/rm/service" | xmllint $t.conf --shell | grep content | cut -f2 -d'=')
- declare phase svc
- echo -n "Generating $t exec..."
- for phase in start stop; do
- echo -n "$phase..."
- rm -f $t.$phase.expected
- for svc in $SERVICES; do
- ../rg_test ../../resources noop $t.conf $phase service $svc >> $t.$phase.expected 2> /dev/null
- done
- done
- echo "OK"
-done
-
-
-#
-# Delta tests
-#
-prev=
-for t in $TESTS; do
- if [ -z "$prev" ]; then
- prev=$t
- continue
- fi
- echo -n "Generating delta between $prev and $t..."
- ../rg_test ../../resources delta \
- $prev.conf $t.conf > delta-$prev-$t.expected 2> /dev/null
- if grep "Error" delta-$prev-$t.expected; then
- echo "FAILED"
- exit 1
- fi
- prev=$t
- echo OK
-done
diff --git a/rgmanager/src/daemons/tests/runtests.sh b/rgmanager/src/daemons/tests/runtests.sh
deleted file mode 100644
index 4da6bbb..0000000
--- a/rgmanager/src/daemons/tests/runtests.sh
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/bin/sh
-#
-# Super primitive sanity check test program. If the output format of
-# any of the trees/lists changes, the tests will need to be regenerated
-# and manually checked.
-#
-# Poor design, but it does effectively detect memory leaks. (when linked
-# against the alloc.c in ../../clulib)
-#
-
-LANG=C
-LC_ALL=C
-LOCALE=C
-export LANG LC_ALL LOCALE
-
-. ./testlist
-
-echo "Running sanity+memory leak checks on rgmanager tree operations..."
-
-#
-# Basic config tests.
-#
-for t in $TESTS; do
- echo -n " Checking $t.conf..."
- ../rg_test ../../resources test $t.conf > $t.out 2> $t.out.stderr
- diff -uw $t.expected $t.out
- if [ $? -ne 0 ]; then
- echo "FAILED"
- echo "*** Basic Test $t failed"
- echo -n "Accept new output [y/N] ? "
- read ovr
- if [ "$ovr" = "y" ]; then
- cp $t.out $t.expected
- else
- exit 1
- fi
- fi
- if grep -q "allocation trace" $t.out.stderr; then
- echo "FAILED - memory leak"
- echo "*** Memory Test $t failed"
- echo
- echo Output:
- echo
- cat $t.out.stderr
- exit 1
- fi
- rm -f $t.out $t.out.stderr
- echo OK
-done
-
-
-#
-# Start/stop tests (noop)
-#
-for t in $TESTS; do
- declare SERVICES=$(echo "xpath /cluster/rm/service" | xmllint $t.conf --shell | grep content | cut -f2 -d'=')
- declare phase svc
- echo -n " Checking $t.conf..."
- for phase in start stop; do
- echo -n "$phase..."
- rm -f $t.$phase.out
- for svc in $SERVICES; do
- ../rg_test ../../resources noop $t.conf $phase service $svc >> $t.$phase.out 2> $t.$phase.out.stderr
- done
- diff -w $t.$phase.expected $t.$phase.out
- if [ $? -ne 0 ]; then
- echo "FAILED"
- echo "*** Start Test $t failed"
- exit 1
- fi
- if grep -q "allocation trace" $t.$phase.out.stderr; then
- echo "FAILED - memory leak"
- echo "*** Memory Test $t failed"
- echo
- echo Output:
- echo
- cat $t.$phase.out.stderr
- exit 1
- fi
- rm -f $t.$phase.out $t.$phase.out.stderr
- done
- echo "OK"
-done
-
-
-#
-# Delta tests
-#
-prev=
-for t in $TESTS; do
- if [ -z "$prev" ]; then
- prev=$t
- continue
- fi
- echo -n " Checking delta between $prev and $t..."
- ../rg_test ../../resources delta \
- $prev.conf $t.conf > delta-$prev-$t.out 2> delta-$prev-$t.out.stderr
- diff -uw delta-$prev-$t.expected delta-$prev-$t.out
- if [ $? -ne 0 ]; then
- echo "FAILED"
- echo "*** Differential test between $prev and $t failed"
- echo -n "Accept new output [y/N] ? "
- read ovr
- if [ "$ovr" = "y" ]; then
- cp delta-$prev-$t.out delta-$prev-$t.expected
- else
- exit 1
- fi
- fi
- if grep -q "allocation trace" delta-$prev-$t.out.stderr; then
- echo "FAILED - memory leak"
- echo "*** Memory Test $t failed"
- echo
- echo Output:
- echo
- cat delta-$prev-$t.out.stderr
- exit 1
- fi
- rm -f delta-$prev-$t.out delta-$prev-$t.out.stderr
- prev=$t
- echo OK
-done
diff --git a/rgmanager/src/daemons/tests/test001.conf b/rgmanager/src/daemons/tests/test001.conf
deleted file mode 100644
index b95ba86..0000000
--- a/rgmanager/src/daemons/tests/test001.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<!-- inline resource group -->
-<cluster>
-<rm>
- <service name="test1"/>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test001.expected b/rgmanager/src/daemons/tests/test001.expected
deleted file mode 100644
index a291576..0000000
--- a/rgmanager/src/daemons/tests/test001.expected
+++ /dev/null
@@ -1,11 +0,0 @@
-=== Resources List ===
-Resource type: service [INLINE]
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
-}
diff --git a/rgmanager/src/daemons/tests/test001.start.expected b/rgmanager/src/daemons/tests/test001.start.expected
deleted file mode 100644
index 9b991d7..0000000
--- a/rgmanager/src/daemons/tests/test001.start.expected
+++ /dev/null
@@ -1,3 +0,0 @@
-Starting test1...
-[start] service:test1
-Start of test1 complete
diff --git a/rgmanager/src/daemons/tests/test001.stop.expected b/rgmanager/src/daemons/tests/test001.stop.expected
deleted file mode 100644
index 993cf06..0000000
--- a/rgmanager/src/daemons/tests/test001.stop.expected
+++ /dev/null
@@ -1,3 +0,0 @@
-Stopping test1...
-[stop] service:test1
-Stop of test1 complete
diff --git a/rgmanager/src/daemons/tests/test002.conf b/rgmanager/src/daemons/tests/test002.conf
deleted file mode 100644
index 2782312..0000000
--- a/rgmanager/src/daemons/tests/test002.conf
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0"?>
-<!-- normal resource group -->
-<!-- If compared with the inline resource group in test1,
- this should not make this resource group restart since no
- attributes have changed. -->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- </resources>
- <service ref="test1"/>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test002.expected b/rgmanager/src/daemons/tests/test002.expected
deleted file mode 100644
index 5bf60f7..0000000
--- a/rgmanager/src/daemons/tests/test002.expected
+++ /dev/null
@@ -1,11 +0,0 @@
-=== Resources List ===
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
-}
diff --git a/rgmanager/src/daemons/tests/test002.start.expected b/rgmanager/src/daemons/tests/test002.start.expected
deleted file mode 100644
index 9b991d7..0000000
--- a/rgmanager/src/daemons/tests/test002.start.expected
+++ /dev/null
@@ -1,3 +0,0 @@
-Starting test1...
-[start] service:test1
-Start of test1 complete
diff --git a/rgmanager/src/daemons/tests/test002.stop.expected b/rgmanager/src/daemons/tests/test002.stop.expected
deleted file mode 100644
index 993cf06..0000000
--- a/rgmanager/src/daemons/tests/test002.stop.expected
+++ /dev/null
@@ -1,3 +0,0 @@
-Stopping test1...
-[stop] service:test1
-Stop of test1 complete
diff --git a/rgmanager/src/daemons/tests/test003.conf b/rgmanager/src/daemons/tests/test003.conf
deleted file mode 100644
index 9514516..0000000
--- a/rgmanager/src/daemons/tests/test003.conf
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0"?>
-<!-- Add an initscript to our regular resource group.
- The initscript should get a 'NEEDSTART' flag. -->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <script name="initscript" file="/etc/init.d/httpd"/>
- </resources>
- <service ref="test1">
- <script ref="initscript"/>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test003.expected b/rgmanager/src/daemons/tests/test003.expected
deleted file mode 100644
index 1681209..0000000
--- a/rgmanager/src/daemons/tests/test003.expected
+++ /dev/null
@@ -1,23 +0,0 @@
-=== Resources List ===
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/httpd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
- script {
- name = "initscript";
- file = "/etc/init.d/httpd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/test003.start.expected b/rgmanager/src/daemons/tests/test003.start.expected
deleted file mode 100644
index fd37d3a..0000000
--- a/rgmanager/src/daemons/tests/test003.start.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-Starting test1...
-[start] service:test1
-[start] script:initscript
-Start of test1 complete
diff --git a/rgmanager/src/daemons/tests/test003.stop.expected b/rgmanager/src/daemons/tests/test003.stop.expected
deleted file mode 100644
index bdbee27..0000000
--- a/rgmanager/src/daemons/tests/test003.stop.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-Stopping test1...
-[stop] script:initscript
-[stop] service:test1
-Stop of test1 complete
diff --git a/rgmanager/src/daemons/tests/test004.conf b/rgmanager/src/daemons/tests/test004.conf
deleted file mode 100644
index c71fe0b..0000000
--- a/rgmanager/src/daemons/tests/test004.conf
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0"?>
-<!-- Change the script, keeping the reference the same.
- the test3 (old) tree should note NEEDSTOP while the new
- tree should note NEEDSTART for the script resource -->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <script name="initscript" file="/etc/init.d/sshd"/>
- </resources>
- <service ref="test1">
- <script ref="initscript"/>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test004.expected b/rgmanager/src/daemons/tests/test004.expected
deleted file mode 100644
index 640b367..0000000
--- a/rgmanager/src/daemons/tests/test004.expected
+++ /dev/null
@@ -1,23 +0,0 @@
-=== Resources List ===
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/test004.start.expected b/rgmanager/src/daemons/tests/test004.start.expected
deleted file mode 100644
index fd37d3a..0000000
--- a/rgmanager/src/daemons/tests/test004.start.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-Starting test1...
-[start] service:test1
-[start] script:initscript
-Start of test1 complete
diff --git a/rgmanager/src/daemons/tests/test004.stop.expected b/rgmanager/src/daemons/tests/test004.stop.expected
deleted file mode 100644
index bdbee27..0000000
--- a/rgmanager/src/daemons/tests/test004.stop.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-Stopping test1...
-[stop] script:initscript
-[stop] service:test1
-Stop of test1 complete
diff --git a/rgmanager/src/daemons/tests/test005.conf b/rgmanager/src/daemons/tests/test005.conf
deleted file mode 100644
index bce3070..0000000
--- a/rgmanager/src/daemons/tests/test005.conf
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0"?>
-<!-- Add an IP address. The new tree should note NEEDSTART for this
- new IP address, but nothing else. -->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <script name="initscript" file="/etc/init.d/sshd"/>
- <ip address="192.168.1.2"/>
- </resources>
- <service ref="test1">
- <ip ref="192.168.1.2"/>
- <script ref="initscript"/>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test005.expected b/rgmanager/src/daemons/tests/test005.expected
deleted file mode 100644
index 6a26533..0000000
--- a/rgmanager/src/daemons/tests/test005.expected
+++ /dev/null
@@ -1,35 +0,0 @@
-=== Resources List ===
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.2 [ primary unique ]
- monitor_link = 1
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
- ip {
- address = "192.168.1.2";
- monitor_link = "1";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/test005.start.expected b/rgmanager/src/daemons/tests/test005.start.expected
deleted file mode 100644
index 8d18f77..0000000
--- a/rgmanager/src/daemons/tests/test005.start.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-Starting test1...
-[start] service:test1
-[start] ip:192.168.1.2
-[start] script:initscript
-Start of test1 complete
diff --git a/rgmanager/src/daemons/tests/test005.stop.expected b/rgmanager/src/daemons/tests/test005.stop.expected
deleted file mode 100644
index 7f6cabc..0000000
--- a/rgmanager/src/daemons/tests/test005.stop.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-Stopping test1...
-[stop] script:initscript
-[stop] ip:192.168.1.2
-[stop] service:test1
-Stop of test1 complete
diff --git a/rgmanager/src/daemons/tests/test006.conf b/rgmanager/src/daemons/tests/test006.conf
deleted file mode 100644
index 1383a9a..0000000
--- a/rgmanager/src/daemons/tests/test006.conf
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0"?>
-<!-- The IP address should have a NEEDSTOP in the old tree and NEEDSTART
- in the new tree, -->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <script name="initscript" file="/etc/init.d/sshd"/>
- <ip address="192.168.1.2" monitor_link="yes"/>
- </resources>
- <service ref="test1">
- <ip ref="192.168.1.2"/>
- <script ref="initscript"/>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test006.expected b/rgmanager/src/daemons/tests/test006.expected
deleted file mode 100644
index eba3ea9..0000000
--- a/rgmanager/src/daemons/tests/test006.expected
+++ /dev/null
@@ -1,35 +0,0 @@
-=== Resources List ===
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.2 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
- ip {
- address = "192.168.1.2";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/test006.start.expected b/rgmanager/src/daemons/tests/test006.start.expected
deleted file mode 100644
index 8d18f77..0000000
--- a/rgmanager/src/daemons/tests/test006.start.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-Starting test1...
-[start] service:test1
-[start] ip:192.168.1.2
-[start] script:initscript
-Start of test1 complete
diff --git a/rgmanager/src/daemons/tests/test006.stop.expected b/rgmanager/src/daemons/tests/test006.stop.expected
deleted file mode 100644
index 7f6cabc..0000000
--- a/rgmanager/src/daemons/tests/test006.stop.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-Stopping test1...
-[stop] script:initscript
-[stop] ip:192.168.1.2
-[stop] service:test1
-Stop of test1 complete
diff --git a/rgmanager/src/daemons/tests/test007.conf b/rgmanager/src/daemons/tests/test007.conf
deleted file mode 100644
index 6122c2f..0000000
--- a/rgmanager/src/daemons/tests/test007.conf
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0"?>
-<!-- When comapred with test6, the old IP address (192.168.1.2) should
- have a NEEDSTOP while the new IP address should have a NEEDSTART
- flag -->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <script name="initscript" file="/etc/init.d/sshd"/>
- <ip address="192.168.1.3" monitor_link="yes"/>
- </resources>
- <service ref="test1">
- <ip ref="192.168.1.3"/>
- <script ref="initscript"/>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test007.expected b/rgmanager/src/daemons/tests/test007.expected
deleted file mode 100644
index 394a01b..0000000
--- a/rgmanager/src/daemons/tests/test007.expected
+++ /dev/null
@@ -1,35 +0,0 @@
-=== Resources List ===
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/test007.start.expected b/rgmanager/src/daemons/tests/test007.start.expected
deleted file mode 100644
index c30c7c2..0000000
--- a/rgmanager/src/daemons/tests/test007.start.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-Starting test1...
-[start] service:test1
-[start] ip:192.168.1.3
-[start] script:initscript
-Start of test1 complete
diff --git a/rgmanager/src/daemons/tests/test007.stop.expected b/rgmanager/src/daemons/tests/test007.stop.expected
deleted file mode 100644
index 238fab5..0000000
--- a/rgmanager/src/daemons/tests/test007.stop.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-Stopping test1...
-[stop] script:initscript
-[stop] ip:192.168.1.3
-[stop] service:test1
-Stop of test1 complete
diff --git a/rgmanager/src/daemons/tests/test008.conf b/rgmanager/src/daemons/tests/test008.conf
deleted file mode 100644
index ebedd3e..0000000
--- a/rgmanager/src/daemons/tests/test008.conf
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0"?>
-<!-- When comapred with test7,
- there should be no NEEDSTART flags in any of the output trees, because
- although we have now defined "mount1", we have not assigned it
- to any resource groups. There SHOULD be a NEEDSTART in the resource
- list, just not any of the trees. -->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <script name="initscript" file="/etc/init.d/sshd"/>
- <ip address="192.168.1.3" monitor_link="yes"/>
- <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/>
- </resources>
- <service ref="test1">
- <ip ref="192.168.1.3"/>
- <script ref="initscript"/>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test008.expected b/rgmanager/src/daemons/tests/test008.expected
deleted file mode 100644
index ba618e1..0000000
--- a/rgmanager/src/daemons/tests/test008.expected
+++ /dev/null
@@ -1,45 +0,0 @@
-=== Resources List ===
-Resource type: fs
-Instances: 0/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/test008.start.expected b/rgmanager/src/daemons/tests/test008.start.expected
deleted file mode 100644
index c30c7c2..0000000
--- a/rgmanager/src/daemons/tests/test008.start.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-Starting test1...
-[start] service:test1
-[start] ip:192.168.1.3
-[start] script:initscript
-Start of test1 complete
diff --git a/rgmanager/src/daemons/tests/test008.stop.expected b/rgmanager/src/daemons/tests/test008.stop.expected
deleted file mode 100644
index 238fab5..0000000
--- a/rgmanager/src/daemons/tests/test008.stop.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-Stopping test1...
-[stop] script:initscript
-[stop] ip:192.168.1.3
-[stop] service:test1
-Stop of test1 complete
diff --git a/rgmanager/src/daemons/tests/test009.conf b/rgmanager/src/daemons/tests/test009.conf
deleted file mode 100644
index 00fbacd..0000000
--- a/rgmanager/src/daemons/tests/test009.conf
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0"?>
-<!-- When comapred with test8,
- We've now bound the fs "mount1" to "test1". There should be a
- NEEDSTART flag in the output of the "new" tree. -->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <script name="initscript" file="/etc/init.d/sshd"/>
- <ip address="192.168.1.3" monitor_link="yes"/>
- <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/>
- </resources>
- <service ref="test1">
- <ip ref="192.168.1.3"/>
- <script ref="initscript"/>
- <fs ref="mount1"/>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test009.expected b/rgmanager/src/daemons/tests/test009.expected
deleted file mode 100644
index 413170b..0000000
--- a/rgmanager/src/daemons/tests/test009.expected
+++ /dev/null
@@ -1,51 +0,0 @@
-=== Resources List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/test009.start.expected b/rgmanager/src/daemons/tests/test009.start.expected
deleted file mode 100644
index 93d3e1a..0000000
--- a/rgmanager/src/daemons/tests/test009.start.expected
+++ /dev/null
@@ -1,6 +0,0 @@
-Starting test1...
-[start] service:test1
-[start] fs:mount1
-[start] ip:192.168.1.3
-[start] script:initscript
-Start of test1 complete
diff --git a/rgmanager/src/daemons/tests/test009.stop.expected b/rgmanager/src/daemons/tests/test009.stop.expected
deleted file mode 100644
index b30788f..0000000
--- a/rgmanager/src/daemons/tests/test009.stop.expected
+++ /dev/null
@@ -1,6 +0,0 @@
-Stopping test1...
-[stop] script:initscript
-[stop] ip:192.168.1.3
-[stop] fs:mount1
-[stop] service:test1
-Stop of test1 complete
diff --git a/rgmanager/src/daemons/tests/test010.conf b/rgmanager/src/daemons/tests/test010.conf
deleted file mode 100644
index c375bb4..0000000
--- a/rgmanager/src/daemons/tests/test010.conf
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0"?>
-<!-- Add NFS export to the mix. Should have no NEEDSTOPS/NEEDSTARTS
- in the resource tree outputs. -->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <script name="initscript" file="/etc/init.d/sshd"/>
- <ip address="192.168.1.3" monitor_link="yes"/>
- <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/>
- <nfsexport name="Dummy Export"/>
- </resources>
- <service ref="test1">
- <ip ref="192.168.1.3"/>
- <script ref="initscript"/>
- <fs ref="mount1"/>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test010.expected b/rgmanager/src/daemons/tests/test010.expected
deleted file mode 100644
index fe4e257..0000000
--- a/rgmanager/src/daemons/tests/test010.expected
+++ /dev/null
@@ -1,59 +0,0 @@
-=== Resources List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/test010.start.expected b/rgmanager/src/daemons/tests/test010.start.expected
deleted file mode 100644
index 93d3e1a..0000000
--- a/rgmanager/src/daemons/tests/test010.start.expected
+++ /dev/null
@@ -1,6 +0,0 @@
-Starting test1...
-[start] service:test1
-[start] fs:mount1
-[start] ip:192.168.1.3
-[start] script:initscript
-Start of test1 complete
diff --git a/rgmanager/src/daemons/tests/test010.stop.expected b/rgmanager/src/daemons/tests/test010.stop.expected
deleted file mode 100644
index b30788f..0000000
--- a/rgmanager/src/daemons/tests/test010.stop.expected
+++ /dev/null
@@ -1,6 +0,0 @@
-Stopping test1...
-[stop] script:initscript
-[stop] ip:192.168.1.3
-[stop] fs:mount1
-[stop] service:test1
-Stop of test1 complete
diff --git a/rgmanager/src/daemons/tests/test011.conf b/rgmanager/src/daemons/tests/test011.conf
deleted file mode 100644
index ac158ca..0000000
--- a/rgmanager/src/daemons/tests/test011.conf
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0"?>
-<!-- Add NFS clients to the mix.
- Between test 10 and this one, there should be NEEDSTARTS in the
- new resource tree for Dummy Export.
-
- Because everything below an element is started if there's a NEEDSTART
- flag (and everything below an element is stopped if there's a
- NEEDSTOP, too), Admin group and User group will not need NEEDSTART
- flags in the resource trees, but their output in the resource list
- should show that they do have NEEDSTART flags.
--->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <script name="initscript" file="/etc/init.d/sshd"/>
- <ip address="192.168.1.3" monitor_link="yes"/>
- <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/>
- <nfsexport name="Dummy Export"/>
- <nfsclient name="User group" target="@users" options="ro"/>
- <nfsclient name="Admin group" target="@admin" options="rw"/>
- <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/>
- <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/>
- <nfsclient name="red" target="red" options="rw,no_root_squash"/>
-
- </resources>
- <service ref="test1">
- <ip ref="192.168.1.3"/>
- <script ref="initscript"/>
- <fs ref="mount1">
- <nfsexport ref="Dummy Export">
- <nfsclient ref="Admin group"/>
- <nfsclient ref="User group"/>
- </nfsexport>
- </fs>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test011.expected b/rgmanager/src/daemons/tests/test011.expected
deleted file mode 100644
index 9a82f01..0000000
--- a/rgmanager/src/daemons/tests/test011.expected
+++ /dev/null
@@ -1,121 +0,0 @@
-=== Resources List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = ro
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "ro";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/test011.start.expected b/rgmanager/src/daemons/tests/test011.start.expected
deleted file mode 100644
index c75b535..0000000
--- a/rgmanager/src/daemons/tests/test011.start.expected
+++ /dev/null
@@ -1,9 +0,0 @@
-Starting test1...
-[start] service:test1
-[start] fs:mount1
-[start] nfsexport:Dummy Export
-[start] nfsclient:Admin group
-[start] nfsclient:User group
-[start] ip:192.168.1.3
-[start] script:initscript
-Start of test1 complete
diff --git a/rgmanager/src/daemons/tests/test011.stop.expected b/rgmanager/src/daemons/tests/test011.stop.expected
deleted file mode 100644
index 2962100..0000000
--- a/rgmanager/src/daemons/tests/test011.stop.expected
+++ /dev/null
@@ -1,9 +0,0 @@
-Stopping test1...
-[stop] script:initscript
-[stop] ip:192.168.1.3
-[stop] nfsclient:User group
-[stop] nfsclient:Admin group
-[stop] nfsexport:Dummy Export
-[stop] fs:mount1
-[stop] service:test1
-Stop of test1 complete
diff --git a/rgmanager/src/daemons/tests/test012.conf b/rgmanager/src/daemons/tests/test012.conf
deleted file mode 100644
index a003ed3..0000000
--- a/rgmanager/src/daemons/tests/test012.conf
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0"?>
-<!--
- NEEDSTOP in the resource list for client "red". NEEDSTART in the
- new resource TREE for client "red"
--->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <script name="initscript" file="/etc/init.d/sshd"/>
- <ip address="192.168.1.3" monitor_link="yes"/>
- <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/>
- <nfsexport name="Dummy Export"/>
- <nfsclient name="User group" target="@users" options="ro"/>
- <nfsclient name="Admin group" target="@admin" options="rw"/>
- <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/>
- <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/>
- <nfsclient name="red" target="red" options="ro"/>
-
- </resources>
- <service ref="test1">
- <ip ref="192.168.1.3"/>
- <script ref="initscript"/>
- <fs ref="mount1">
- <nfsexport ref="Dummy Export">
- <nfsclient ref="Admin group" __enforce_timeouts="1" />
- <nfsclient ref="User group"/>
- <nfsclient ref="red"/>
- </nfsexport>
- </fs>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test012.expected b/rgmanager/src/daemons/tests/test012.expected
deleted file mode 100644
index 48bca23..0000000
--- a/rgmanager/src/daemons/tests/test012.expected
+++ /dev/null
@@ -1,127 +0,0 @@
-=== Resources List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = ro
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = ro
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "ro";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "ro";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/test012.start.expected b/rgmanager/src/daemons/tests/test012.start.expected
deleted file mode 100644
index e7fd06f..0000000
--- a/rgmanager/src/daemons/tests/test012.start.expected
+++ /dev/null
@@ -1,10 +0,0 @@
-Starting test1...
-[start] service:test1
-[start] fs:mount1
-[start] nfsexport:Dummy Export
-[start] nfsclient:Admin group
-[start] nfsclient:User group
-[start] nfsclient:red
-[start] ip:192.168.1.3
-[start] script:initscript
-Start of test1 complete
diff --git a/rgmanager/src/daemons/tests/test012.stop.expected b/rgmanager/src/daemons/tests/test012.stop.expected
deleted file mode 100644
index 5218b3a..0000000
--- a/rgmanager/src/daemons/tests/test012.stop.expected
+++ /dev/null
@@ -1,10 +0,0 @@
-Stopping test1...
-[stop] script:initscript
-[stop] ip:192.168.1.3
-[stop] nfsclient:red
-[stop] nfsclient:User group
-[stop] nfsclient:Admin group
-[stop] nfsexport:Dummy Export
-[stop] fs:mount1
-[stop] service:test1
-Stop of test1 complete
diff --git a/rgmanager/src/daemons/tests/test013.conf b/rgmanager/src/daemons/tests/test013.conf
deleted file mode 100644
index fd62271..0000000
--- a/rgmanager/src/daemons/tests/test013.conf
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0"?>
-<!--
- NEEDSTOP in the old resource _tree_ for client red.
- NEEDSTART in the new resource _tree_ for client red. We have
- changed the options to "rw".
--->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <script name="initscript" file="/etc/init.d/sshd"/>
- <ip address="192.168.1.3" monitor_link="yes"/>
- <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/>
- <nfsexport name="Dummy Export"/>
- <nfsclient name="User group" target="@users" options="ro"/>
- <nfsclient name="Admin group" target="@admin" options="rw"/>
- <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/>
- <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/>
- <nfsclient name="red" target="red" options="rw"/>
-
- </resources>
- <service ref="test1">
- <ip ref="192.168.1.3"/>
- <script ref="initscript"/>
- <fs ref="mount1">
- <nfsexport ref="Dummy Export">
- <nfsclient ref="Admin group"/>
- <nfsclient ref="User group"/>
- <nfsclient ref="red"/>
- </nfsexport>
- </fs>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test013.expected b/rgmanager/src/daemons/tests/test013.expected
deleted file mode 100644
index 2e18327..0000000
--- a/rgmanager/src/daemons/tests/test013.expected
+++ /dev/null
@@ -1,127 +0,0 @@
-=== Resources List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = ro
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "ro";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
diff --git a/rgmanager/src/daemons/tests/test013.start.expected b/rgmanager/src/daemons/tests/test013.start.expected
deleted file mode 100644
index e7fd06f..0000000
--- a/rgmanager/src/daemons/tests/test013.start.expected
+++ /dev/null
@@ -1,10 +0,0 @@
-Starting test1...
-[start] service:test1
-[start] fs:mount1
-[start] nfsexport:Dummy Export
-[start] nfsclient:Admin group
-[start] nfsclient:User group
-[start] nfsclient:red
-[start] ip:192.168.1.3
-[start] script:initscript
-Start of test1 complete
diff --git a/rgmanager/src/daemons/tests/test013.stop.expected b/rgmanager/src/daemons/tests/test013.stop.expected
deleted file mode 100644
index 5218b3a..0000000
--- a/rgmanager/src/daemons/tests/test013.stop.expected
+++ /dev/null
@@ -1,10 +0,0 @@
-Stopping test1...
-[stop] script:initscript
-[stop] ip:192.168.1.3
-[stop] nfsclient:red
-[stop] nfsclient:User group
-[stop] nfsclient:Admin group
-[stop] nfsexport:Dummy Export
-[stop] fs:mount1
-[stop] service:test1
-Stop of test1 complete
diff --git a/rgmanager/src/daemons/tests/test014.conf b/rgmanager/src/daemons/tests/test014.conf
deleted file mode 100644
index ced4848..0000000
--- a/rgmanager/src/daemons/tests/test014.conf
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0"?>
-<!--
- NEEDSTART for resource group "test2".
--->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <service name="test2"/>
- <script name="initscript" file="/etc/init.d/sshd"/>
- <ip address="192.168.1.3" monitor_link="yes"/>
- <ip address="192.168.1.4" monitor_link="yes"/>
- <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/>
- <fs fstype="ext3" name="mount2" mountpoint="/mnt/cluster2" device="/dev/sdb9"/>
- <nfsexport name="Dummy Export"/>
- <nfsclient name="User group" target="@users" options="ro"/>
- <nfsclient name="Admin group" target="@admin" options="rw"/>
- <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/>
- <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/>
- <nfsclient name="red" target="red" options="rw"/>
-
- </resources>
- <service ref="test1">
- <ip ref="192.168.1.3"/>
- <script ref="initscript"/>
- <fs ref="mount1">
- <nfsexport ref="Dummy Export">
- <nfsclient ref="Admin group"/>
- <nfsclient ref="User group"/>
- <nfsclient ref="red"/>
- </nfsexport>
- </fs>
- </service>
- <service ref="test2">
- <ip ref="192.168.1.4"/>
- <script ref="initscript"/>
- <fs ref="mount2">
- <nfsexport ref="Dummy Export">
- <nfsclient ref="Admin group"/>
- <nfsclient ref="User group"/>
- <nfsclient ref="red"/>
- </nfsexport>
- </fs>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test014.expected b/rgmanager/src/daemons/tests/test014.expected
deleted file mode 100644
index 0b50522..0000000
--- a/rgmanager/src/daemons/tests/test014.expected
+++ /dev/null
@@ -1,192 +0,0 @@
-=== Resources List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount2 [ primary ]
- mountpoint = /mnt/cluster2 [ unique required ]
- device = /dev/sdb9 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.4 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = ro
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test2 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "ro";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-service {
- name = "test2";
- fs {
- name = "mount2";
- mountpoint = "/mnt/cluster2";
- device = "/dev/sdb9";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb9";
- path = "/mnt/cluster2";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster2";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster2";
- options = "ro";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster2";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.4";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test2";
- }
-}
diff --git a/rgmanager/src/daemons/tests/test014.start.expected b/rgmanager/src/daemons/tests/test014.start.expected
deleted file mode 100644
index 562e1a5..0000000
--- a/rgmanager/src/daemons/tests/test014.start.expected
+++ /dev/null
@@ -1,20 +0,0 @@
-Starting test1...
-[start] service:test1
-[start] fs:mount1
-[start] nfsexport:Dummy Export
-[start] nfsclient:Admin group
-[start] nfsclient:User group
-[start] nfsclient:red
-[start] ip:192.168.1.3
-[start] script:initscript
-Start of test1 complete
-Starting test2...
-[start] service:test2
-[start] fs:mount2
-[start] nfsexport:Dummy Export
-[start] nfsclient:Admin group
-[start] nfsclient:User group
-[start] nfsclient:red
-[start] ip:192.168.1.4
-[start] script:initscript
-Start of test2 complete
diff --git a/rgmanager/src/daemons/tests/test014.stop.expected b/rgmanager/src/daemons/tests/test014.stop.expected
deleted file mode 100644
index c3eb880..0000000
--- a/rgmanager/src/daemons/tests/test014.stop.expected
+++ /dev/null
@@ -1,20 +0,0 @@
-Stopping test1...
-[stop] script:initscript
-[stop] ip:192.168.1.3
-[stop] nfsclient:red
-[stop] nfsclient:User group
-[stop] nfsclient:Admin group
-[stop] nfsexport:Dummy Export
-[stop] fs:mount1
-[stop] service:test1
-Stop of test1 complete
-Stopping test2...
-[stop] script:initscript
-[stop] ip:192.168.1.4
-[stop] nfsclient:red
-[stop] nfsclient:User group
-[stop] nfsclient:Admin group
-[stop] nfsexport:Dummy Export
-[stop] fs:mount2
-[stop] service:test2
-Stop of test2 complete
diff --git a/rgmanager/src/daemons/tests/test015.conf b/rgmanager/src/daemons/tests/test015.conf
deleted file mode 100644
index e1f76bf..0000000
--- a/rgmanager/src/daemons/tests/test015.conf
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0"?>
-<!--
- NEEDSTOP in old tree for "User group"
- NEEDSTART in new tree for "User group".
-
- We have changed the options again. Please make sure that BOTH
- tree nodes (the one in "test1" AND in "Test2") have NEEDSTOP/NEEDSTART
- flags!
--->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <service name="test2"/>
- <script name="initscript" file="/etc/init.d/sshd"/>
- <ip address="192.168.1.3" monitor_link="yes"/>
- <ip address="192.168.1.4" monitor_link="yes"/>
- <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/>
- <fs fstype="ext3" name="mount2" mountpoint="/mnt/cluster2" device="/dev/sdb9"/>
- <nfsexport name="Dummy Export"/>
- <nfsclient name="User group" target="@users" options="rw,sync"/>
- <nfsclient name="Admin group" target="@admin" options="rw"/>
- <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/>
- <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/>
- <nfsclient name="red" target="red" options="rw"/>
-
- </resources>
- <service ref="test1">
- <ip ref="192.168.1.3"/>
- <script ref="initscript"/>
- <fs ref="mount1">
- <nfsexport ref="Dummy Export">
- <nfsclient ref="Admin group"/>
- <nfsclient ref="User group"/>
- <nfsclient ref="red"/>
- </nfsexport>
- </fs>
- </service>
- <service ref="test2">
- <ip ref="192.168.1.4"/>
- <script ref="initscript"/>
- <fs ref="mount2">
- <nfsexport ref="Dummy Export">
- <nfsclient ref="Admin group"/>
- <nfsclient ref="User group"/>
- <nfsclient ref="red"/>
- </nfsexport>
- </fs>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test015.expected b/rgmanager/src/daemons/tests/test015.expected
deleted file mode 100644
index 3a509ca..0000000
--- a/rgmanager/src/daemons/tests/test015.expected
+++ /dev/null
@@ -1,192 +0,0 @@
-=== Resources List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount2 [ primary ]
- mountpoint = /mnt/cluster2 [ unique required ]
- device = /dev/sdb9 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.4 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,sync
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test2 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-service {
- name = "test2";
- fs {
- name = "mount2";
- mountpoint = "/mnt/cluster2";
- device = "/dev/sdb9";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb9";
- path = "/mnt/cluster2";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster2";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster2";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster2";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.4";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test2";
- }
-}
diff --git a/rgmanager/src/daemons/tests/test015.start.expected b/rgmanager/src/daemons/tests/test015.start.expected
deleted file mode 100644
index 562e1a5..0000000
--- a/rgmanager/src/daemons/tests/test015.start.expected
+++ /dev/null
@@ -1,20 +0,0 @@
-Starting test1...
-[start] service:test1
-[start] fs:mount1
-[start] nfsexport:Dummy Export
-[start] nfsclient:Admin group
-[start] nfsclient:User group
-[start] nfsclient:red
-[start] ip:192.168.1.3
-[start] script:initscript
-Start of test1 complete
-Starting test2...
-[start] service:test2
-[start] fs:mount2
-[start] nfsexport:Dummy Export
-[start] nfsclient:Admin group
-[start] nfsclient:User group
-[start] nfsclient:red
-[start] ip:192.168.1.4
-[start] script:initscript
-Start of test2 complete
diff --git a/rgmanager/src/daemons/tests/test015.stop.expected b/rgmanager/src/daemons/tests/test015.stop.expected
deleted file mode 100644
index c3eb880..0000000
--- a/rgmanager/src/daemons/tests/test015.stop.expected
+++ /dev/null
@@ -1,20 +0,0 @@
-Stopping test1...
-[stop] script:initscript
-[stop] ip:192.168.1.3
-[stop] nfsclient:red
-[stop] nfsclient:User group
-[stop] nfsclient:Admin group
-[stop] nfsexport:Dummy Export
-[stop] fs:mount1
-[stop] service:test1
-Stop of test1 complete
-Stopping test2...
-[stop] script:initscript
-[stop] ip:192.168.1.4
-[stop] nfsclient:red
-[stop] nfsclient:User group
-[stop] nfsclient:Admin group
-[stop] nfsexport:Dummy Export
-[stop] fs:mount2
-[stop] service:test2
-Stop of test2 complete
diff --git a/rgmanager/src/daemons/tests/test016.conf b/rgmanager/src/daemons/tests/test016.conf
deleted file mode 100644
index ed3501f..0000000
--- a/rgmanager/src/daemons/tests/test016.conf
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0"?>
-<!--
- Negative test: Attempting to assign an IP address to multiple resource
- groups. Only ONE copy of "192.168.1.3" should appear in the tree.
-
- There should be _no_ NEEDSTOPs/NEEDSTARTs anywhere.
--->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <service name="test2"/>
- <script name="initscript" file="/etc/init.d/sshd"/>
- <ip address="192.168.1.3" monitor_link="yes"/>
- <ip address="192.168.1.4" monitor_link="yes"/>
- <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/>
- <fs fstype="ext3" name="mount2" mountpoint="/mnt/cluster2" device="/dev/sdb9"/>
- <nfsexport name="Dummy Export"/>
- <nfsclient name="User group" target="@users" options="rw,sync"/>
- <nfsclient name="Admin group" target="@admin" options="rw"/>
- <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/>
- <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/>
- <nfsclient name="red" target="red" options="rw"/>
-
- </resources>
- <service ref="test1">
- <ip ref="192.168.1.3"/>
- <script ref="initscript"/>
- <fs ref="mount1">
- <nfsexport ref="Dummy Export">
- <nfsclient ref="Admin group"/>
- <nfsclient ref="User group"/>
- <nfsclient ref="red"/>
- </nfsexport>
- </fs>
- </service>
- <service ref="test2">
- <ip ref="192.168.1.3"/>
- <ip ref="192.168.1.4"/>
- <script ref="initscript"/>
- <fs ref="mount2">
- <nfsexport ref="Dummy Export">
- <nfsclient ref="Admin group"/>
- <nfsclient ref="User group"/>
- <nfsclient ref="red"/>
- </nfsexport>
- </fs>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test016.expected b/rgmanager/src/daemons/tests/test016.expected
deleted file mode 100644
index d286c2f..0000000
--- a/rgmanager/src/daemons/tests/test016.expected
+++ /dev/null
@@ -1,193 +0,0 @@
-Warning: Max references exceeded for resource address (type ip)
-=== Resources List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount2 [ primary ]
- mountpoint = /mnt/cluster2 [ unique required ]
- device = /dev/sdb9 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.4 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,sync
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test2 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-service {
- name = "test2";
- fs {
- name = "mount2";
- mountpoint = "/mnt/cluster2";
- device = "/dev/sdb9";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb9";
- path = "/mnt/cluster2";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster2";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster2";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster2";
- options = "rw";
- }
- }
- }
- ip {
- address = "192.168.1.4";
- monitor_link = "yes";
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test2";
- }
-}
diff --git a/rgmanager/src/daemons/tests/test016.start.expected b/rgmanager/src/daemons/tests/test016.start.expected
deleted file mode 100644
index 3f49953..0000000
--- a/rgmanager/src/daemons/tests/test016.start.expected
+++ /dev/null
@@ -1,22 +0,0 @@
-Warning: Max references exceeded for resource address (type ip)
-Starting test1...
-[start] service:test1
-[start] fs:mount1
-[start] nfsexport:Dummy Export
-[start] nfsclient:Admin group
-[start] nfsclient:User group
-[start] nfsclient:red
-[start] ip:192.168.1.3
-[start] script:initscript
-Start of test1 complete
-Warning: Max references exceeded for resource address (type ip)
-Starting test2...
-[start] service:test2
-[start] fs:mount2
-[start] nfsexport:Dummy Export
-[start] nfsclient:Admin group
-[start] nfsclient:User group
-[start] nfsclient:red
-[start] ip:192.168.1.4
-[start] script:initscript
-Start of test2 complete
diff --git a/rgmanager/src/daemons/tests/test016.stop.expected b/rgmanager/src/daemons/tests/test016.stop.expected
deleted file mode 100644
index dfc1cc1..0000000
--- a/rgmanager/src/daemons/tests/test016.stop.expected
+++ /dev/null
@@ -1,22 +0,0 @@
-Warning: Max references exceeded for resource address (type ip)
-Stopping test1...
-[stop] script:initscript
-[stop] ip:192.168.1.3
-[stop] nfsclient:red
-[stop] nfsclient:User group
-[stop] nfsclient:Admin group
-[stop] nfsexport:Dummy Export
-[stop] fs:mount1
-[stop] service:test1
-Stop of test1 complete
-Warning: Max references exceeded for resource address (type ip)
-Stopping test2...
-[stop] script:initscript
-[stop] ip:192.168.1.4
-[stop] nfsclient:red
-[stop] nfsclient:User group
-[stop] nfsclient:Admin group
-[stop] nfsexport:Dummy Export
-[stop] fs:mount2
-[stop] service:test2
-Stop of test2 complete
diff --git a/rgmanager/src/daemons/tests/test017.conf b/rgmanager/src/daemons/tests/test017.conf
deleted file mode 100644
index c300e47..0000000
--- a/rgmanager/src/daemons/tests/test017.conf
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0"?>
-<!--
- Lots of needstarts/needstops; this one is meant to test the ordering
- of untyped resources. In the test 2 service, the start/stop ordering
- should be:
-
- start test2
- start initscript
- start ip .1.3
- start mount2
- start dummy export
- start admin group
- start user group
- start red
- start script2
- start .1.4
- start script3
-
-
-
--->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <service name="test2"/>
- <script name="initscript" file="/etc/init.d/sshd"/>
- <script name="script2" file="/etc/init.d/script2"/>
- <script name="script3" file="/etc/init.d/script3"/>
- <ip address="192.168.1.3" monitor_link="yes"/>
- <ip address="192.168.1.4" monitor_link="yes"/>
- <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/>
- <fs fstype="ext3" name="mount2" mountpoint="/mnt/cluster2" device="/dev/sdb9"/>
- <nfsexport name="Dummy Export"/>
- <nfsclient name="User group" target="@users" options="rw,sync"/>
- <nfsclient name="Admin group" target="@admin" options="rw"/>
- <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/>
- <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/>
- <nfsclient name="red" target="red" options="rw"/>
-
- </resources>
- <service ref="test1">
- <script ref="initscript"/>
- <fs ref="mount1">
- <nfsexport ref="Dummy Export">
- <nfsclient ref="Admin group"/>
- <nfsclient ref="User group"/>
- <nfsclient ref="red"/>
- </nfsexport>
- </fs>
- </service>
- <service ref="test2">
- <script ref="initscript">
- <ip ref="192.168.1.3"/>
- <fs ref="mount2">
- <nfsexport ref="Dummy Export">
- <nfsclient ref="Admin group"/>
- <nfsclient ref="User group"/>
- <nfsclient ref="red"/>
- </nfsexport>
- </fs>
- <script ref="script2"/>
- <ip ref="192.168.1.4"/>
- </script>
- <script ref="script3"/>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test017.expected b/rgmanager/src/daemons/tests/test017.expected
deleted file mode 100644
index ae72496..0000000
--- a/rgmanager/src/daemons/tests/test017.expected
+++ /dev/null
@@ -1,215 +0,0 @@
-=== Resources List ===
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount1 [ primary ]
- mountpoint = /mnt/cluster [ unique required ]
- device = /dev/sdb8 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: fs
-Instances: 1/1
-Agent: fs.sh
-Attributes:
- name = mount2 [ primary ]
- mountpoint = /mnt/cluster2 [ unique required ]
- device = /dev/sdb9 [ unique required ]
- fstype = ext3
- nfslock [ inherit("nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.3 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: ip
-Instances: 1/1
-Agent: ip.sh
-Attributes:
- address = 192.168.1.4 [ primary unique ]
- monitor_link = yes
- nfslock [ inherit("service%nfslock") ]
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = User group [ primary unique ]
- target = @users [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,sync
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = Admin group [ primary unique ]
- target = @admin [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = yellow [ primary unique ]
- target = yellow [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = magenta [ primary unique ]
- target = magenta [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw,no_root_squash
-
-Resource type: nfsclient
-Agent: nfsclient.sh
-Attributes:
- name = red [ primary unique ]
- target = red [ required ]
- path [ inherit("path") ]
- fsid [ inherit("fsid") ]
- options = rw
-
-Resource type: nfsexport
-Agent: nfsexport.sh
-Attributes:
- name = Dummy Export [ primary ]
- device [ inherit("device") ]
- path [ inherit("mountpoint") ]
- fsid [ inherit("fsid") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = initscript [ primary unique ]
- file = /etc/init.d/sshd [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = script2 [ primary unique ]
- file = /etc/init.d/script2 [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: script
-Agent: script.sh
-Attributes:
- name = script3 [ primary unique ]
- file = /etc/init.d/script3 [ unique required ]
- service_name [ inherit("service%name") ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test1 [ primary unique required ]
-
-Resource type: service
-Instances: 1/1
-Agent: service.sh
-Attributes:
- name = test2 [ primary unique required ]
-
-=== Resource Tree ===
-service {
- name = "test1";
- fs {
- name = "mount1";
- mountpoint = "/mnt/cluster";
- device = "/dev/sdb8";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb8";
- path = "/mnt/cluster";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster";
- options = "rw";
- }
- }
- }
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test1";
- }
-}
-service {
- name = "test2";
- script {
- name = "initscript";
- file = "/etc/init.d/sshd";
- service_name = "test2";
- ip {
- address = "192.168.1.3";
- monitor_link = "yes";
- }
- fs {
- name = "mount2";
- mountpoint = "/mnt/cluster2";
- device = "/dev/sdb9";
- fstype = "ext3";
- nfsexport {
- name = "Dummy Export";
- device = "/dev/sdb9";
- path = "/mnt/cluster2";
- nfsclient {
- name = "Admin group";
- target = "@admin";
- path = "/mnt/cluster2";
- options = "rw";
- }
- nfsclient {
- name = "User group";
- target = "@users";
- path = "/mnt/cluster2";
- options = "rw,sync";
- }
- nfsclient {
- name = "red";
- target = "red";
- path = "/mnt/cluster2";
- options = "rw";
- }
- }
- }
- script {
- name = "script2";
- file = "/etc/init.d/script2";
- }
- ip {
- address = "192.168.1.4";
- monitor_link = "yes";
- }
- }
- script {
- name = "script3";
- file = "/etc/init.d/script3";
- service_name = "test2";
- }
-}
diff --git a/rgmanager/src/daemons/tests/test017.start.expected b/rgmanager/src/daemons/tests/test017.start.expected
deleted file mode 100644
index 054809f..0000000
--- a/rgmanager/src/daemons/tests/test017.start.expected
+++ /dev/null
@@ -1,22 +0,0 @@
-Starting test1...
-[start] service:test1
-[start] fs:mount1
-[start] nfsexport:Dummy Export
-[start] nfsclient:Admin group
-[start] nfsclient:User group
-[start] nfsclient:red
-[start] script:initscript
-Start of test1 complete
-Starting test2...
-[start] service:test2
-[start] script:initscript
-[start] ip:192.168.1.3
-[start] fs:mount2
-[start] nfsexport:Dummy Export
-[start] nfsclient:Admin group
-[start] nfsclient:User group
-[start] nfsclient:red
-[start] script:script2
-[start] ip:192.168.1.4
-[start] script:script3
-Start of test2 complete
diff --git a/rgmanager/src/daemons/tests/test017.stop.expected b/rgmanager/src/daemons/tests/test017.stop.expected
deleted file mode 100644
index ccc056c..0000000
--- a/rgmanager/src/daemons/tests/test017.stop.expected
+++ /dev/null
@@ -1,22 +0,0 @@
-Stopping test1...
-[stop] script:initscript
-[stop] nfsclient:red
-[stop] nfsclient:User group
-[stop] nfsclient:Admin group
-[stop] nfsexport:Dummy Export
-[stop] fs:mount1
-[stop] service:test1
-Stop of test1 complete
-Stopping test2...
-[stop] script:script3
-[stop] ip:192.168.1.4
-[stop] script:script2
-[stop] nfsclient:red
-[stop] nfsclient:User group
-[stop] nfsclient:Admin group
-[stop] nfsexport:Dummy Export
-[stop] fs:mount2
-[stop] ip:192.168.1.3
-[stop] script:initscript
-[stop] service:test2
-Stop of test2 complete
diff --git a/rgmanager/src/daemons/tests/test018.conf b/rgmanager/src/daemons/tests/test018.conf
deleted file mode 100644
index da7ed6e..0000000
--- a/rgmanager/src/daemons/tests/test018.conf
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0"?>
-<!--
- while testing for #212121, I found that if you had multiple
- instances of untyped children where the untyped children were
- multi-instance resources, you could end up with resource duplication
- the second time around.
-
- For example:
-
- start test2
- start initscript
- start clusterfs - this should not happen twice
- start clusterfs
- start ip .1.3
- start mount2
- start dummy export
- start admin group
- start user group
- start red
- start script2
- start .1.4
- start script3
-
- ... would occur without the change to restree.c which removes
- the addition of newchild to the known-children.
-
--->
-<cluster>
-<rm>
- <resources>
- <service name="test1"/>
- <service name="test2"/>
- <script name="initscript" file="/etc/init.d/sshd"/>
- <script name="script2" file="/etc/init.d/script2"/>
- <script name="script3" file="/etc/init.d/script3"/>
- <ip address="192.168.1.3" monitor_link="yes"/>
- <ip address="192.168.1.4" monitor_link="yes"/>
- <fs fstype="ext3" name="mount1" mountpoint="/mnt/cluster" device="/dev/sdb8"/>
- <fs fstype="ext3" name="mount2" mountpoint="/mnt/cluster2" device="/dev/sdb9"/>
- <nfsexport name="Dummy Export"/>
- <nfsclient name="User group" target="@users" options="rw,sync"/>
- <nfsclient name="Admin group" target="@admin" options="rw"/>
- <nfsclient name="yellow" target="yellow" options="rw,no_root_squash"/>
- <nfsclient name="magenta" target="magenta" options="rw,no_root_squash"/>
- <nfsclient name="red" target="red" options="rw"/>
- <clusterfs name="argle" mountpoint="/mnt/cluster3" device="/dev/sdb10"/>
-
- </resources>
- <service ref="test1">
- <script ref="initscript">
- <clusterfs ref="argle"/>
- </script>
- <fs ref="mount1">
- <nfsexport ref="Dummy Export">
- <nfsclient ref="Admin group"/>
- <nfsclient ref="User group"/>
- <nfsclient ref="red"/>
- </nfsexport>
- </fs>
- </service>
- <service ref="test2">
- <script ref="initscript">
- <clusterfs ref="argle"/>
- <ip ref="192.168.1.3"/>
- <fs ref="mount2">
- <nfsexport ref="Dummy Export">
- <nfsclient ref="Admin group"/>
- <nfsclient ref="User group"/>
- <nfsclient ref="red"/>
- </nfsexport>
- </fs>
- <script ref="script2"/>
- <ip ref="192.168.1.4"/>
- </script>
- <script ref="script3"/>
- </service>
-</rm>
-</cluster>
diff --git a/rgmanager/src/daemons/tests/test018.start.expected b/rgmanager/src/daemons/tests/test018.start.expected
deleted file mode 100644
index b633297..0000000
--- a/rgmanager/src/daemons/tests/test018.start.expected
+++ /dev/null
@@ -1,24 +0,0 @@
-Starting test1...
-[start] service:test1
-[start] fs:mount1
-[start] nfsexport:Dummy Export
-[start] nfsclient:Admin group
-[start] nfsclient:User group
-[start] nfsclient:red
-[start] script:initscript
-[start] clusterfs:argle
-Start of test1 complete
-Starting test2...
-[start] service:test2
-[start] script:initscript
-[start] clusterfs:argle
-[start] ip:192.168.1.3
-[start] fs:mount2
-[start] nfsexport:Dummy Export
-[start] nfsclient:Admin group
-[start] nfsclient:User group
-[start] nfsclient:red
-[start] script:script2
-[start] ip:192.168.1.4
-[start] script:script3
-Start of test2 complete
diff --git a/rgmanager/src/daemons/tests/test018.stop.expected b/rgmanager/src/daemons/tests/test018.stop.expected
deleted file mode 100644
index 5df827b..0000000
--- a/rgmanager/src/daemons/tests/test018.stop.expected
+++ /dev/null
@@ -1,24 +0,0 @@
-Stopping test1...
-[stop] clusterfs:argle
-[stop] script:initscript
-[stop] nfsclient:red
-[stop] nfsclient:User group
-[stop] nfsclient:Admin group
-[stop] nfsexport:Dummy Export
-[stop] fs:mount1
-[stop] service:test1
-Stop of test1 complete
-Stopping test2...
-[stop] script:script3
-[stop] ip:192.168.1.4
-[stop] script:script2
-[stop] nfsclient:red
-[stop] nfsclient:User group
-[stop] nfsclient:Admin group
-[stop] nfsexport:Dummy Export
-[stop] fs:mount2
-[stop] ip:192.168.1.3
-[stop] clusterfs:argle
-[stop] script:initscript
-[stop] service:test2
-Stop of test2 complete
diff --git a/rgmanager/src/daemons/tests/testlist b/rgmanager/src/daemons/tests/testlist
deleted file mode 100644
index 045a3e1..0000000
--- a/rgmanager/src/daemons/tests/testlist
+++ /dev/null
@@ -1,4 +0,0 @@
-#
-# Tests to run.
-#
-TESTS=$(/bin/ls -1 test*.conf | cut -f1 -d.)
diff --git a/rgmanager/src/daemons/update-dbus.c b/rgmanager/src/daemons/update-dbus.c
deleted file mode 100644
index 474140e..0000000
--- a/rgmanager/src/daemons/update-dbus.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/* DBus notifications */
-#include <stdint.h>
-#include <rg_dbus.h>
-#include <errno.h>
-
-#ifdef DBUS
-
-#include <stdio.h>
-#include <stdint.h>
-#include <resgroup.h>
-#include <poll.h>
-#include <dbus/dbus.h>
-#include <liblogthread.h>
-#include <members.h>
-#include <signal.h>
-
-
-#define DBUS_RGM_NAME "com.redhat.cluster.rgmanager"
-#define DBUS_RGM_IFACE "com.redhat.cluster.rgmanager"
-#define DBUS_RGM_PATH "/com/redhat/cluster/rgmanager"
-
-static void * _dbus_auto_flush(void *arg);
-
-static DBusConnection *db = NULL;
-static pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
-static pthread_t th = 0;
-#endif
-
-/* Set this to the desired value prior to calling rgm_dbus_init() */
-int rgm_dbus_notify = RGM_DBUS_DEFAULT;
-
-/*
- * block the world when entering dbus critical sections so that
- * if we get a signal while in dbus critical (exclusive of crash
- * signals), we ignore it
- */
-#define DBUS_ENTRY(set, old) \
-do { \
- pthread_mutex_lock(&mu); \
- sigfillset(&set); \
- sigdelset(&set, SIGILL); \
- sigdelset(&set, SIGSEGV); \
- sigdelset(&set, SIGABRT); \
- sigdelset(&set, SIGBUS); \
- sigprocmask(SIG_SETMASK, &set, &old); \
-} while(0)
-
-#define DBUS_EXIT(old) \
-do { \
- sigprocmask(SIG_SETMASK, &old, NULL); \
- pthread_mutex_unlock(&mu); \
-} while(0)
-
-
-int
-rgm_dbus_init(void)
-#ifdef DBUS
-{
- DBusConnection *dbc = NULL;
- DBusError err;
- sigset_t set, old;
-
- if (!rgm_dbus_notify)
- return 0;
-
- DBUS_ENTRY(set, old);
- if (db) {
- DBUS_EXIT(old);
- return 0;
- }
-
- dbus_threads_init_default();
- dbus_error_init(&err);
-
- dbc = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
- if (!dbc) {
- logt_print(LOG_DEBUG,
- "DBus Failed to initialize: dbus_bus_get: %s\n",
- err.message);
- dbus_error_free(&err);
- DBUS_EXIT(old);
- return -1;
- }
-
- dbus_connection_set_exit_on_disconnect(dbc, FALSE);
-
- db = dbc;
-
- pthread_create(&th, NULL, _dbus_auto_flush, NULL);
-
- DBUS_EXIT(old);
- logt_print(LOG_DEBUG, "DBus Notifications Initialized\n");
- return 0;
-}
-#else
-{
- errno = ENOSYS;
- return -1;
-}
-#endif
-
-
-#ifdef DBUS
-static int
-_rgm_dbus_release(void)
-{
- pthread_t t;
-
- if (!db)
- return 0;
-
- /* tell thread to exit - not sure how to tell dbus
- * to wake up, so just have it poll XXX */
-
- /* if the thread left because the dbus connection died,
- this block is avoided */
- if (th) {
- t = th;
- th = 0;
- pthread_join(t, NULL);
- }
-
- dbus_connection_close(db);
- dbus_connection_unref(db);
- db = NULL;
-
- logt_print(LOG_DEBUG, "DBus Released\n");
- return 0;
-}
-#endif
-
-
-/* Clean shutdown (e.g. when exiting */
-int
-rgm_dbus_release(void)
-#ifdef DBUS
-{
- int ret;
- sigset_t set, old;
-
- DBUS_ENTRY(set, old);
- ret = _rgm_dbus_release();
- DBUS_EXIT(old);
- return ret;
-}
-#else
-{
- return 0;
-}
-#endif
-
-
-#ifdef DBUS
-/* Auto-flush thread. Since sending only guarantees queueing,
- * we need this thread to push things out over dbus in the
- * background */
-static void *
-_dbus_auto_flush(void *arg)
-{
- sigset_t set;
-
- sigfillset(&set);
- sigdelset(&set, SIGILL);
- sigdelset(&set, SIGSEGV);
- sigdelset(&set, SIGABRT);
- sigdelset(&set, SIGBUS);
- sigprocmask(SIG_SETMASK, &set, NULL);
-
- /* DBus connection functions are thread safe */
- while (dbus_connection_read_write(db, 500)) {
- if (!th)
- break;
- }
-
- th = 0;
- return NULL;
-}
-
-
-static int
-_rgm_dbus_notify(const char *svcname,
- const char *svcstatus,
- const char *svcflags,
- const char *svcowner,
- const char *svclast)
-{
- DBusMessage *msg = NULL;
- int ret = 0;
- sigset_t set, old;
-
- DBUS_ENTRY(set, old);
-
- if (!db) {
- goto out_unlock;
- }
-
- /* Notifications are enabled */
- ret = -1;
-
- /* Check to ensure the connection is still valid. If it
- * isn't, clean up and shut down the dbus connection.
- *
- * The main rgmanager thread will periodically try to
- * reinitialize the dbus notification subsystem unless
- * the administrator ran rgmanager with the -D command
- * line option.
- */
- if (dbus_connection_get_is_connected(db) != TRUE) {
- goto out_unlock;
- }
-
- if (!th) {
- goto out_unlock;
- }
-
- if (!(msg = dbus_message_new_signal(DBUS_RGM_PATH,
- DBUS_RGM_IFACE,
- "ServiceStateChange"))) {
- goto out_unlock;
- }
-
- if (!dbus_message_append_args(msg,
- DBUS_TYPE_STRING, &svcname,
- DBUS_TYPE_STRING, &svcstatus,
- DBUS_TYPE_STRING, &svcflags,
- DBUS_TYPE_STRING, &svcowner,
- DBUS_TYPE_STRING, &svclast,
- DBUS_TYPE_INVALID)) {
- goto out_unlock;
- }
-
- dbus_connection_send(db, msg, NULL);
- ret = 0;
-
-out_unlock:
- DBUS_EXIT(old);
- if (msg)
- dbus_message_unref(msg);
-
- return ret;
-}
-
-
-/*
- * view-formation callback function
- */
-int32_t
-rgm_dbus_update(char *key, uint64_t view, void *data, uint32_t size)
-{
- char flags[64];
- rg_state_t *st;
- cluster_member_list_t *m = NULL;
- const char *owner;
- const char *last;
- sigset_t set, old;
- int ret = 0;
-
- if (!rgm_dbus_notify)
- goto out_free;
- if (view == 1)
- goto out_free;
- if (size != (sizeof(*st)))
- goto out_free;
-
- DBUS_ENTRY(set, old);
- if (!db) {
- DBUS_EXIT(old);
- goto out_free;
- }
- if (!th) {
- /* Dispatch thread died. */
- _rgm_dbus_release();
- DBUS_EXIT(old);
- goto out_free;
- }
- DBUS_EXIT(old);
-
- st = (rg_state_t *)data;
- swab_rg_state_t(st);
-
- /* Don't send transitional states */
- if (st->rs_state == RG_STATE_STARTING ||
- st->rs_state == RG_STATE_STOPPING)
- goto out_free;
-
- m = member_list();
- if (!m)
- goto out_free;
-
- owner = memb_id_to_name(m, st->rs_owner);
- last = memb_id_to_name(m, st->rs_last_owner);
-
- if (!owner)
- owner = "(none)";
- if (!last)
- last = "(none)";
-
- flags[0] = 0;
- rg_flags_str(flags, sizeof(flags), st->rs_flags, (char *)" ");
- if (flags[0] == 0)
- snprintf(flags, sizeof(flags), "(none)");
-
- ret = _rgm_dbus_notify(st->rs_name,
- rg_state_str(st->rs_state),
- (char *)flags, owner, last);
-
- if (ret < 0) {
- logt_print(LOG_ERR, "Error sending update for %s; "
- "DBus notifications disabled\n", key);
- rgm_dbus_release();
- }
-
-out_free:
- if (m)
- free_member_list(m);
- free(data);
- return 0;
-}
-#endif
diff --git a/rgmanager/src/daemons/watchdog.c b/rgmanager/src/daemons/watchdog.c
deleted file mode 100644
index dfecab1..0000000
--- a/rgmanager/src/daemons/watchdog.c
+++ /dev/null
@@ -1,108 +0,0 @@
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/reboot.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-
-#include <signals.h>
-#include <logging.h>
-
-int watchdog_init(void);
-
-static pid_t child = 0;
-
-static void
-signal_handler(int signum)
-{
- kill(child, signum);
-}
-
-
-static void
-redirect_signals(void)
-{
- int i;
- for (i = 0; i < _NSIG; i++) {
- switch (i) {
- case SIGCHLD:
- case SIGILL:
- case SIGFPE:
- case SIGSEGV:
- case SIGBUS:
- setup_signal(i, SIG_DFL);
- break;
- default:
- setup_signal(i, signal_handler);
- }
- }
-}
-
-
-static int
-sysrq_reboot(void)
-{
- int fd;
-
- fd = open("/proc/sysrq-trigger", O_WRONLY|O_SYNC);
- if (fd < 0)
- return fd;
-
- write(fd, "b\n", 2);
- fsync(fd);
- fdatasync(fd);
- close(fd);
-
- return 0;
-}
-
-
-/**
- return watchdog's pid, or 0 on failure
-*/
-int
-watchdog_init(void)
-{
- int status;
- pid_t parent;
-
- parent = getpid();
- child = fork();
- if (child < 0)
- return 0;
- else if (!child)
- return parent;
-
- redirect_signals();
- mlockall(MCL_CURRENT); /* shouldn't need MCL_FUTURE */
-
- while (1) {
- if (waitpid(child, &status, 0) <= 0)
- continue;
-
- if (WIFEXITED(status))
- exit(WEXITSTATUS(status));
-
- if (WIFSIGNALED(status)) {
- if (WTERMSIG(status) == SIGKILL) {
- /* Assume the admin did a 'killall' - it will
- * kill us within a couple of seconds. If
- * we are still alive after this sleep, it
- * could have been the OOM killer killing
- * rgmanager proper and we need to reboot.
- */
- sleep(3);
- }
-#ifdef DEBUG
- logt_print(LOG_CRIT, "Watchdog: Daemon died, but not rebooting because DEBUG is set\n");
-#else
- logt_print(LOG_CRIT, "Watchdog: Daemon died, rebooting...\n");
- sync();
- sysrq_reboot();
- reboot(RB_AUTOBOOT);
-#endif
- exit(255);
- }
- }
-}
diff --git a/rgmanager/src/resources/Makefile b/rgmanager/src/resources/Makefile
deleted file mode 100644
index 00b2bc8..0000000
--- a/rgmanager/src/resources/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-include ../../../make/defines.mk
-
-all:
-
-SHAREDIRT= default_event_script.sl \
- follow-service.sl
-
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-clean: generalclean
diff --git a/rgmanager/src/resources/default_event_script.sl b/rgmanager/src/resources/default_event_script.sl
deleted file mode 100644
index 12260ee..0000000
--- a/rgmanager/src/resources/default_event_script.sl
+++ /dev/null
@@ -1,652 +0,0 @@
-%
-% Copyright (C) 1997-2003 Sistina Software, Inc. All rights reserved.
-% Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
-%
-% This program is free software; you can redistribute it and/or
-% modify it under the terms of the GNU General Public License
-% as published by the Free Software Foundation; either version 2
-% of the License, or (at your option) any later version.
-%
-% This program is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with this program; if not, write to the Free Software
-% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-%
-
-
-define node_in_set(node_list, node)
-{
- variable x, len;
-
- len = length(node_list);
- for (x = 0; x < len; x++) {
- if (node_list[x] == node)
- return 1;
- }
-
- return 0;
-}
-
-
-%
-% Returns 3 node lists:
-% (1) Nodes with no services
-% (2) Nodes with non-exclusive services
-% (3) Nodes with exclusive services
-%
-% NOTE: This function currently defenstrates failover domain rules
-%
-define separate_nodes(node_list)
-{
- variable services = service_list();
- variable nodes_empty, nodes_services, nodes_excl;
- variable x, len;
- variable owner, state, excl, ns = 0, nx = 0;
-
- nodes_empty = node_list;
-
- % Most Awesome Initializer EVER!!!
- nodes_services = subtract([0], 0);
- nodes_excl = subtract([0], 0);
-
- len = length(services);
- for (x = 0; x < len; x++) {
-
- (,,, owner, state) = service_status(services[x]);
- if (owner < 0) {
- continue;
- }
-
- excl = atoi(service_property(services[x], "exclusive"));
- nodes_empty = subtract(nodes_empty, owner);
- if (excl) {
- nodes_excl = union(nodes_excl, owner);
- } else {
- nodes_services = union(nodes_services, owner);
- }
- }
-
- return (nodes_empty, nodes_services, nodes_excl);
-}
-
-
-define exclusive_prioritize(svc, node_list)
-{
- variable services = service_list();
- variable len, x, y, owner, nowner, state, preferred_owner;
- variable svc_excl, other_excl;
- variable nodes_x, nodes_s, nodes_e;
-
- %
- % Not exclusive? Don't care!
- %
- svc_excl = atoi(service_property(svc, "exclusive"));
- if (svc_excl == 0) {
- notice("Starting ", svc, " on ", node_list);
- return service_start(svc, node_list);
- }
-
- (nodes_e, nodes_s, nodes_x) = separate_nodes(node_list);
- debug("Nodes - Empty: ", nodes_e, " w/Services: ", nodes_s, " w/Excl: ", nodes_x);
- if (length(nodes_e) > 0) {
- %
- % If we've got an exclusive service, only allow it to start on
- % empty nodes.
- %
- notice("Starting ", svc, " on ", nodes_e);
- nowner = service_start(svc, nodes_e);
- if ((nowner > 0) or (nowner != FAIL)) {
- return nowner;
- }
- }
-
- if (length(nodes_x) == 0) {
- %
- % If we've got NO nodes with other exclusive services
- % and no empty nodes, the service can not be started
- %
- notice("No empty / exclusive nodes available; cannot restart ", svc);
- return ERR_DOMAIN;
- }
-
- %
- % Prioritization of exclusive services: pancake a service and replace it
- % with this service if this services is a higher priority.
- %
- len = length(services);
- for (x = 0; x < len; x++) {
- if (svc == services[x]) {
- % don't do anything to ourself!
- continue;
- }
-
- (,,, owner, state) = service_status(services[x]);
- if (owner < 0) {
- continue;
- }
-
- if (node_in_set(node_list, owner) == 0) {
- continue;
- }
-
- other_excl = atoi(service_property(services[x], "exclusive"));
- if (other_excl == 0) {
- continue;
- }
-
- %
- % If we're a higher priority (lower #) exclusive
- % Stop the exclusive service that node and move that
- % node to the front.
- %
- if (svc_excl >= other_excl) {
- continue;
- }
-
- %
- %
- %
- warning("STOPPING service ", services[x], " because ", svc, " is a higher priority.");
- () = service_stop(services[x]);
-
- %
- % Try just the one node.
- %
- notice("Starting ", svc, " on ", owner);
- nowner = service_start(svc, owner);
- if ((nowner > 0) or (nowner != FAIL)) {
- return nowner;
- }
- }
-
- return ERR_DOMAIN;
-}
-
-
-define move_or_start(service, node_list)
-{
- variable len;
- variable state, owner;
- variable depends;
-
- depends = service_property(service, "depend");
- if (depends != "") {
- (,,, owner, state) = service_status(depends);
- if ((owner < 0) or
- ((event_type == EVENT_NODE) and (owner == node_id) and
- (node_state == 0))) {
- debug(service, " is not runnable; dependency not met");
- ()=service_stop(service);
- return ERR_DEPEND;
- }
- }
-
- (,,, owner, state) = service_status(service);
- debug("Evaluating ", service, " state=", state, " owner=", owner);
- if ((event_type == EVENT_NODE) and (node_id == owner) and
- (node_state == NODE_OFFLINE)) {
- info("Marking service ", service, " on down member ",
- owner, " as stopped");
- if (service_stop(service) < 0) {
- return ERR_ABORT;
- }
- }
-
- len = length(node_list);
- if (len == 0) {
- notice(service, " is not runnable - restricted domain offline");
- ()=service_stop(service);
- return ERR_DOMAIN;
- }
-
- if (((event_type != EVENT_USER) and (state == "disabled")) or
- ((state == "failed") or (state == "frozen"))) {
- %
- % Commenting out this block will -not- allow you to
- % recover failed services from event scripts. Sorry.
- % All it will get you is a false log message about
- % starting this service.
- %
- % You may enable disabled services, but I recommend
- % against it.
- %
- debug(service, " is not runnable");
- return -1;
- }
-
- if (node_list[0] == owner) {
- debug(service, " is already running on best node");
- return ERR_RUNNING;
- }
-
- if ((owner >= 0) and (node_in_set(node_list, owner) == 1)) {
- notice("Moving ", service, " from ", owner,
- " to ", node_list);
- if (service_stop(service) < 0) {
- return ERR_ABORT;
- }
- } else {
- return exclusive_prioritize(service, node_list);
- }
-
- if (length(node_list) == 0) {
- return ERR_DOMAIN;
- }
- notice("Starting ", service, " on ", node_list);
- return service_start(service, node_list);
-}
-
-
-%
-% Returns the set of online nodes in preferred/shuffled order which
-% are allowed to run this service. Gives highest preference to current
-% owner if nofailback is specified.
-%
-define allowed_nodes(service)
-{
- variable anodes;
- variable online;
- variable nodes_domain;
- variable ordered, restricted, nofailback;
- variable state, owner;
- variable depends;
-
- (nofailback, restricted, ordered, nodes_domain) =
- service_domain_info(service);
-
- (,,, owner, state) = service_status(service);
-
- anodes = nodes_online();
-
- % Shuffle the array so we don't start all services on the same
- % node. TODO - add RR, Least-services, placement policies...
- online = shuffle(anodes);
-
- if (restricted == 1) {
- anodes = intersection(nodes_domain, online);
- } else {
- % Ordered failover domains (nodes_domain) unioned with the
- % online nodes basically just reorders the online node list
- % according to failover domain priority rules.
- anodes = union(intersection(nodes_domain, online),
- online);
- }
-
- if ((nofailback == 1) or (ordered == 0)) {
-
- if ((owner < 0) or (node_in_set(anodes, owner) == 0)) {
- return anodes;
- }
-
- % Because union takes left as priority, we can
- % return the union of the current owner with the
- % allowed node list. This means the service will
- % remain on the same node it's currently on.
- return union(owner, anodes);
- }
-
- return anodes;
-}
-
-define string_list(thelist, delimiter)
-{
- variable index;
- variable output="";
-
- if (length(thelist) == 0) {
- return output;
- }
-
- for (index=0; index < length(thelist)-1; index++) {
- output=output+string(thelist[index])+delimiter;
- }
- return output+thelist[index];
-}
-
-% this function gets the smallest property from a given list of services
-% if the list only exists of one element the property itself is returned
-% if the given property is not found 0 is returned
-define services_min_attribute(services, property)
-{
- variable x;
- variable min_property=-1;
- variable tmp_property;
-
- for (x = 0; x < length(services); x++) {
- tmp_property=service_property(services[x], property);
- if (tmp_property == NULL) {
- tmp_property=0;
- } else {
- tmp_property=atoi(tmp_property);
- }
- if ((min_property < 0) or (tmp_property < min_property)) {
- min_property=tmp_property;
- }
- %debug("services_min_attribute: ",services[x]," attribute: ",min_property, "tmp: ", tmp_property, " min: ", min_property);
- }
-
- %debug("services_min_attribute: (", string_list(services, ", "),")[",property,"]: ",min_property);
-
- return min_property;
-}
-
-% This function will sort a given service_list by the given attribute name and
-% return the list
-define sorted_service_list(services, attribute)
-{
- variable work_queue={};
- variable sorted_list={}, tmp, tmp2;
- variable x, y;
- variable cur_min_prop=0;
- variable service_prop=0;
-
- y=0;
- %debug("sorted_service_list: ", strjoin(services, ", "));
- for (x=0; x<length(services); x++) {
- list_append(work_queue, string(services[x]));
- }
-
- %debug("sorted_service_list: work_queue ", string_list(work_queue, ", "));
- while (length(work_queue) > 0) {
- cur_min_prop=services_min_attribute(work_queue, attribute);
- %debug("sorted_service_list sorting services list for attribute ", attribute, " cur_min: ",cur_min_prop);
- for (x = 0; x < length(work_queue); x++) {
- service_prop=service_property(work_queue[x], "priority");
- if (service_prop == NULL) {
- service_prop=0;
- } else {
- service_prop=atoi(service_prop);
- }
- %debug("sorted_service_list: ",work_queue[x], " property[", attribute,"]: ",service_prop);
- if (cur_min_prop==service_prop) {
- %debug("sorted_service_list: adding service ",work_queue[x]," to sorted. work_queue: ", string_list(work_queue, ", "));
- list_append(sorted_list, work_queue[x]);
- %debug("sorted_service_list: sorted_list: ", string_list(sorted_list, ", "));
- %debug("sorted_service_list: removing service ",work_queue[x], " from work_queue ", string_list(work_queue, ", "));
- list_delete(work_queue, x);
- x=x-1;
- %debug("sorted_service_list: work_queue: ",string_list(work_queue, ", "));
- y=y+1;
- }
- }
- }
-
- debug("sorted_service_list ", string_list(sorted_list, ", "));
- return sorted_list;
-}
-
-define sortedservices_node_event_handler(services, attribute) {
- variable x;
- variable nodes;
-
- services=sorted_service_list(services, attribute);
- for (x = 0; x < length(services); x++) {
- debug("Executing sortedservices node event handler for service: ", services[x]);
- nodes = allowed_nodes(services[x]);
- ()=move_or_start(services[x], nodes);
- }
-}
-
-define default_node_event_handler()
-{
- variable services = service_list();
- variable x;
- variable nodes;
-
- debug("Executing default node event handler");
- for (x = 0; x < length(services); x++) {
- nodes = allowed_nodes(services[x]);
- ()=move_or_start(services[x], nodes);
- }
-}
-
-
-define default_service_event_handler()
-{
- variable services = service_list();
- variable x, excl, len;
- variable depends;
- variable depend_mode;
- variable policy;
- variable nodes;
- variable tmp;
- variable owner;
- variable state;
- variable d_trans, s_trans;
- variable s_state;
-
- debug("Executing default service event handler");
-
- if (service_state == "recovering") {
-
- policy = service_property(service_name, "recovery");
- debug("Recovering",
- " Service: ", service_name,
- " Last owner: ", service_last_owner,
- " Policy: ", policy,
- " RTE: ", service_restarts_exceeded);
-
- if (policy == "disable") {
- () = service_stop(service_name, 1);
- return;
- }
-
- nodes = allowed_nodes(service_name);
- if (policy == "restart" and service_restarts_exceeded == 0) {
- nodes = union(service_last_owner, nodes);
- } else {
- % relocate
- tmp = subtract(nodes, service_last_owner);
- if (length(tmp) == 0) {
- () = service_stop(service_name,0);
- return;
- }
-
- nodes = union(tmp, service_last_owner);
- }
-
- ()=move_or_start(service_name, nodes);
- }
-
- %
- % Simplistic dependency handling
- %
- len = length(services);
- for (x = 0; x < len; x++) {
- if (service_name == services[x]) {
- % don't do anything to ourself!
- continue;
- }
-
- depends = service_property(services[x], "depend");
- depend_mode = service_property(services[x], "depend_mode");
-
- % No dependency; do nothing
- if (depends != service_name) {
- continue;
- }
-
- (d_trans,,,,, owner, state) = service_status(services[x], 1);
- if ((service_state == "started") and (owner < 0) and
- (state == "stopped")) {
- info("Dependency met; starting ", services[x]);
- nodes = allowed_nodes(services[x]);
- ()=move_or_start(services[x], nodes);
- continue;
- }
-
- % service died - stop service(s) that depend on the dead
- if ((service_owner < 0) and (owner >= 0) and
- (depend_mode != "soft")) {
-
- % grab the -current- state of the service here
- % If the service is running, and its dependent service
- % as above is running and the dependent service was
- % started at or after the service, then stopping it
- % will result in unwanted service outage.
- (s_trans,,,,,, s_state) = service_status(service_name, 1);
- if ((s_state == "started") and (state == "started") and
- (d_trans >= s_trans)) {
- %debug("S:", service_name, " trans ", s_trans);
- %debug("D:", services[x], " trans ", d_trans);
-
- debug("Skipping ", services[x],
- "; restart not needed");
- continue;
- }
-
- info("Dependency lost; stopping ", services[x]);
- ()=service_stop(services[x]);
- }
- }
-
- if (service_state == "recovering") {
- return;
- }
-
- %
- % Try to restart exclusive service which might have been recently
- % stopped in order to make room for other exclusive services.
- %
- % Note that as a side effect, exclusive services (>=2) can't be
- % stopped with clusvcadm -s; they will just pop right back - you
- % must disable them if want them to stay stopped.
- %
- % This code has a side effect of brute-forcing the lowest-priority
- % exclusive service offline in a cascaded fashion.
- %
- for (x = 0; x < len; x++) {
- if (service_name == services[x]) {
- % don't do anything to ourself!
- continue;
- }
-
- excl = atoi(service_property(services[x], "exclusive"));
- % non-exclusive or highest-prio (1) shouldn't get here
- if ((excl == 0) or (excl == 1)) {
- continue;
- }
-
- (,,, owner, state) = service_status(services[x]);
- if (state == "stopped") {
- info("Restarting stopped exclusive priority ",
- excl, " service ", services[x]);
- nodes = allowed_nodes(services[x]);
- ()=move_or_start(services[x], nodes);
- }
- }
-}
-
-define default_config_event_handler()
-{
- debug("Executing default config event handler");
-}
-
-define default_user_event_handler()
-{
- variable ret;
- variable nodes;
- variable reordered;
- variable x;
- variable target = user_target;
- variable found = 0;
- variable owner, state;
-
- nodes = allowed_nodes(service_name);
- (,,, owner, state) = service_status(service_name);
-
- if (user_request == USER_RESTART) {
-
- if (owner >= 0) {
- reordered = union(owner, nodes);
- nodes = reordered;
- }
-
- notice("Stopping ", service_name, " for relocate to ", nodes);
-
- found = service_stop(service_name);
- if (found < 0) {
- return ERR_ABORT;
- }
-
- ret = move_or_start(service_name, nodes);
-
- } else if ((user_request == USER_RELOCATE) or
- (user_request == USER_ENABLE)) {
-
- if (user_target > 0) {
- for (x = 0; x < length(nodes); x++) {
- %
- % Put the preferred node at the front of the
- % list for a user-relocate operation
- %
- if (nodes[x] == user_target) {
- reordered = union(user_target, nodes);
- nodes = reordered;
- found = 1;
- }
- }
-
- if (found == 0) {
- warning("User specified node ", user_target,
- " is offline");
- }
- }
-
- if ((owner >= 0) and (user_request == USER_RELOCATE)) {
- if (service_stop(service_name) < 0) {
- return ERR_ABORT;
- }
-
- %
- % The current owner shouldn't be the default
- % for a relocate operation
- %
- reordered = subtract(nodes, owner);
- nodes = union(reordered, owner);
- }
-
- ret = move_or_start(service_name, nodes);
-
- } else if (user_request == USER_DISABLE) {
-
- ret = service_stop(service_name, 1);
-
- } else if (user_request == USER_STOP) {
-
- ret = service_stop(service_name);
-
- } else if (user_request == USER_FREEZE) {
-
- ret = service_freeze(service_name);
-
- } else if (user_request == USER_UNFREEZE) {
-
- ret = service_unfreeze(service_name);
-
- } else if (user_request == USER_MIGRATE) {
-
- ret = service_migrate(service_name, user_target);
-
- } else if (user_request == USER_CONVALESCE) {
-
- ret = service_convalesce(service_name);
-
- }
-
- return ret;
-}
-
-if (event_type == EVENT_NODE)
- sortedservices_node_event_handler(service_list(), "priority");
-if (event_type == EVENT_SERVICE)
- default_service_event_handler();
-if (event_type == EVENT_CONFIG)
- default_config_event_handler();
-if (event_type == EVENT_USER)
- user_return=default_user_event_handler();
-
diff --git a/rgmanager/src/resources/follow-service.sl b/rgmanager/src/resources/follow-service.sl
deleted file mode 100644
index 6c17160..0000000
--- a/rgmanager/src/resources/follow-service.sl
+++ /dev/null
@@ -1,157 +0,0 @@
-% follow-service.sl
-%
-% Description: Implements the "follow service" mechanism based on the Red Hat RIND event
-% scripting mechanism.
-%
-% Author: Marc Grimme, Mark Hlawatschek, October 2008
-% Support: support(a)atix.de
-% License: GNU General Public License (GPL), version 2 or later
-% Copyright: (c) 2008-2012 ATIX AG
-
-
-debug("*** follow-service.sl");
-
-
-%
-% Returns a list of nodes for the given service that are online and in the failoverdomain.
-%
-define nodelist_online(service_name) {
- variable nodes, nofailback, restricted, ordered, node_list;
- nodes=nodes_online();
-
- (nofailback, restricted, ordered, node_list) = service_domain_info(service_name);
-
- if ((node_list == NULL) or (node_list == 0)) {
- debug("service ",service_name, " has no failover domain. Taking all available nodes: ", nodes);
- return nodes;
- } else {
- debug("service ",service_name, " has a failover domain. Taking intersection with available nodes: ", nodes, " => ", node_list);
- return intersection(nodes, node_list);
- }
-}
-
-%
-% Idea:
-% General purpose function of a construct when Service(svc1) and Service(svc2)
-% should not be running on the same node even after failover.
-% There are to options to influence the behaviour. If both services have to be
-% running on the same node (only one node is left in the failovergroup) what
-% service is the master and should both services be running or only the master
-% service survives. If master is not svc1 or svc2 both service might run on the
-% same node. If master is either svc1 or svc2 the specified one will be the
-% surviving service.
-% If followslave is not 0 the svc1 always follows svc2. That means it will be
-% started on on the same node as svc1. And if available svc2 will be relocated
-% to any other node.
-%
-define follow_service(svc1, svc2, master) %, followslave)
-{
- variable state_svc1, state_svc2, owner_svc1, owner_svc2;
- variable nodes1, nodes2, allowed;
-
- debug("*** FOLLOW_SERVICE: follow_service(",svc1,", ",svc2,", ", master, ")");
- debug("*** FOLLOW_SERVICE: event_type: ", event_type, ", service_name: ", service_name, ", service_state: ", service_state);
-
- %
- % setup the master
- %
- if ((master != svc1) and (master != svc2)) {
- debug("*** FOLLOW_SERVICE: master=NULL");
- master=NULL;
- }
-
- % get infos we need to decide further
- (,,, owner_svc1, state_svc1) = service_status(svc1);
- (,,, owner_svc2, state_svc2) = service_status(svc2);
- nodes1 = nodelist_online(svc1);
- nodes2 = nodelist_online(svc2);
- debug("*** FOLLOW_SERVICE: service_status(",svc1,"): ", state_svc1);
- debug("*** FOLLOW_SERVICE: owner_svc1: ", owner_svc1, ", owner_svc2: ", owner_svc2, ", nodes1: ", nodes1, ", nodes2: ", nodes2);
-
- if (((event_type == EVENT_NODE) and (owner_svc1 == node_id) and (node_state == NODE_OFFLINE) and (owner_svc2 >=0)) or
- ((event_type == EVENT_SERVICE) and (service_name == svc1) and (service_state == "recovering" ) and (owner_svc2 >= 0))) {
- %
- % uh oh, the owner of the master server died. Restart it
- % on the node running the slave server or if we should not
- % follow the slave start it somewhere else.
- % We should end up here if svc1 has to be restarted
-
- %
- % If this was a service event, don't execute the default event
- % script trigger after this script completes.
- %
- if (event_type == EVENT_SERVICE) {
- stop_processing();
- }
- % were to start svc2
- allowed=subtract(nodes2, owner_svc2);
- if (length(allowed) > 1) {
- allowed=subtract(allowed, service_last_owner);
- }
- debug("*** FOLLOW SERVICE: service event triggered following svc2 to ",owner_svc2, " svc2 on : ",allowed);
-
- % either svc1 is the master or there are node were to start svc2
- if ((master == svc1) or (length(allowed) > 0)) {
- ()=service_start(svc1, owner_svc2);
- }
- % either svc2 is the master or there are node were to start svc2
- if ((master == svc2) or (length(allowed) > 0)) {
- ()=service_stop(svc2);
- ()=service_start(svc2, allowed);
- }
- }
- else if (((event_type == EVENT_NODE) and (owner_svc2 == node_id) and (node_state == NODE_OFFLINE) and (owner_svc2 >=0)) or
- ((event_type == EVENT_SERVICE) and (service_name == svc2) and (service_state == "recovering" ) and (owner_svc1 >= 0))) {
- %
- % uh oh, the owner of the svc2 died. Restart it
- % on any other node but not the one running the svc1.
- % If svc1 is the only one left only start it there
- % if master==svc2
- %
- % Just relocate svc2 or if svc2 is master stop svc1 and start svc2 on owner_svc1
-
- %
- % If this was a service event, don't execute the default event
- % script trigger after this script completes.
- %
-
- if (event_type == EVENT_SERVICE) {
- stop_processing();
- }
-
- allowed=subtract(nodes2, owner_svc1);
- if (length(allowed) > 1) {
- allowed=subtract(allowed, service_last_owner);
- }
-
- debug("*** FOLLOW SERVICE: service event triggered relocating svc2 to ",allowed, " svc1 on : ",owner_svc1);
-
- if (length(allowed) > 0) {
- ()=service_stop(svc2);
- ()=service_start(svc2, allowed);
- } else if (master == svc2) {
- ()=service_stop(svc1);
- ()=service_start(svc2, owner_svc1);
- }
- }
- else if (((event_type == EVENT_SERVICE) and (service_state == "started") and (owner_svc2 == owner_svc1) and (owner_svc1 > 0) and (owner_svc2 > 0)) or
- ((event_type == EVENT_CONFIG) and (owner_svc2 == owner_svc1))) {
- allowed=subtract(nodes2, owner_svc1);
- debug("*** FOLLOW SERVICE: service event both running on same node triggered.", allowed);
- if (length(allowed) > 0) {
- %()=service_stop(svc1);
- %()=service_start(svc1, owner_svc2);
- ()=service_stop(svc2);
- ()=service_start(svc2, allowed);
- } else if ((master == svc2) and (owner_svc2 > 0)){
- debug("*** FOLLOW SERVICE: will stop service .", svc1);
- ()=service_stop(svc1);
- } else if ((master == svc1) and (owner_svc1 > 0)) {
- debug("*** FOLLOW SERVICE: will stop service .", svc2);
- ()=service_stop(svc2);
- } else {
- debug("*** FOLLOW SERVICE: both services running on the same node or only one is running.", allowed, ", ", master);
- }
- }
- return;
-}
diff --git a/rgmanager/src/utils/Makefile b/rgmanager/src/utils/Makefile
deleted file mode 100644
index 390fe76..0000000
--- a/rgmanager/src/utils/Makefile
+++ /dev/null
@@ -1,73 +0,0 @@
-TARGET1= clubufflush
-TARGET2= clufindhostname
-TARGET3= clustat
-TARGET4= clusvcadm
-TARGET5= clulog
-TARGET6= clunfslock
-
-SBINDIRT=$(TARGET1) $(TARGET2) $(TARGET3) $(TARGET4) $(TARGET5) $(TARGET6)
-
-all: depends ${TARGET1} ${TARGET2} ${TARGET3} ${TARGET4} ${TARGET5} ${TARGET6}
-
-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 -D_GNU_SOURCE
-CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${dlmincdir}
-CFLAGS += -I${logtincdir} -I${ncursesincdir}
-CFLAGS += -I$(S)/../../include
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L../clulib -lclulib
-LDFLAGS += -L${libdir}
-
-LDDEPS += ../clulib/libclulib.a
-
-CCS_LDFLAGS += -L${ccslibdir} -lccs
-CMAN_LDFLAGS += -L${cmanlibdir} -lcman
-LOGSYS_LDFLAGS += -L${logtlibdir} -llogthread
-NCURSES_LDFLAGS += -L${ncurseslibdir} -lncurses
-PTHREAD_LDFLAGS += -lpthread
-
-OBJS1= $(TARGET1).o
-OBJS2= $(TARGET2).o
-OBJS3= $(TARGET3).o
-OBJS4= $(TARGET4).o
-OBJS5= $(TARGET5).o
-
-${TARGET1}: ${OBJS1} ${LDDEPS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-${TARGET2}: ${OBJS2} ${LDDEPS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-${TARGET3}: ${OBJS3} ${LDDEPS}
- $(CC) -o $@ $^ $(CCS_LDFLAGS) $(CMAN_LDFLAGS) \
- $(NCURSES_LDFLAGS) $(PTHREAD_LDFLAGS) \
- $(LOGSYS_LDFLAGS) $(LDFLAGS)
-
-${TARGET4}: ${OBJS4} ${LDDEPS}
- $(CC) -o $@ $^ $(CMAN_LDFLAGS) $(PTHREAD_LDFLAGS) \
- $(LOGSYS_LDFLAGS) $(LDFLAGS)
-
-${TARGET5}: ${OBJS5} ${LDDEPS}
- $(CC) -o $@ $^ $(CCS_LDFLAGS) \
- $(LOGSYS_LDFLAGS) $(LDFLAGS)
-
-${TARGET6}:
- cp $(S)/${TARGET6}.sh ${TARGET6}
- chmod 755 ${TARGET6}
-
-depends:
- $(MAKE) -C ../clulib all
-
-clean: generalclean
-
--include $(OBJS1:.o=.Tpo)
--include $(OBJS2:.o=.Tpo)
--include $(OBJS3:.o=.Tpo)
--include $(OBJS4:.o=.Tpo)
--include $(OBJS5:.o=.Tpo)
diff --git a/rgmanager/src/utils/clubufflush.c b/rgmanager/src/utils/clubufflush.c
deleted file mode 100644
index 3eaed48..0000000
--- a/rgmanager/src/utils/clubufflush.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/** @file
- * Calls ioctl to invalidate/flush buffers on a given device.
- *
- * Author: Gregory P. Myrdal <Myrdal(a)MissionCriticalLinux.Com>
- *
- * invalidatebuffers.c
- */
-
-/*
- * Version string that is filled in by CVS
- */
-static const char *version __attribute__ ((unused)) = "$Revision$";
-
-/*
- * System includes
- */
-#include <unistd.h>
-#include <stdio.h>
-#include <syslog.h>
-#include <linux/fs.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-#ifdef __NFDBITS
-#undef __NFDBITS
-#endif
-
-#ifdef __FDMASK
-#undef __FDMASK
-#endif
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <stdlib.h>
-/*
- * Cluster includes
- */
-#include <logging.h>
-
-/***************************************************************************
- *
- * Functions
- *
- ***************************************************************************/
-
-/**
- * printUsage
- *
- * Print out usage string to stdout.
- */
-static void
-printUsage(char *progName)
-{
- printf("Usage: %s [-h] [-f device]\n", progName);
-}
-
-/***************************************************************************
- *
- * Main
- *
- ***************************************************************************/
-int
-main(int argc, char **argv)
-{
- int opt;
- uid_t uid;
- char *devicename = (char *)NULL;
- int fd;
-
- uid=getuid();
- if (uid)
- {
- printf("%s should only be run as user root\n", argv[0]);
- exit(1);
- }
-
- while ((opt = getopt(argc, argv, "f:h")) != -1)
- {
- switch (opt)
- {
- case 'f': // stop services
- devicename = strdup(optarg);
- break;
-
- case 'h': // command line help
- printUsage(argv[0]);
- exit(0);
-
- default: // unknown option
- printUsage(argv[0]);
- exit(0);
- }
- }
-
- if (devicename == (char *)NULL)
- {
- printUsage(argv[0]);
- exit(1);
- }
-
- fd = open(devicename, O_RDONLY, 0);
-
- if (fd < 0)
- {
- printf("Cannot open %s for flushing: %s\n",
- devicename, strerror(errno));
- exit(1);
- }
-
- if (ioctl(fd, BLKFLSBUF, 0) < 0)
- {
- printf("Cannot flush %s: %s\n", devicename, strerror(errno));
- exit(1);
- }
- free(devicename);
- close(fd);
-
- exit(0);
-}
diff --git a/rgmanager/src/utils/clufindhostname.c b/rgmanager/src/utils/clufindhostname.c
deleted file mode 100644
index f8bf7fd..0000000
--- a/rgmanager/src/utils/clufindhostname.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/** @file
- * Utility/command to return name found by gethostbyname and gethostbyaddr.
- *
- * Author: Richard Rabbat <rabbat(a)missioncriticallinux.com>
- * IPv6 support added 7/2006
- */
-#include <netdb.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <arpa/inet.h>
-#include <string.h>
-
-static void
-usage(char *progname)
-{
- fprintf(stderr, "Usage: %s [-i ip_addr] [-n ip_name]\n", progname);
-}
-
-int
-main(int argc, char **argv)
-{
- struct hostent *hp;
- void *ptr;
- struct in_addr addr4;
- struct in6_addr addr6;
- int opt, size, family, ret;
- char *sep;
-
- if (argc != 3) {
- usage(argv[0]);
- exit(1);
- }
-
- while ((opt = getopt(argc, argv, "i:n:")) != EOF) {
- switch (opt) {
- case 'i':
- /* Check for IPv4 address */
- sep = strchr(optarg, '.');
- if (sep) {
- family = AF_INET;
- ptr = &addr4;
- size = sizeof(addr4);
- } else {
- family = AF_INET6;
- ptr = &addr6;
- size = sizeof(addr6);
- }
-
- ret = inet_pton(family, optarg, ptr);
- if (ret <= 0) {
- if (ret < 0)
- perror("inet_pton");
- exit(2);
- }
-
- if (!(hp = gethostbyaddr(ptr, size, family))) {
- exit(2);
- } else {
- fprintf(stdout, "%s\n", hp->h_name);
- exit(0);
- }
- break;
- case 'n':
- if (!(hp = gethostbyname(argv[2]))) {
- exit(2);
- } else {
- fprintf(stdout, "%s\n", hp->h_name);
- exit(0);
- }
- break;
- default:
- break;
- }
- }
- exit(0);
-}
diff --git a/rgmanager/src/utils/clulog.c b/rgmanager/src/utils/clulog.c
deleted file mode 100644
index 86da8ce..0000000
--- a/rgmanager/src/utils/clulog.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/** @file
- * Utility for logging arbitrary strings to the cluster log file via syslog.
- *
- * Author: Lon Hohberger <lhh at redhat.com>
- * Based on original code by: Jeff Moyer <jmoyer at redhat.com>
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <limits.h>
-#include <libgen.h>
-#include <getopt.h>
-#include <string.h>
-#include <ccs.h>
-#include <logging.h>
-
-static void
-usage(char *progname)
-{
- fprintf(stdout, "%s [-m logname] -s severity \"message text\"\n", progname);
- exit(0);
-}
-
-
-int
-main(int argc, char **argv)
-{
- int opt, ccsfd;
- int severity = -1;
-
- char *logmsg = NULL;
- char *myname = NULL;
-
- while ((opt = getopt(argc, argv, "m:l:s:h")) != EOF) {
- switch(opt) {
- case 'l':
- case 's':
- severity = atoi(optarg);
- break;
- case 'm':
- myname = optarg;
- break;
- case 'h':
- default:
- usage(argv[0]);
- return 0;
- }
- }
-
- logmsg = argv[optind];
-
- if (severity < 0)
- severity = SYSLOGLEVEL;
-
- init_logging((char *)"rgmanager", 1, severity);
- ccsfd = ccs_connect();
- setup_logging(ccsfd);
- ccs_disconnect(ccsfd);
-
- if (myname && strcmp(myname, "rgmanager")) {
- logt_print(severity, "[%s] %s\n", myname, logmsg);
- } else {
- logt_print(severity, "%s\n", logmsg);
- }
-
- close_logging();
- return 0;
-}
diff --git a/rgmanager/src/utils/clunfslock.sh b/rgmanager/src/utils/clunfslock.sh
deleted file mode 100644
index 67b2d6d..0000000
--- a/rgmanager/src/utils/clunfslock.sh
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/bin/bash
-#
-# rpc.statd -H $0 to enable. This provides the HA-callout capability
-# for RHCS-managed NFS services. Note that you must edit
-# /etc/sysconfig/nfs in order to make this work; clumanager/rgmanager
-# will not interfere with a running nfs statd.
-#
-# Arg 3 (server as known to client) does not work; it's always 127.0.0.1
-# so we traverse all cluster mount points.
-#
-
-clustered_mounts()
-{
- declare dev mp
-
- while read dev mp; do
- if [ "${dev:0:4}" != "/dev" ]; then
- continue
- fi
-
- # XXX Need clumanager to create this on mount
- if [ -d "$mp/.clumanager" ]; then
- echo $dev $mp
- fi
- done < <(cat /proc/mounts | awk '{print $1,$2}')
-}
-
-
-add-client()
-{
- declare dev mp
-
- while read dev mp; do
- [ -d "$mp/.clumanager/statd/sm" ] || \
- mkdir -p $mp/.clumanager/statd/sm
- touch $mp/.clumanager/statd/sm/$1
- done < <(clustered_mounts)
-}
-
-
-del-client()
-{
- while read $dev $mp; do
- [ -d "$mp/.clumanager/statd/sm" ] || \
- mkdir -p $mp/.clumanager/statd/sm
- rm -f $mp/.clumanager/statd/sm/$1
- done < <(clustered_mounts)
-}
-
-case "$1" in
- add-client)
- :
- ;;
- del-client)
- :
- ;;
- *)
- echo "Usage: $0 <add-client|del-client> <host> [server]"
- exit 0
-esac
-
-
-if [ -z "$2" ]; then
- echo "Usage: $0 <add-client|del-client> <host> [server]"
- exit 1
-fi
-
-$1 $2 $3
-exit 0
diff --git a/rgmanager/src/utils/clustat.c b/rgmanager/src/utils/clustat.c
deleted file mode 100644
index f736b51..0000000
--- a/rgmanager/src/utils/clustat.c
+++ /dev/null
@@ -1,1216 +0,0 @@
-#include <members.h>
-#include <msgsimple.h>
-#include <resgroup.h>
-#include <platform.h>
-#include <libgen.h>
-#include <ncurses.h>
-#include <term.h>
-#include <rg_types.h>
-#include <termios.h>
-#include <ccs.h>
-#include <libcman.h>
-#include <signal.h>
-#include <message.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#define FLAG_UP 0x1
-#define FLAG_LOCAL 0x2
-#define FLAG_RGMGR 0x4
-#define FLAG_NOCFG 0x8 /* Shouldn't happen */
-#define FLAG_QDISK 0x10
-#define FLAG_RGMAST 0x20 /* for RIND */
-
-#define RG_VERBOSE 0x1
-
-#define QSTAT_ONLY 1
-#define VERSION_ONLY 2
-#define NODEID_ONLY 3
-
-
-int running = 1;
-int dimx = 80, dimy = 24, stdout_is_tty = 0;
-int rgmanager_master_present = 0;
-
-static void
-term_handler(int sig)
-{
- running = 0;
-}
-
-
-typedef struct {
- int rgl_count;
- rg_state_t rgl_states[0];
-} rg_state_list_t;
-
-
-static int
-rg_name_sort(const void *left, const void *right)
-{
- return strcmp(((rg_state_t *)left)->rs_name,
- ((rg_state_t *)right)->rs_name);
-}
-
-
-static int
-member_id_sort(const void *left, const void *right)
-{
- cman_node_t *l = (cman_node_t *)left;
- cman_node_t *r = (cman_node_t *)right;
-
- if (l->cn_nodeid < r->cn_nodeid)
- return -1;
- if (l->cn_nodeid > r->cn_nodeid)
- return 1;
- return 0;
-}
-
-
-static void
-flag_rgmanager_nodes(cluster_member_list_t *cml)
-{
- msgctx_t ctx;
- int max = 0, n;
- generic_msg_hdr *msgp;
- fd_set rfds;
-
- struct timeval tv;
-
- if (msg_open(MSG_SOCKET, 0, 0, &ctx, 10) < 0) {
- //perror("msg_open");
- return;
- }
-
- msg_send_simple(&ctx, RG_STATUS_NODE, 0, 0);
-
- while (1) {
- FD_ZERO(&rfds);
- msg_fd_set(&ctx, &rfds, &max);
- tv.tv_sec = 10;
- tv.tv_usec = 0;
-
- n = select(max+1, &rfds, NULL, NULL, &tv);
- if (n == 0) {
- fprintf(stderr, "Timed out waiting for a response "
- "from Resource Group Manager\n");
- break;
- }
-
- if (n < 0) {
- if (errno == EAGAIN ||
- errno == EINTR)
- continue;
- fprintf(stderr, "Failed to receive "
- "service data: select: %s\n",
- strerror(errno));
- break;
- }
-
- n = msg_receive_simple(&ctx, &msgp, tv.tv_sec);
-
- if (n < 0) {
- if (errno == EAGAIN)
- continue;
- perror("msg_receive_simple");
- break;
- }
- if (n < sizeof(generic_msg_hdr)) {
- printf("Error: Malformed message\n");
- break;
- }
-
- if (!msgp) {
- printf("Error: no message?!\n");
- break;
- }
-
- swab_generic_msg_hdr(msgp);
-
- if (msgp->gh_command == RG_FAIL) {
- printf("Member states unavailable: %s\n",
- rg_strerror(msgp->gh_arg1));
- free(msgp);
- msg_close(&ctx);
- return;
- }
-
- if (msgp->gh_command == RG_SUCCESS) {
- free(msgp);
- break;
- }
-
- for (n = 0; n < cml->cml_count; n++) {
- if (cml->cml_members[n].cn_nodeid != msgp->gh_arg1)
- continue;
- cml->cml_members[n].cn_member |= FLAG_RGMGR;
- if (msgp->gh_arg2) {
- rgmanager_master_present = 1;
- cml->cml_members[n].cn_member |= FLAG_RGMAST;
- }
- }
-
- free(msgp);
- msgp = NULL;
- }
-
- msg_send_simple(&ctx, RG_SUCCESS, 0, 0);
- msg_close(&ctx);
-
- return;
-}
-
-
-static rg_state_list_t *
-rg_state_list(int local_node_id, int fast)
-{
- msgctx_t ctx;
- int max = 0, n, x;
- rg_state_list_t *rsl = NULL;
- generic_msg_hdr *msgp = NULL;
- rg_state_msg_t *rsmp = NULL;
- fd_set rfds;
-
- struct timeval tv;
-
- if (msg_open(MSG_SOCKET, 0, 0, &ctx, 10) < 0) {
- //perror("msg_open");
- return NULL;
- }
-
- msg_send_simple(&ctx, RG_STATUS, fast, 0);
-
- rsl = malloc(sizeof(rg_state_list_t));
- if (!rsl) {
- printf("Try again, out of memory\n");
- exit(0);
- }
- memset(rsl, 0, sizeof(rg_state_list_t));
-
- while (1) {
- FD_ZERO(&rfds);
- msg_fd_set(&ctx, &rfds, &max);
- tv.tv_sec = 10;
- tv.tv_usec = 0;
-
- n = select(max+1, &rfds, NULL, NULL, &tv);
- if (n == 0) {
- fprintf(stderr, "Timed out waiting for a response "
- "from Resource Group Manager\n");
- break;
- }
-
- if (n < 0) {
- if (errno == EAGAIN ||
- errno == EINTR)
- continue;
- fprintf(stderr, "Failed to receive "
- "service data: select: %s\n",
- strerror(errno));
- break;
- }
-
- n = msg_receive_simple(&ctx, &msgp, tv.tv_sec);
-
- if (n < 0) {
- if (errno == EAGAIN)
- continue;
- perror("msg_receive_simple");
- break;
- }
- if (n < sizeof(generic_msg_hdr)) {
- printf("Error: Malformed message\n");
- break;
- }
-
- if (!msgp) {
- printf("Error: no message?!\n");
- break;
- }
-
- swab_generic_msg_hdr(msgp);
-
- if (msgp->gh_command == RG_FAIL) {
- printf("Service states unavailable: %s\n",
- rg_strerror(msgp->gh_arg1));
- msg_close(&ctx);
- return NULL;
- }
-
- if (msgp->gh_command == RG_SUCCESS) {
- free(msgp);
- break;
- }
-
- if (n < sizeof(*rsmp)) {
- msg_close(&ctx);
- return NULL;
- }
-
- rsmp = (rg_state_msg_t *)msgp;
-
- swab_rg_state_t(&rsmp->rsm_state);
-
- rsl->rgl_count++;
- x = sizeof(rg_state_list_t) +
- (sizeof(rg_state_t) * rsl->rgl_count);
- rsl = realloc(rsl, x);
- if (!rsl) {
- printf("Try again; out of RAM\n");
- exit(1);
- }
-
- memcpy(&rsl->rgl_states[(rsl->rgl_count-1)],
- &rsmp->rsm_state, sizeof(rg_state_t));
-
- free(msgp);
- msgp = NULL;
- }
-
- msg_send_simple(&ctx, RG_SUCCESS, 0, 0);
- msg_close(&ctx);
-
- if (!rsl->rgl_count) {
- free(rsl);
- return NULL;
- }
-
- qsort(rsl->rgl_states, rsl->rgl_count, sizeof(rg_state_t),
- rg_name_sort);
-
- return rsl;
-}
-
-
-static cluster_member_list_t *ccs_member_list(void)
-{
- int desc;
- int x;
- char buf[128];
- char *name;
- cluster_member_list_t *ret = NULL;
- cman_node_t *nodes = NULL;
-
- desc = ccs_connect();
- if (desc < 0) {
- return NULL;
- }
-
- while ((ret = malloc(sizeof(*ret))) == NULL)
- sleep(1);
-
- x = 0;
- memset(buf, 0, sizeof(buf));
-
- while (++x) {
- name = NULL;
- snprintf(buf, sizeof(buf)-1,
- "/cluster/clusternodes/clusternode[%d]/@name", x);
-
- if (ccs_get(desc, buf, &name) != 0)
- break;
-
- if (!name)
- break;
- if (!strlen(name)) {
- free(name);
- continue;
- }
-
- if (!nodes) {
- nodes = malloc(x * sizeof(cman_node_t));
- if (!nodes) {
- perror("malloc");
- ccs_disconnect(desc);
- exit(1);
- }
- } else {
- nodes = realloc(nodes, x * sizeof(cman_node_t));
- if (!nodes) {
- perror("realloc");
- ccs_disconnect(desc);
- exit(1);
- }
- }
-
- memset(&nodes[x-1], 0, sizeof(cman_node_t));
- strncpy(nodes[x-1].cn_name, name,
- sizeof(nodes[x-1].cn_name));
- free(name);
-
- /* Add node ID */
- snprintf(buf, sizeof(buf)-1,
- "/cluster/clusternodes/clusternode[%d]/@nodeid", x);
- if (ccs_get(desc, buf, &name) == 0) {
- nodes[x-1].cn_nodeid = atoi(name);
- free(name);
- }
-
- ret->cml_count = x;
- }
-
- ccs_disconnect(desc);
-
- ret->cml_members = nodes;
- if (nodes) {
- qsort(ret->cml_members, ret->cml_count,
- sizeof(cman_node_t), member_id_sort);
- }
-
- return ret;
-}
-
-
-static void
-flag_nodes(cluster_member_list_t *all, cluster_member_list_t *these,
- uint8_t flag)
-{
- int x;
- cman_node_t *m;
-
- for (x=0; x<all->cml_count; x++) {
-
- m = memb_name_to_p(these, all->cml_members[x].cn_name);
-
- if (m && m->cn_member) {
- all->cml_members[x].cn_nodeid = m->cn_nodeid;
- all->cml_members[x].cn_member |= flag;
- }
- }
-}
-
-
-static cluster_member_list_t *
-add_missing(cluster_member_list_t *all, cluster_member_list_t *these)
-{
- int x, y, addflag;
- cman_node_t *m, *nn;
-
- if (!these)
- return all;
-
- for (x=0; x<these->cml_count; x++) {
-
- m = NULL;
- for (y = 0; y < all->cml_count; y++) {
- if (!strcmp(all->cml_members[y].cn_name,
- these->cml_members[x].cn_name))
- m = &all->cml_members[y];
- }
-
- if (!m) {
- all->cml_members = realloc(all->cml_members,
- (all->cml_count+1) *
- sizeof(cman_node_t));
- if (!all->cml_members) {
- perror("realloc");
- exit(1);
- }
-
- nn = &all->cml_members[all->cml_count];
-
- memcpy(nn, &these->cml_members[x],
- sizeof(cman_node_t));
-
- if (nn->cn_nodeid == 0) { /* quorum disk? */
- addflag = FLAG_QDISK;
- } else {
- addflag = FLAG_NOCFG;
- }
-
- if (nn->cn_member) {
- nn->cn_member = FLAG_UP | addflag;
- } else {
- nn->cn_member = addflag;
- }
- ++all->cml_count;
-
- }
- }
-
- return all;
-}
-
-
-static const char *
-my_memb_id_to_name(cluster_member_list_t *members, int memb_id)
-{
- int x;
-
- if (memb_id == 0)
- return "none";
-
- for (x = 0; x < members->cml_count; x++) {
- if (members->cml_members[x].cn_nodeid == memb_id)
- return members->cml_members[x].cn_name;
- }
-
- return "unknown";
-}
-
-
-static void
-_txt_rg_state(rg_state_t *rs, cluster_member_list_t *members, int flags,
- int svcsize, int nodesize, int statsize)
-{
- char owner[MAXHOSTNAMELEN+1];
- char state_string[255] = "";
- char flags_string[16] = "";
- char *name = rs->rs_name, *ptr;
- int l;
-
- if (stdout_is_tty) {
- ptr = strchr(rs->rs_name, ':');
- if (ptr) {
- l = (int)(ptr - rs->rs_name);
- if ((l == 7) && /* strlen("service") == 7 */
- (strncmp(rs->rs_name, "service", l) == 0))
- name = ptr+1;
- }
- }
-
- memset(owner, 0, sizeof(owner));
-
- if (rs->rs_state == RG_STATE_STOPPED ||
- rs->rs_state == RG_STATE_DISABLED ||
- rs->rs_state == RG_STATE_ERROR ||
- rs->rs_state == RG_STATE_FAILED) {
-
- snprintf(owner, sizeof(owner)-1, "(%-.*s)", nodesize-2,
- my_memb_id_to_name(members, rs->rs_last_owner));
- } else {
-
- snprintf(owner, sizeof(owner)-1, "%-.*s", nodesize,
- my_memb_id_to_name(members, rs->rs_owner));
- }
-
- /* Show a frozen service */
- if (rs->rs_flags) {
- rg_flags_str(flags_string, sizeof(flags_string), rs->rs_flags,
- NULL);
-
- snprintf(state_string, sizeof(state_string),
- "%-*.*s[%s]", (int)(statsize-(2+strlen(flags_string))),
- (int)(statsize-(2+strlen(flags_string))),
- rg_state_str(rs->rs_state), flags_string);
- } else {
- snprintf(state_string, sizeof(state_string),
- "%-*.*s", statsize, statsize,
- rg_state_str(rs->rs_state));
- }
-
- printf(" %-*.*s %-*.*s %-*.*s\n",
- svcsize, svcsize, rs->rs_name,
- nodesize, nodesize, owner,
- statsize, statsize, state_string);
-}
-
-
-static void
-_txt_rg_state_v(rg_state_t *rs, cluster_member_list_t *members, int flags)
-{
- time_t t;
- char flags_string[255] = "";
-
- rg_flags_str(flags_string, sizeof(flags_string), rs->rs_flags,
- (char *)", ");
-
- printf("Service Name : %s\n", rs->rs_name);
- printf(" Current State : %s (%d)\n",
- rg_state_str(rs->rs_state), rs->rs_state);
- if (rs->rs_flags)
- printf(" Flags : %s (%d)\n",
- flags_string, rs->rs_flags);
- else
- printf(" Flags : none (%d)\n",
- rs->rs_flags);
- printf(" Owner : %s\n",
- my_memb_id_to_name(members, rs->rs_owner));
- printf(" Last Owner : %s\n",
- my_memb_id_to_name(members, rs->rs_last_owner));
-
- t = (time_t)(rs->rs_transition);
- printf(" Last Transition : %s\n", ctime(&t));
-}
-
-
-static void
-txt_rg_state(rg_state_t *rs, cluster_member_list_t *members, int flags, int svcsize,
- int nodesize, int statsize)
-{
- if (flags & RG_VERBOSE)
- _txt_rg_state_v(rs, members, flags);
- else
- _txt_rg_state(rs, members, flags, svcsize, nodesize, statsize);
-}
-
-
-static void
-xml_rg_state(rg_state_t *rs, cluster_member_list_t *members, int flags)
-{
- char time_str[32];
- char flags_string[255] = "";
- int x;
- time_t t;
-
- /* Chop off newlines */
- t = (time_t)(rs->rs_transition);
- ctime_r(&t, time_str);
- for (x = 0; time_str[x]; x++) {
- if (time_str[x] < 32) {
- time_str[x] = 0;
- break;
- }
- }
-
- printf(" <group name=\"%s\" state=\"%d\" state_str=\"%s\""
- " flags=\"%d\" flags_str=\"%s\""
- " owner=\"%s\" last_owner=\"%s\" restarts=\"%d\""
- " last_transition=\"%llu\" last_transition_str=\"%s\"/>\n",
- rs->rs_name,
- rs->rs_state,
- rg_state_str(rs->rs_state),
- rs->rs_flags,
- rg_flags_str(flags_string, sizeof(flags_string),
- rs->rs_flags, (char *)" "),
- my_memb_id_to_name(members, rs->rs_owner),
- my_memb_id_to_name(members, rs->rs_last_owner),
- rs->rs_restarts,
- (long long unsigned)rs->rs_transition,
- time_str);
-}
-
-
-static void
-build_service_field_sizes(int cols, int *svcsize, int *nodesize, int *statsize)
-{
- int pad = 6; /* Spaces and such; newline */
-
- /* Based on 80 columns */
- *svcsize = 30;
- *nodesize = 30;
- *statsize = 14; /* uninitialized */
-
- *svcsize = (cols - (*statsize + pad)) / 2;
- *nodesize = (cols - (*statsize + pad)) / 2;
- if (*svcsize > MAXHOSTNAMELEN)
- *svcsize = MAXHOSTNAMELEN;
- if (*nodesize > MAXHOSTNAMELEN)
- *nodesize = MAXHOSTNAMELEN;
-}
-
-
-static void
-print_svc_header(int svcsize, int nodesize, int statsize)
-{
- printf(" %-*.*s %-*.*s %-*.*s\n",
- svcsize, svcsize, "Service Name",
- nodesize, nodesize, "Owner (Last)",
- statsize, statsize, "State");
- printf(" %-*.*s %-*.*s %-*.*s\n",
- svcsize, svcsize, "------- ----",
- nodesize, nodesize, "----- ------",
- statsize, statsize, "-----");
-}
-
-
-static int
-txt_rg_states(rg_state_list_t *rgl, cluster_member_list_t *members,
- char *svcname, int flags)
-{
- int x, ret = 0, svcsize, nodesize, statsize;
-
- if (!rgl || !members)
- return -1;
-
- if (svcname)
- ret = -1;
-
- build_service_field_sizes(dimx, &svcsize, &nodesize, &statsize);
-
- if (!(flags & RG_VERBOSE)) {
- if (!svcname)
- print_svc_header(svcsize, nodesize, statsize);
- } else {
- printf("Service Information\n"
- "------- -----------\n\n");
- }
-
- for (x = 0; x < rgl->rgl_count; x++) {
- if (svcname) {
- if (strcmp(rgl->rgl_states[x].rs_name, svcname)) {
- continue;
- }
- print_svc_header(svcsize, nodesize, statsize);
- }
- txt_rg_state(&rgl->rgl_states[x], members, flags,
- svcsize, nodesize, statsize);
- if (svcname) {
- switch (rgl->rgl_states[x].rs_state) {
- case RG_STATE_STARTING:
- case RG_STATE_STARTED:
- case RG_STATE_STOPPING:
- ret = 0;
- break;
- default:
- ret = rgl->rgl_states[x].rs_state;
- }
- }
- }
-
- return ret;
-}
-
-
-static int
-xml_rg_states(rg_state_list_t *rgl, cluster_member_list_t *members,
- char *svcname, int flags)
-{
- int x;
- int ret = 0;
-
- if (!rgl || !members)
- return -1;
-
- printf(" <groups>\n");
-
- for (x = 0; x < rgl->rgl_count; x++) {
- if (svcname &&
- strcmp(rgl->rgl_states[x].rs_name, svcname))
- continue;
- xml_rg_state(&rgl->rgl_states[x], members, flags);
- if (svcname) {
- switch (rgl->rgl_states[x].rs_state) {
- case RG_STATE_STARTING:
- case RG_STATE_STARTED:
- case RG_STATE_STOPPING:
- break;
- default:
- ret = rgl->rgl_states[x].rs_state;
- }
- }
- }
-
- printf(" </groups>\n");
- return ret;
-}
-
-
-static void
-txt_quorum_state(int qs)
-{
- printf("Member Status: ");
-
- if (qs) {
- printf("Quorate\n\n");
- } else {
- printf("Inquorate\n\n");
- }
-}
-
-
-static void
-txt_cluster_info(cman_cluster_t *ci)
-{
- time_t now = time(NULL);
-
- printf("Cluster Status for %s @ %s",
- ci->ci_name, ctime(&now));
-}
-
-
-static void
-xml_cluster_info(cman_cluster_t *ci)
-{
- printf(" <cluster name=\"%s\" id=\"%d\" generation=\"%d\"/>\n",
- ci->ci_name, ci->ci_number, ci->ci_generation);
-}
-
-
-static void
-xml_quorum_state(int qs)
-{
- /* XXX output groupmember attr (carry over from RHCS4) */
- printf(" <quorum ");
-
- if (qs & FLAG_UP) {
- printf("quorate=\"1\"");
- } else {
- printf("quorate=\"0\"\n");
- }
- if (qs & FLAG_RGMGR) {
- printf(" groupmember=\"1\"");
- } else {
- printf(" groupmember=\"0\"");
- }
-
- printf("/>\n");
-}
-
-static void
-build_member_field_size(int cols, int *nodesize)
-{
- /* Based on 80 columns */
- *nodesize = 40;
-
- *nodesize = (cols / 2);
- if (*nodesize > MAXHOSTNAMELEN)
- *nodesize = MAXHOSTNAMELEN;
-}
-
-
-static void
-txt_member_state(cman_node_t *node, int nodesize)
-{
- /* If it's down and not in cluster.conf, don't show it */
- if ((node->cn_member & (FLAG_NOCFG | FLAG_UP)) == FLAG_NOCFG)
- return;
-
- printf(" %-*.*s ", nodesize, nodesize, node->cn_name);
- printf("%4d ", node->cn_nodeid);
-
- if (node->cn_member & FLAG_UP)
- printf("Online");
- else
- printf("Offline");
-
- if (node->cn_member & FLAG_LOCAL)
- printf(", Local");
-
- if (node->cn_member & FLAG_NOCFG)
- printf(", Estranged");
-
- if (node->cn_member & FLAG_RGMGR) {
- if (rgmanager_master_present) {
- if (node->cn_member & FLAG_RGMAST)
- printf(", RG-Master");
- else
- printf(", RG-Worker");
- } else {
- printf(", rgmanager");
- }
- }
-
- if (node->cn_member & FLAG_QDISK)
- printf(", Quorum Disk");
-
- printf("\n");
-}
-
-
-static void
-xml_member_state(cman_node_t *node)
-{
- /* If it's down and not in cluster.conf, don't show it */
- if ((node->cn_member & (FLAG_NOCFG | FLAG_UP)) == FLAG_NOCFG)
- return;
-
- printf(" <node name=\"%s\" state=\"%d\" local=\"%d\" "
- "estranged=\"%d\" rgmanager=\"%d\" rgmanager_master=\"%d\" "
- "qdisk=\"%d\" nodeid=\"0x%08x\"/>\n",
- node->cn_name,
- !!(node->cn_member & FLAG_UP),
- !!(node->cn_member & FLAG_LOCAL),
- !!(node->cn_member & FLAG_NOCFG),
- !!(node->cn_member & FLAG_RGMGR),
- !!(node->cn_member & FLAG_RGMAST),
- !!(node->cn_member & FLAG_QDISK),
- (uint32_t)((node->cn_nodeid )&0xffffffff));
-}
-
-
-static void
-print_member_header(int nodesize)
-{
- printf(" %-*.*s", nodesize, nodesize, "Member Name");
- printf("%-4.4s %s\n", "ID", "Status");
- printf(" %-*.*s", nodesize, nodesize, "------ ----");
- printf("%-4.4s %s\n", "----", "------");
-}
-
-
-static int
-txt_member_states(cluster_member_list_t *membership, char *name)
-{
- int x, ret = -1, nodesize;
-
- if (!membership) {
- printf("Membership information not available\n");
- return -1;
- }
-
- build_member_field_size(dimx, &nodesize);
-
- if (!name) {
- printf(" %-*.*s", nodesize, nodesize, "Member Name");
- printf("%-4.4s %s\n", "ID", "Status");
- printf(" %-*.*s", nodesize, nodesize, "------ ----");
- printf("%-4.4s %s\n", "----", "------");
- ret = 0;
- }
-
- for (x = 0; x < membership->cml_count; x++) {
- if (name) {
- if (strcmp(membership->cml_members[x].cn_name, name)) {
- continue;
- }
- print_member_header(nodesize);
- }
- txt_member_state(&membership->cml_members[x], nodesize);
- if (name) {
- ret = !(membership->cml_members[x].cn_member & FLAG_UP);
- return ret;
- }
- }
-
- if (!name)
- printf("\n");
- return ret;
-}
-
-
-static int
-xml_member_states(cluster_member_list_t *membership, char *name)
-{
- int x, ret = 0;
-
- if (!membership) {
- printf(" <nodes/>\n");
- return -1;
- }
-
- printf(" <nodes>\n");
- for (x = 0; x < membership->cml_count; x++) {
- if (name && strcmp(membership->cml_members[x].cn_name, name))
- continue;
- xml_member_state(&membership->cml_members[x]);
- if (name)
- ret = !(membership->cml_members[x].cn_member & FLAG_UP);
- }
- printf(" </nodes>\n");
-
- return ret;
-}
-
-
-static int
-txt_cluster_status(cman_cluster_t *ci,
- int qs, cluster_member_list_t *membership,
- rg_state_list_t *rgs, char *name, char *svcname,
- int flags)
-{
- int ret1 = 0, ret2 = 0;
-
- if (!svcname && !name) {
- txt_cluster_info(ci);
- txt_quorum_state(qs);
- if (!membership) {
- /* XXX Check for rgmanager?! */
- printf("Resource Group Manager not running; "
- "no service information available.\n\n");
- }
- }
-
- if (!svcname || (name && svcname))
- ret1 = txt_member_states(membership, name);
-
- if (rgs &&
- (!name || (name && svcname)))
- ret2 = txt_rg_states(rgs, membership, svcname, flags);
-
- if (name && ret1)
- return ret1;
- if (svcname && ret2)
- return ret2;
- return 0;
-}
-
-
-static int
-xml_cluster_status(cman_cluster_t *ci, int qs,
- cluster_member_list_t *membership,
- rg_state_list_t *rgs, char *name, char *svcname,
- int flags)
-{
- int ret1 = 0, ret2 = -1;
- int x;
-
- printf("<?xml version=\"1.0\"?>\n");
- printf("<clustat version=\"4.1.1\">\n");
-
- if (qs) {
- qs = FLAG_UP;
- if (membership) {
- for (x = 0; x < membership->cml_count; x++) {
- if ((membership->cml_members[x].cn_member &
- (FLAG_LOCAL|FLAG_RGMGR)) ==
- (FLAG_LOCAL|FLAG_RGMGR)) {
- qs |= FLAG_RGMGR;
- break;
- }
- }
- }
- }
-
- if (!svcname && !name)
- xml_cluster_info(ci);
- if (!svcname && !name)
- xml_quorum_state(qs);
- if (!svcname || (name && svcname))
- ret1 = xml_member_states(membership, name);
-
- if (rgs &&
- (!name || (name && svcname)))
- ret2 = xml_rg_states(rgs, membership, svcname, flags);
- printf("</clustat>\n");
-
- if (name && ret1)
- return ret1;
- if (svcname && ret2)
- return ret2;
- return 0;
-}
-
-
-static cluster_member_list_t *
-build_member_list(cman_handle_t ch, int *lid, int fast)
-{
- cluster_member_list_t *all, *part;
- cman_node_t *m;
- int root = 0;
- int x;
-
- /* Get all members from ccs, and all members reported by the cluster
- infrastructure */
- root = (getuid() == 0 || geteuid() == 0);
-
- part = get_member_list(ch);
-
- if (!fast && root && (all = ccs_member_list())) {
-
- /* See if our config has anyone missed. If so, flag
- them as missing from the config file */
- all = add_missing(all, part);
-
- /* Flag online nodes */
- flag_nodes(all, part, FLAG_UP);
- free_member_list(part);
- } else {
- /* not root - keep it simple for the next block */
- all = part;
- }
-
- if (!all) {
- *lid = 0;
- return NULL;
- }
-
- /* Grab the local node ID and flag it from the list of reported
- online nodes */
- *lid = get_my_nodeid(ch);
- /* */
- for (x=0; x<all->cml_count; x++) {
- if (all->cml_members[x].cn_nodeid == *lid) {
- m = &all->cml_members[x];
- m->cn_member |= FLAG_LOCAL;
- break;
- }
- }
-
- return all;
-}
-
-
-static void
-usage(char *arg0)
-{
- printf(
-"usage: %s <options>\n"
-" -i <interval> Refresh every <interval> seconds. May not be used\n"
-" with -x.\n"
-" -I Display local node ID and exit\n"
-" -m <member> Display status of <member> and exit\n"
-" -s <service> Display status of <service> and exit\n"
-" -v Display version and exit\n"
-" -x Dump information as XML\n"
-" -Q Return 0 if quorate, 1 if not (no output)\n"
-" -f Enable fast clustat reports\n"
-" -l Use long format for services\n"
-"\n", basename(arg0));
-}
-
-
-int
-main(int argc, char **argv)
-{
- int qs, ret = 0;
- cluster_member_list_t *membership;
- rg_state_list_t *rgs = NULL;
- int local_node_id;
- int fast = 0;
- int runtype = 0;
- time_t now;
- cman_handle_t ch = NULL;
- cman_cluster_t ci;
-
- int refresh_sec = 0, errors = 0;
- int opt, xml = 0, flags = 0;
- char *member_name = NULL;
- char *rg_name = NULL, real_rg_name[64];
-
- while ((opt = getopt(argc, argv, "fIls:m:i:xvQh?")) != EOF) {
- switch(opt) {
- case 'v':
- runtype = VERSION_ONLY;
- break;
-
- case 'I':
- runtype = NODEID_ONLY;
- break;
-
- case 'i':
- refresh_sec = atoi(optarg);
- if (refresh_sec <= 0)
- refresh_sec = 1;
- break;
- case 'l':
- flags |= RG_VERBOSE;
- break;
-
- case 'm':
- member_name = optarg;
- break;
-
- case 'Q':
- /* Return to shell: 0 true, 1 false... */
- runtype = QSTAT_ONLY;
- break;
-
- case 's':
- rg_name = optarg;
- if (!strchr(rg_name,':')) {
- memset(real_rg_name, 0, sizeof(real_rg_name));
- snprintf(real_rg_name,
- sizeof(real_rg_name)-1,
- "service:%s", rg_name);
- rg_name = real_rg_name;
- }
- break;
-
- case 'x':
- if (refresh_sec) {
- printf("Error: Options '-i' and '-x' are "
- "mutually exclusive\n");
- ret = 1;
- goto cleanup;
- }
-
- xml = 1;
- break;
- case 'f':
- ++fast;
- break;
- case '?':
- case 'h':
- usage(argv[0]);
- return 0;
- break;
- default:
- errors++;
- break;
- }
- }
-
- if (errors) {
- usage(argv[0]);
- return 1;
- }
-
- signal(SIGPIPE, SIG_IGN);
-
- /* Connect & grab all our info */
- ch = cman_init(NULL);
- if (!ch && (runtype != VERSION_ONLY)) {
- perror("Could not connect to CMAN");
- return 1;
- }
-
- switch(runtype) {
- case QSTAT_ONLY:
- if (!ch)
- break;
- ret = !(cman_is_quorate(ch));
- goto cleanup;
- case VERSION_ONLY:
- printf("%s version %s\n", basename(argv[0]),
- RELEASE_VERSION);
- goto cleanup;
- case NODEID_ONLY:
- if (!ch)
- break;
- local_node_id = get_my_nodeid(ch);
- printf("0x%08x\n",(uint32_t)(local_node_id));
- goto cleanup;
- }
-
- if (!ch) {
- printf("Could not connect to cluster service\n");
- return 1;
- }
-
- /* XXX add member/rg single-shot state */
- signal(SIGINT, term_handler);
- signal(SIGTERM, term_handler);
-
- if (isatty(STDOUT_FILENO)) {
- stdout_is_tty = 1;
- setupterm((char *) 0, STDOUT_FILENO, (int *) 0);
- dimx = tigetnum((char *)"cols");
- dimy = tigetnum((char *)"lines");
- }
-
- memset(&ci, 0, sizeof(ci));
- cman_get_cluster(ch, &ci);
-
- while (1) {
- qs = cman_is_quorate(ch);
- membership = build_member_list(ch, &local_node_id, fast);
-
- if (!member_name)
- rgs = rg_state_list(local_node_id, fast);
- if (rgs) {
- flag_rgmanager_nodes(membership);
- }
-
- if (refresh_sec) {
- tputs(clear_screen, lines > 0 ? lines : 1, putchar);
- now = time(NULL);
- }
-
- if (xml)
- ret = xml_cluster_status(&ci, qs, membership, rgs,
- member_name, rg_name,
- flags);
- else
- ret = txt_cluster_status(&ci, qs, membership, rgs,
- member_name, rg_name,
- flags);
-
- if (membership)
- free_member_list(membership);
- if (rgs)
- free(rgs);
-
- if (!refresh_sec || !running)
- break;
-
- sleep(refresh_sec);
- }
-
-cleanup:
- cman_finish(ch);
-
- return ret;
-}
diff --git a/rgmanager/src/utils/clusvcadm.c b/rgmanager/src/utils/clusvcadm.c
deleted file mode 100644
index 3de9237..0000000
--- a/rgmanager/src/utils/clusvcadm.c
+++ /dev/null
@@ -1,465 +0,0 @@
-/** @file
- * The New And Improved Cluster Service Admin Utility.
- * TODO Clean up the code.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/param.h>
-#include <libgen.h>
-#include <resgroup.h>
-#include <platform.h>
-#include <members.h>
-#include <message.h>
-#include <libcman.h>
-#include <resgroup.h>
-#include <msgsimple.h>
-#include <signal.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-
-static void
-build_message(SmMessageSt *msgp, int action, char *svcName, int target,
- int arg1, int arg2)
-{
- msgp->sm_hdr.gh_magic = GENERIC_HDR_MAGIC;
- msgp->sm_hdr.gh_command = RG_ACTION_REQUEST;
- msgp->sm_hdr.gh_length = sizeof(*msgp);
- msgp->sm_hdr.gh_arg1 = arg1;
- msgp->sm_hdr.gh_arg2 = arg2;
- msgp->sm_data.d_action = action;
- strncpy(msgp->sm_data.d_svcName, svcName,
- sizeof(msgp->sm_data.d_svcName));
- msgp->sm_data.d_svcOwner = target;
- msgp->sm_data.d_ret = 0;
-
- swab_SmMessageSt(msgp);
-}
-
-
-static int
-do_lock_req(int req)
-{
- cman_handle_t ch;
- msgctx_t ctx;
- int ret = RG_FAIL;
- cluster_member_list_t *membership = NULL;
- int me;
- generic_msg_hdr hdr;
-
- ctx.type = -1;
-
- ch = cman_init(NULL);
- if (!ch) {
- printf("Could not connect to cluster service\n");
- goto out;
- }
-
- membership = get_member_list(ch);
- me = get_my_nodeid(ch);
-
- if (msg_open(MSG_SOCKET, 0, RG_PORT, &ctx, 5) < 0) {
- printf("Could not connect to resource group manager\n");
- goto out;
- }
-
- if (msg_send_simple(&ctx, req, 0, 0) < 0) {
- printf("Communication failed\n");
- goto out;
- }
-
- if (msg_receive(&ctx, &hdr, sizeof(hdr), 5) < sizeof(hdr)) {
- printf("Receive failed\n");
- goto out;
- }
-
- swab_generic_msg_hdr(&hdr);
- ret = hdr.gh_command;
-
-out:
- if (membership)
- free_member_list(membership);
-
- if (ctx.type >= 0)
- msg_close(&ctx);
-
- if (ch)
- cman_finish(ch);
-
- return ret;
-}
-
-
-static int
-do_lock(void)
-{
- if (do_lock_req(RG_LOCK) != RG_SUCCESS) {
- printf("Lock operation failed\n");
- return 1;
- }
- printf("Resource groups locked\n");
- return 0;
-}
-
-
-static int
-do_unlock(void)
-{
- if (do_lock_req(RG_UNLOCK) != RG_SUCCESS) {
- printf("Unlock operation failed\n");
- return 1;
- }
- printf("Resource groups unlocked\n");
- return 0;
-}
-
-
-static int
-do_query_lock(void)
-{
- switch(do_lock_req(RG_QUERY_LOCK)) {
- case RG_LOCK:
- printf("Resource groups locked\n");
- break;
- case RG_UNLOCK:
- printf("Resource groups unlocked\n");
- break;
- default:
- printf("Query operation failed\n");
- return 1;
- }
- return 0;
-}
-
-
-static void
-usage(char *name)
-{
-printf("usage: %s [command]\n\n", name);
-
-printf("Resource Group Control Commands:\n");
-printf(" -v Display version and exit\n");
-printf(" -d <group> Disable <group>. This stops a group\n"
- " until an administrator enables it again,\n"
- " the cluster loses and regains quorum, or\n"
- " an administrator-defined event script\n"
- " explicitly enables it again.\n");
-printf(" -e <group> Enable <group>\n");
-printf(" -e <group> -F Enable <group> according to failover\n"
- " domain rules (deprecated; always the\n"
- " case when using central processing)\n");
-printf(" -e <group> -m <member> Enable <group> on <member>\n");
-printf(" -r <group> -m <member> Relocate <group> [to <member>]\n"
- " Stops a group and starts it on another\n"
- " cluster member.\n");
-printf(" -M <group> -m <member> Migrate <group> to <member>\n");
-printf(" (e.g. for live migration of VMs)\n");
-printf(" -q Quiet operation\n");
-printf(" -R <group> Restart a group in place.\n");
-printf(" -s <group> Stop <group>. This temporarily stops\n"
- " a group. After the next group or\n"
- " or cluster member transition, the group\n"
- " will be restarted (if possible).\n");
-printf(" -Z <group> Freeze resource group. This prevents\n"
- " transitions and status checks, and is \n"
- " useful if an administrator needs to \n"
- " administer part of a service without \n"
- " stopping the whole service.\n");
-printf(" -U <group> Unfreeze (thaw) resource group. Restores\n"
- " a group to normal operation.\n");
-printf(" -c <group> Convalesce (repair, fix) resource group.\n"
- " Attempts to start failed, non-critical \n"
- " resources within a resource group.\n");
-
-printf("Resource Group Locking (for cluster Shutdown / Debugging):\n");
-printf(" -l Lock local resource group managers.\n"
- " This prevents resource groups from\n"
- " starting.\n");
-printf(" -S Show lock state\n");
-printf(" -u Unlock resource group managers.\n"
- " This allows resource groups to start.\n");
-}
-
-
-static int
-find_closest_node(cluster_member_list_t *cml, char *name, size_t maxlen)
-{
- int x, c = 0, cl = 0, nc = 0, ncl = 0, cur = 0;
-
- for (x=0; x<cml->cml_count; x++) {
- cur = 0;
-
- while (cml->cml_members[x].cn_name[cur] && name[cur] &&
- (cml->cml_members[x].cn_name[cur] == name[cur]))
- cur++;
- if (!cur)
- continue;
- if (cur >= cl) {
- ncl = cl; /* Next-closest */
- nc = c;
- cl = cur;
- c = x;
- }
- }
-
- if (!cl) {
- printf("No matches for '%s' found\n", name);
- return 0;
- }
-
- if (ncl == cl) {
- printf("More than one possible match for '%s' found\n",
- name);
- return 0;
- }
-
- printf("Closest match: '%s'\n",
- cml->cml_members[c].cn_name);
-
- strncpy(name, cml->cml_members[c].cn_name, maxlen);
- return cml->cml_members[c].cn_nodeid;
-}
-
-
-int
-main(int argc, char **argv)
-{
- extern char *optarg;
- char *svcname=NULL, nodename[256], realsvcname[64];
- int opt;
- msgctx_t ctx;
- cman_handle_t ch;
- SmMessageSt msg;
- generic_msg_hdr *h = (generic_msg_hdr *)&msg;
- int action = RG_STATUS;
- int fod = 0;
- int node_specified = 0;
- int me, svctarget = 0;
- const char *actionstr = NULL;
- cluster_member_list_t *membership;
-
- while ((opt = getopt(argc, argv, "lSue:M:d:r:n:c:m:FvR:s:Z:U:qh?")) != EOF) {
- switch (opt) {
- case 'l':
- return do_lock();
-
- case 'S':
- return do_query_lock();
-
- case 'u':
- return do_unlock();
-
- case 'e':
- /* ENABLE */
- actionstr = "trying to enable";
- action = RG_ENABLE;
- svcname = optarg;
- break;
- case 'F':
- if (node_specified) {
- fprintf(stderr,
- "Cannot use '-F' with '-n' or '-m'\n");
- return 1;
- }
- fod = 1;
- break;
- case 'd':
- /* DISABLE */
- actionstr = "disabling";
- action = RG_DISABLE;
- svcname = optarg;
- break;
- case 'r':
- /* RELOCATE */
- actionstr = "relocate";
- action = RG_RELOCATE;
- svcname = optarg;
- break;
- case 'M':
- /* MIGRATE */
- actionstr = "migrate";
- action = RG_MIGRATE;
- svcname = optarg;
- break;
- case 's':
- /* stop */
- actionstr = "stopping";
- action = RG_STOP_USER;
- svcname = optarg;
- break;
- case 'R':
- actionstr = "trying to restart";
- action = RG_RESTART;
- svcname = optarg;
- break;
- case 'm': /* member ... */
- case 'n': /* node .. same thing */
- if (fod) {
- fprintf(stderr,
- "Cannot use '-F' with '-n' or '-m'\n");
- return 1;
- }
- strncpy(nodename,optarg,sizeof(nodename));
- node_specified = 1;
- break;
- case 'v':
- printf("%s\n", RELEASE_VERSION);
- return 0;
- case 'Z':
- actionstr = "freezing";
- action = RG_FREEZE;
- svcname = optarg;
- break;
- case 'U':
- actionstr = "unfreezing";
- action = RG_UNFREEZE;
- svcname = optarg;
- break;
- case 'c':
- actionstr = "convalescing";
- action = RG_CONVALESCE;
- svcname = optarg;
- break;
- case 'q':
- close(STDOUT_FILENO);
- break;
- case 'h':
- case '?':
- default:
- usage(basename(argv[0]));
- return 1;
- }
- }
-
- if (!svcname) {
- usage(basename(argv[0]));
- return 1;
- }
-
- if (action == RG_MIGRATE && !node_specified) {
- printf("Migration requires a target cluster member\n");
- return 1;
- }
-
- if (!strchr(svcname,':')) {
- snprintf(realsvcname, sizeof(realsvcname), "service:%s",
- svcname);
- svcname = realsvcname;
- }
-
- signal(SIGPIPE, SIG_IGN);
-
- /* No login */
- ch = cman_init(NULL);
- if (!ch) {
- printf("Could not connect to cluster service\n");
- return 1;
- }
-
- membership = get_member_list(ch);
- me = get_my_nodeid(ch);
-
- if (node_specified) {
- svctarget = memb_name_to_id(membership, nodename);
- if (svctarget == 0) {
- printf("'%s' not in membership list\n",
- nodename);
- svctarget = find_closest_node(membership, nodename,
- sizeof(nodename));
- if (!svctarget)
- return 1;
- }
- if (action == RG_MIGRATE &&
- memb_online(membership, svctarget) == 0) {
- printf("'%s' is offline\n", nodename);
- return 1;
- }
- } else {
- svctarget = 0;
- /*
- clu_local_nodename(RG_SERVICE_GROUP, nodename,
- sizeof(nodename));
- */
- //strcpy(nodename,"me");
- }
-
- build_message(&msg, action, svcname, svctarget, fod, 0);
-
- if (action != RG_RELOCATE && action != RG_MIGRATE) {
- if (!node_specified)
- printf("Local machine %s %s", actionstr, svcname);
- else
- printf("Member %s %s %s", nodename, actionstr, svcname);
- printf("...");
- fflush(stdout);
- if (msg_open(MSG_SOCKET, 0, RG_PORT, &ctx, 5) < 0) {
- printf("Could not connect to resource group manager\n");
- return 1;
- }
- } else {
- if (!svctarget)
- printf("Trying to %s %s", actionstr, svcname);
- else
- printf("Trying to %s %s to %s", actionstr, svcname,
- nodename);
- printf("...");
- fflush(stdout);
- if (msg_open(MSG_SOCKET, 0, RG_PORT, &ctx, 5) < 0) {
- printf("Could not connect to resource group manager\n");
- return 1;
- }
- }
-
- if (ctx.type < 0) {
- fprintf(stderr,
- "Could not connect to resource group manager!\n");
- return 1;
- }
-
- if (msg_send(&ctx, &msg, sizeof(msg)) < sizeof(msg)) {
- perror("msg_send");
- fprintf(stderr,
- "Error sending message to resource group manager.\n");
- return 1;
- }
-
- /* Reusing opt here */
- if ((opt = msg_receive(&ctx, &msg, sizeof(msg), 0)) < sizeof(*h)) {
- perror("msg_receive");
- fprintf(stderr, "Error receiving reply!\n");
- return 1;
- }
-
- /* Decode */
- if (opt < sizeof(msg)) {
- swab_generic_msg_hdr(h);
- printf("%s\n", rg_strerror(h->gh_arg1));
- return h->gh_arg1;
- }
-
- swab_SmMessageSt(&msg);
- printf("%s\n", rg_strerror(msg.sm_data.d_ret));
- if (msg.sm_data.d_ret == RG_ERUN)
- return 0;
- if (msg.sm_data.d_ret)
- return msg.sm_data.d_ret;
-
- switch (action) {
- /*case RG_MIGRATE:*/
- case RG_RELOCATE:
- case RG_START:
- case RG_ENABLE:
- printf("%s%s is now running on %s\n",
- (!node_specified ||
- msg.sm_data.d_svcOwner==svctarget)?"":"Warning: ",
- svcname, memb_id_to_name(membership,
- msg.sm_data.d_svcOwner));
- break;
- default:
- break;
- }
-
- return msg.sm_data.d_ret;
-}
diff --git a/scripts/uninstall.pl b/scripts/uninstall.pl
deleted file mode 100644
index 4326e85..0000000
--- a/scripts/uninstall.pl
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/perl
-
-## Description: Basically the reverse of the install program, except it
-## only supports a list of files and a directory as arguments
-
-$| = 1;
-
-use Getopt::Std;
-
-# list all valid options here. User will get errors if invalid options are
-# specified on the command line
-getopts('hD');
-
-$args = 1;
-
-# We need at least two arguments to uninstall
-if(!defined($ARGV[1])) {
- $args = 0;
-}
-
-# if the user set the help flag or didn't provide enough args, print help
-# and die.
-if(defined($opt_h) || ($args == 0)) {
- $msg = "usage: $0 [OPTIONS] TARGET DIRECTORY\n";
- $msg = $msg . "\t-D\tRemove specified directory if empty\n";
- $msg = $msg . "\t-h\tDisplay this help message\n";
- die $msg;
-}
-
-# find out how many command line arguments we have
-$length = $#ARGV;
-# We need a special case if there is only one file specified
-if($length > 1) {
- @filelist = @ARGV;
- $#filelist = $length - 1;
-}
-else {
- @filelist = @ARGV[0];
-}
-
-# the last argument is the directory
-$dir = @ARGV[$length];
-
-# prepend the directory name to all files in the filelist
-$i = 0;
-print "Attempting to remove the following files from directory $dir/:\n";
-while($i < $length) {
- print "@filelist[$i] ";
- @filelist[$i] = "$dir/" . @filelist[$i];
- $i++;
-}
-print "\n";
-
-#print "Files:@filelist\n";
-#print "Directory: $dir\n";
-
-# delete the files in filelist
-$unlinked = unlink @filelist;
-if($unlinked < $length) {
- print "Error! Unable to remove all files in $dir:\n\tYou may have to manually delete some of them.\n"
-}
-# if user specifed they want the directory deleted, try to delete it. Print
-# error message if not able to delete directory, including error.
-if(defined($opt_D)) {
- $result = rmdir($dir);
- if($result == FALSE) {
- print "Error! Unable to remove directory $dir/:\n\t$!\n";
- }
-}
-
-
Gitweb: http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=cdfa000f93716…
Commit: cdfa000f9371658b362e5983747c2b61a6ed8edf
Parent: ba234a47306013ba96658c3efa9b9d05dcf55380
Author: Jan Pokorn�� <jpokorny(a)redhat.com>
AuthorDate: Tue Feb 28 02:32:08 2017 +0100
Committer: Jan Pokorn�� <jpokorny(a)redhat.com>
CommitterDate: Tue Feb 28 02:32:08 2017 +0100
fedorahosted.org discontinued
Signed-off-by: Jan Pokorn�� <jpokorny(a)redhat.com>
---
Makefile | 73 -
README | 3 +
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 | 33 -
cman/cman_tool/cman_tool.h | 112 -
cman/cman_tool/join.c | 395 ---
cman/cman_tool/main.c | 1290 -------
cman/daemon/Makefile | 41 -
cman/daemon/ais.c | 378 --
cman/daemon/ais.h | 14 -
cman/daemon/barrier.c | 471 ---
cman/daemon/barrier.h | 6 -
cman/daemon/cman-preconfig.c | 1796 ----------
cman/daemon/cman.h | 19 -
cman/daemon/cmanconfig.c | 304 --
cman/daemon/cmanconfig.h | 3 -
cman/daemon/cnxman-private.h | 183 -
cman/daemon/cnxman-socket.h | 289 --
cman/daemon/commands.c | 2469 -------------
cman/daemon/commands.h | 37 -
cman/daemon/daemon.c | 528 ---
cman/daemon/daemon.h | 12 -
cman/daemon/fnvhash.c | 93 -
cman/daemon/fnvhash.h | 1 -
cman/daemon/list.h | 97 -
cman/daemon/nodelist.h | 93 -
cman/init.d/Makefile | 21 -
cman/init.d/cman.in | 980 ------
cman/init.d/cman.init.defaults.in | 104 -
cman/lib/Makefile | 12 -
cman/lib/libcman.c | 1133 ------
cman/lib/libcman.h | 457 ---
cman/lib/libcman.pc.in | 11 -
cman/man/Makefile | 17 -
cman/man/checkquorum.8 | 29 -
cman/man/cman.5 | 211 --
cman/man/cman_notify.8 | 17 -
cman/man/cman_tool.8 | 436 ---
cman/man/cmannotifyd.8 | 66 -
cman/man/mkqdisk.8 | 31 -
cman/man/qdisk.5 | 530 ---
cman/man/qdiskd.8 | 25 -
cman/notifyd/Makefile | 37 -
cman/notifyd/cman_notify.in | 40 -
cman/notifyd/main.c | 440 ---
cman/qdisk/Makefile | 52 -
cman/qdisk/bitmap.c | 91 -
cman/qdisk/daemon_init.c | 236 --
cman/qdisk/disk.c | 790 -----
cman/qdisk/disk.h | 298 --
cman/qdisk/disk_util.c | 264 --
cman/qdisk/iostate.c | 154 -
cman/qdisk/iostate.h | 19 -
cman/qdisk/main.c | 2254 ------------
cman/qdisk/mkqdisk.c | 102 -
cman/qdisk/platform.h | 40 -
cman/qdisk/proc.c | 262 --
cman/qdisk/scandisk.c | 764 ----
cman/qdisk/scandisk.h | 86 -
cman/qdisk/score.c | 486 ---
cman/qdisk/score.h | 47 -
cman/scripts/Makefile | 11 -
cman/scripts/checkquorum | 97 -
cman/scripts/checkquorum.wdmd | 104 -
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 | 334 --
common/liblogthread/liblogthread.h | 19 -
common/liblogthread/liblogthread.pc.in | 11 -
config/Makefile | 4 -
config/libs/Makefile | 4 -
config/libs/libccsconfdb/Makefile | 24 -
config/libs/libccsconfdb/ccs.h | 16 -
config/libs/libccsconfdb/ccs_internal.h | 29 -
config/libs/libccsconfdb/extras.c | 447 ---
config/libs/libccsconfdb/fullxpath.c | 363 --
config/libs/libccsconfdb/libccs.c | 648 ----
config/libs/libccsconfdb/libccs.pc.in | 11 -
config/libs/libccsconfdb/xpathlite.c | 444 ---
config/man/Makefile | 9 -
config/man/cluster.conf.5 | 237 --
config/plugins/Makefile | 4 -
config/plugins/ldap/99cluster.ldif | 1826 ----------
config/plugins/ldap/Makefile | 30 -
config/plugins/ldap/configldap.c | 292 --
config/plugins/ldap/example.ldif | 137 -
config/plugins/ldap/ldap-base.csv | 338 --
config/plugins/xml/Makefile | 27 -
config/plugins/xml/config.c | 146 -
config/tools/Makefile | 4 -
config/tools/ccs_tool/Makefile | 39 -
config/tools/ccs_tool/ccs_tool.c | 307 --
config/tools/ccs_tool/editconf.c | 1225 -------
config/tools/ccs_tool/editconf.h | 8 -
config/tools/ldap/Makefile | 30 -
config/tools/ldap/confdb2ldif.c | 179 -
config/tools/ldap/rng2ldif/Makefile | 46 -
config/tools/ldap/rng2ldif/debug.h | 10 -
config/tools/ldap/rng2ldif/genclass.c | 102 -
config/tools/ldap/rng2ldif/ldaptypes.c | 53 -
config/tools/ldap/rng2ldif/ldaptypes.h | 8 -
config/tools/ldap/rng2ldif/name.c | 58 -
config/tools/ldap/rng2ldif/name.h | 6 -
config/tools/ldap/rng2ldif/rng2ldif.c | 232 --
config/tools/ldap/rng2ldif/tree.c | 433 ---
config/tools/ldap/rng2ldif/tree.h | 40 -
config/tools/ldap/rng2ldif/value-list.c | 191 -
config/tools/ldap/rng2ldif/value-list.h | 28 -
config/tools/ldap/rng2ldif/zalloc.c | 23 -
config/tools/ldap/rng2ldif/zalloc.h | 6 -
config/tools/man/Makefile | 13 -
config/tools/man/ccs_config_dump.8 | 35 -
config/tools/man/ccs_config_validate.8 | 56 -
config/tools/man/ccs_tool.8 | 37 -
config/tools/man/ccs_update_schema.8 | 29 -
config/tools/man/confdb2ldif.8 | 64 -
config/tools/xml/Makefile | 47 -
config/tools/xml/ccs_config_dump.c | 187 -
config/tools/xml/ccs_config_validate.in | 242 --
config/tools/xml/ccs_update_schema.in | 377 --
config/tools/xml/cluster.rng.in.head | 1125 ------
config/tools/xml/cluster.rng.in.tail | 1 -
configure | 688 ----
contrib/Makefile | 6 -
contrib/libaislock/Makefile | 15 -
contrib/libaislock/libaislock.c | 466 ---
contrib/libaislock/libaislock.h | 190 -
contrib/libaislock/libaislock.pc.in | 11 -
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 | 81 -
dlm/libdlm/libdlm.c | 1485 --------
dlm/libdlm/libdlm.h | 275 --
dlm/libdlm/libdlm.pc.in | 11 -
dlm/libdlm/libdlm_internal.h | 9 -
dlm/libdlm/libdlm_lt.pc.in | 11 -
dlm/libdlmcontrol/Makefile | 17 -
dlm/libdlmcontrol/libdlmcontrol.h | 90 -
dlm/libdlmcontrol/libdlmcontrol.pc.in | 11 -
dlm/libdlmcontrol/main.c | 419 ---
dlm/man/Makefile | 30 -
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 | 98 -
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 | 289 --
dlm/tests/usertest/dlmtest2.c | 1454 --------
dlm/tests/usertest/flood.c | 170 -
dlm/tests/usertest/joinleave.c | 62 -
dlm/tests/usertest/lstest.c | 326 --
dlm/tests/usertest/lvb.c | 244 --
dlm/tests/usertest/pingtest.c | 343 --
dlm/tests/usertest/sublocks.c | 178 -
dlm/tests/usertest/threads.c | 309 --
dlm/tool/Makefile | 32 -
dlm/tool/main.c | 1324 -------
doc/COPYING.applications | 339 --
doc/COPYING.libraries | 510 ---
doc/COPYRIGHT | 239 --
doc/Makefile | 24 -
doc/README.licence | 33 -
doc/cluster.logrotate.in | 9 -
doc/cluster_conf.html | 1240 -------
doc/cman_notify_template.sh | 57 -
doc/usage.txt | 90 -
fence/Makefile | 4 -
fence/fence_check/Makefile | 20 -
fence/fence_check/fence_check.in | 241 --
fence/fence_node/Makefile | 35 -
fence/fence_node/fence_node.c | 306 --
fence/fence_tool/Makefile | 32 -
fence/fence_tool/fence_tool.c | 737 ----
fence/fenced/Makefile | 49 -
fence/fenced/config.c | 226 --
fence/fenced/config.h | 39 -
fence/fenced/cpg.c | 2510 -------------
fence/fenced/dbus.c | 87 -
fence/fenced/fd.h | 299 --
fence/fenced/fenced.h | 36 -
fence/fenced/group.c | 489 ---
fence/fenced/logging.c | 92 -
fence/fenced/main.c | 1105 ------
fence/fenced/member_cman.c | 416 ---
fence/fenced/recover.c | 476 ---
fence/include/linux_endian.h | 68 -
fence/include/list.h | 336 --
fence/libfence/Makefile | 20 -
fence/libfence/agent.c | 1142 ------
fence/libfence/libfence.h | 65 -
fence/libfence/libfence.pc.in | 11 -
fence/libfenced/Makefile | 14 -
fence/libfenced/libfenced.h | 53 -
fence/libfenced/libfenced.pc.in | 11 -
fence/libfenced/main.c | 341 --
fence/man/Makefile | 10 -
fence/man/fence_check.8 | 65 -
fence/man/fence_node.8 | 127 -
fence/man/fence_tool.8 | 60 -
fence/man/fenced.8 | 353 --
gfs2/Makefile | 4 -
gfs2/convert/Makefile | 33 -
gfs2/convert/gfs2_convert.c | 2229 ------------
gfs2/edit/Makefile | 40 -
gfs2/edit/extended.c | 702 ----
gfs2/edit/extended.h | 8 -
gfs2/edit/gfs2hex.c | 650 ----
gfs2/edit/gfs2hex.h | 14 -
gfs2/edit/hexedit.c | 3679 --------------------
gfs2/edit/hexedit.h | 226 --
gfs2/edit/savemeta.c | 1012 ------
gfs2/fsck/FEATURES | 25 -
gfs2/fsck/Makefile | 56 -
gfs2/fsck/eattr.c | 61 -
gfs2/fsck/eattr.h | 18 -
gfs2/fsck/fs_bits.h | 17 -
gfs2/fsck/fs_recovery.c | 769 ----
gfs2/fsck/fs_recovery.h | 12 -
gfs2/fsck/fsck.h | 143 -
gfs2/fsck/hash.c | 91 -
gfs2/fsck/hash.h | 7 -
gfs2/fsck/initialize.c | 1581 ---------
gfs2/fsck/inode_hash.c | 69 -
gfs2/fsck/inode_hash.h | 10 -
gfs2/fsck/link.c | 95 -
gfs2/fsck/link.h | 10 -
gfs2/fsck/lost_n_found.c | 259 --
gfs2/fsck/lost_n_found.h | 9 -
gfs2/fsck/main.c | 389 ---
gfs2/fsck/metawalk.c | 2041 -----------
gfs2/fsck/metawalk.h | 157 -
gfs2/fsck/pass1.c | 1641 ---------
gfs2/fsck/pass1b.c | 629 ----
gfs2/fsck/pass1c.c | 280 --
gfs2/fsck/pass2.c | 1935 ----------
gfs2/fsck/pass3.c | 347 --
gfs2/fsck/pass4.c | 218 --
gfs2/fsck/pass5.c | 311 --
gfs2/fsck/rgrepair.c | 983 ------
gfs2/fsck/util.c | 706 ----
gfs2/fsck/util.h | 188 -
gfs2/include/osi_list.h | 84 -
gfs2/include/osi_tree.h | 395 ---
gfs2/init.d/Makefile | 18 -
gfs2/init.d/gfs2.in | 172 -
gfs2/libgfs2/Makefile | 33 -
gfs2/libgfs2/block_list.c | 65 -
gfs2/libgfs2/buf.c | 146 -
gfs2/libgfs2/device_geometry.c | 126 -
gfs2/libgfs2/fs_bits.c | 259 --
gfs2/libgfs2/fs_geometry.c | 259 --
gfs2/libgfs2/fs_ops.c | 1841 ----------
gfs2/libgfs2/gfs1.c | 429 ---
gfs2/libgfs2/gfs2_disk_hash.c | 72 -
gfs2/libgfs2/gfs2_log.c | 192 -
gfs2/libgfs2/libgfs2.h | 822 -----
gfs2/libgfs2/misc.c | 543 ---
gfs2/libgfs2/ondisk.c | 638 ----
gfs2/libgfs2/recovery.c | 244 --
gfs2/libgfs2/rgrp.c | 228 --
gfs2/libgfs2/size.c | 67 -
gfs2/libgfs2/structures.c | 530 ---
gfs2/libgfs2/super.c | 327 --
gfs2/man/Makefile | 20 -
gfs2/man/fsck.gfs2.8 | 89 -
gfs2/man/gfs2.8 | 40 -
gfs2/man/gfs2_convert.8 | 68 -
gfs2/man/gfs2_edit.8 | 417 ---
gfs2/man/gfs2_grow.8 | 66 -
gfs2/man/gfs2_jadd.8 | 60 -
gfs2/man/gfs2_quota.8 | 105 -
gfs2/man/gfs2_tool.8 | 117 -
gfs2/man/mkfs.gfs2.8 | 101 -
gfs2/man/mount.gfs2.8 | 233 --
gfs2/man/tunegfs2.8 | 54 -
gfs2/mkfs/Makefile | 46 -
gfs2/mkfs/README | 25 -
gfs2/mkfs/gfs2_mkfs.h | 67 -
gfs2/mkfs/main.c | 54 -
gfs2/mkfs/main_grow.c | 423 ---
gfs2/mkfs/main_jadd.c | 540 ---
gfs2/mkfs/main_mkfs.c | 678 ----
gfs2/mount/Makefile | 35 -
gfs2/mount/gfs_ondisk.h | 1904 ----------
gfs2/mount/mount.gfs2.c | 238 --
gfs2/mount/mtab.c | 204 --
gfs2/mount/ondisk1.c | 59 -
gfs2/mount/util.c | 715 ----
gfs2/mount/util.h | 86 -
gfs2/quota/Makefile | 35 -
gfs2/quota/check.c | 603 ----
gfs2/quota/gfs2_quota.h | 82 -
gfs2/quota/main.c | 913 -----
gfs2/quota/names.c | 81 -
gfs2/tool/Makefile | 37 -
gfs2/tool/gfs2_tool.h | 51 -
gfs2/tool/iflags.h | 40 -
gfs2/tool/main.c | 196 --
gfs2/tool/misc.c | 349 --
gfs2/tool/ondisk.c | 11 -
gfs2/tool/sb.c | 227 --
gfs2/tool/tune.c | 144 -
gfs2/tune/Makefile | 34 -
gfs2/tune/main.c | 162 -
gfs2/tune/super.c | 206 --
gfs2/tune/tunegfs2.h | 29 -
group/Makefile | 4 -
group/daemon/Makefile | 35 -
group/daemon/app.c | 1846 ----------
group/daemon/cman.c | 206 --
group/daemon/cpg.c | 1116 ------
group/daemon/gd_internal.h | 325 --
group/daemon/groupd.h | 13 -
group/daemon/joinleave.c | 165 -
group/daemon/logging.c | 60 -
group/daemon/main.c | 1087 ------
group/dlm_controld/Makefile | 52 -
group/dlm_controld/action.c | 1089 ------
group/dlm_controld/config.c | 306 --
group/dlm_controld/config.h | 53 -
group/dlm_controld/cpg.c | 2630 --------------
group/dlm_controld/crc.c | 72 -
group/dlm_controld/deadlock.c | 1550 ---------
group/dlm_controld/dlm_controld.h | 38 -
group/dlm_controld/dlm_daemon.h | 391 ---
group/dlm_controld/group.c | 376 --
group/dlm_controld/logging.c | 61 -
group/dlm_controld/main.c | 1442 --------
group/dlm_controld/member_cman.c | 350 --
group/dlm_controld/netlink.c | 225 --
group/dlm_controld/plock.c | 2371 -------------
group/gfs_control/Makefile | 31 -
group/gfs_control/main.c | 463 ---
group/gfs_controld/Makefile | 51 -
group/gfs_controld/config.c | 229 --
group/gfs_controld/config.h | 38 -
group/gfs_controld/cpg-new.c | 3656 -------------------
group/gfs_controld/cpg-old.c | 2461 -------------
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 | 339 --
group/gfs_controld/group.c | 372 --
group/gfs_controld/logging.c | 61 -
group/gfs_controld/main.c | 1593 ---------
group/gfs_controld/member_cman.c | 255 --
group/gfs_controld/plock.c | 2407 -------------
group/gfs_controld/util.c | 299 --
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 | 14 -
group/man/dlm_controld.8 | 313 --
group/man/gfs_control.8 | 44 -
group/man/gfs_controld.8 | 184 -
group/man/group_tool.8 | 80 -
group/man/groupd.8 | 64 -
group/test/Makefile | 16 -
group/test/client.c | 45 -
group/test/clientd.c | 179 -
group/tool/Makefile | 37 -
group/tool/main.c | 770 ----
make/binding-passthrough.mk | 7 -
make/clean.mk | 7 -
make/cobj.mk | 18 -
make/copyright.cf | 6 -
make/defines.mk.input | 79 -
make/install.mk | 92 -
make/libs.mk | 59 -
make/official_release_version | 1 -
make/passthrough.mk | 7 -
make/perl-binding-common.mk | 30 -
make/release.mk | 160 -
make/uninstall.mk | 59 -
rgmanager/ChangeLog | 634 ----
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/cpglock-internal.h | 35 -
rgmanager/include/cpglock.h | 40 -
rgmanager/include/daemon_init.h | 10 -
rgmanager/include/ds.h | 13 -
rgmanager/include/event.h | 142 -
rgmanager/include/fdops.h | 14 -
rgmanager/include/findproc.h | 11 -
rgmanager/include/fo_domain.h | 49 -
rgmanager/include/gettid.h | 7 -
rgmanager/include/groups.h | 43 -
rgmanager/include/list.h | 95 -
rgmanager/include/lock.h | 17 -
rgmanager/include/logging.h | 11 -
rgmanager/include/members.h | 40 -
rgmanager/include/message.h | 175 -
rgmanager/include/msgsimple.h | 64 -
rgmanager/include/platform.h | 62 -
rgmanager/include/pthread_dbg.h | 41 -
rgmanager/include/res-ocf.h | 53 -
rgmanager/include/resgroup.h | 252 --
rgmanager/include/reslist.h | 210 --
rgmanager/include/restart_counter.h | 15 -
rgmanager/include/rg_dbus.h | 20 -
rgmanager/include/rg_locks.h | 47 -
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/sock.h | 18 -
rgmanager/include/vf.h | 181 -
rgmanager/init.d/Makefile | 20 -
rgmanager/init.d/cpglockd.in | 147 -
rgmanager/init.d/cpglockd.init.defaults.in | 7 -
rgmanager/init.d/rgmanager.in | 162 -
rgmanager/man/Makefile | 19 -
rgmanager/man/clubufflush.8 | 13 -
rgmanager/man/clufindhostname.8 | 22 -
rgmanager/man/clulog.8 | 27 -
rgmanager/man/clurgmgrd.8 | 1 -
rgmanager/man/clustat.8 | 53 -
rgmanager/man/clusvcadm.8 | 147 -
rgmanager/man/cpglockd.8 | 21 -
rgmanager/man/rgmanager.8 | 392 ---
rgmanager/src/Makefile | 4 -
rgmanager/src/clulib/Makefile | 41 -
rgmanager/src/clulib/ckpt_state.c | 536 ---
rgmanager/src/clulib/cman.c | 249 --
rgmanager/src/clulib/cpg_lock.c | 137 -
rgmanager/src/clulib/daemon_init.c | 229 --
rgmanager/src/clulib/dlm_lock.c | 301 --
rgmanager/src/clulib/fdops.c | 176 -
rgmanager/src/clulib/gettid.c | 24 -
rgmanager/src/clulib/libcpglock.c | 287 --
rgmanager/src/clulib/lock.c | 6 -
rgmanager/src/clulib/locktest.c | 67 -
rgmanager/src/clulib/logging.c | 112 -
rgmanager/src/clulib/members.c | 523 ---
rgmanager/src/clulib/message.c | 273 --
rgmanager/src/clulib/msg_cluster.c | 1272 -------
rgmanager/src/clulib/msg_socket.c | 441 ---
rgmanager/src/clulib/msgsimple.c | 108 -
rgmanager/src/clulib/msgtest.c | 266 --
rgmanager/src/clulib/rg_strings.c | 219 --
rgmanager/src/clulib/sets.c | 353 --
rgmanager/src/clulib/signals.c | 68 -
rgmanager/src/clulib/sock.c | 354 --
rgmanager/src/clulib/tmgr.c | 150 -
rgmanager/src/clulib/vft.c | 1803 ----------
rgmanager/src/clulib/wrap_lock.c | 205 --
rgmanager/src/daemons/Makefile | 126 -
rgmanager/src/daemons/cpglockd.c | 1814 ----------
rgmanager/src/daemons/cpglockdump.c | 8 -
rgmanager/src/daemons/event_config.c | 512 ---
rgmanager/src/daemons/fo_domain.c | 642 ----
rgmanager/src/daemons/groups.c | 1936 ----------
rgmanager/src/daemons/main.c | 1271 -------
rgmanager/src/daemons/reslist.c | 989 ------
rgmanager/src/daemons/resrules.c | 1198 -------
rgmanager/src/daemons/restart_counter.c | 193 -
rgmanager/src/daemons/restree.c | 1931 ----------
rgmanager/src/daemons/rg_event.c | 562 ---
rgmanager/src/daemons/rg_forward.c | 279 --
rgmanager/src/daemons/rg_locks.c | 368 --
rgmanager/src/daemons/rg_queue.c | 71 -
rgmanager/src/daemons/rg_state.c | 2340 -------------
rgmanager/src/daemons/rg_thread.c | 767 ----
rgmanager/src/daemons/sbuf.c | 85 -
rgmanager/src/daemons/service_op.c | 359 --
rgmanager/src/daemons/slang_event.c | 1468 --------
rgmanager/src/daemons/test.c | 450 ---
.../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/update-dbus.c | 319 --
rgmanager/src/daemons/watchdog.c | 108 -
rgmanager/src/resources/Makefile | 12 -
rgmanager/src/resources/default_event_script.sl | 702 ----
rgmanager/src/resources/follow-service.sl | 151 -
rgmanager/src/utils/Makefile | 73 -
rgmanager/src/utils/clubufflush.c | 121 -
rgmanager/src/utils/clufindhostname.c | 77 -
rgmanager/src/utils/clulog.c | 70 -
rgmanager/src/utils/clunfslock.sh | 69 -
rgmanager/src/utils/clustat.c | 1214 -------
rgmanager/src/utils/clusvcadm.c | 463 ---
scripts/uninstall.pl | 71 -
626 files changed, 3 insertions(+), 165144 deletions(-)
diff --git a/Makefile b/Makefile
deleted file mode 100644
index cbca444..0000000
--- a/Makefile
+++ /dev/null
@@ -1,73 +0,0 @@
-include make/defines.mk
-
-REALSUBDIRS = common config cman dlm fence/libfenced group \
- fence gfs2 rgmanager bindings doc \
- contrib
-
-SUBDIRS = $(filter-out \
- $(if ${without_common},common) \
- $(if ${without_config},config) \
- $(if ${without_cman},cman) \
- $(if ${without_dlm},dlm) \
- $(if ${without_fence},fence/libfenced) \
- $(if ${without_group},group) \
- $(if ${without_fence},fence) \
- $(if ${without_gfs2},gfs2) \
- $(if ${without_rgmanager},rgmanager) \
- $(if ${without_bindings},bindings) \
- , $(REALSUBDIRS))
-
-all: ${SUBDIRS}
-
-${SUBDIRS}:
- ${MAKE} -C $@ all
-
-# Dependencies
-
-common:
-config:
-cman: common config
-dlm: config
-fence/libfenced:
-group: cman dlm fence/libfenced
-fence: group
-gfs2: group
-rgmanager: cman dlm
-bindings: cman
-contrib: dlm
-
-oldconfig:
- @if [ -f $(OBJDIR)/.configure.sh ]; then \
- sh $(OBJDIR)/.configure.sh; \
- else \
- echo "Unable to find old configuration data"; \
- fi
-
-install:
- set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
- install -d ${notifyddir}
- install -d ${logdir}
- install -d ${DESTDIR}/var/lib/cluster
- install -d ${DESTDIR}/var/run/cluster
-
-uninstall:
- set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
- rmdir ${notifyddir} || :;
- rmdir ${logdir} || :;
- rmdir ${DESTDIR}/var/lib/cluster || :;
- rmdir ${DESTDIR}/var/run/cluster || :;
-
-clean:
- set -e && for i in ${REALSUBDIRS}; do \
- contrib_code=1 \
- legacy_code=1 \
- ${MAKE} -C $$i $@;\
- done
-
-distclean: clean
- rm -f make/defines.mk
- rm -f .configure.sh
- rm -f *tar.gz
- rm -rf build
-
-.PHONY: ${REALSUBDIRS}
diff --git a/README b/README
new file mode 100644
index 0000000..ded30cd
--- /dev/null
+++ b/README
@@ -0,0 +1,3 @@
+DISCONTINUED ON FEDORAHOSTED.ORG
+
+New home: https://pagure.io/linux-cluster/cluster
diff --git a/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 <fdinitto(a)redhat.com>
-
-=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 <fdinitto(a)redhat.com>
-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 <fdinitto(a)redhat.com>',
- '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 1cf8bc9..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 scripts
diff --git a/cman/cman_tool/Makefile b/cman/cman_tool/Makefile
deleted file mode 100644
index 139ac52..0000000
--- a/cman/cman_tool/Makefile
+++ /dev/null
@@ -1,33 +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}\" -DSBINDIR=\"${sbindir}\"
-CFLAGS += -I${cmanincdir} -I${ccsincdir}
-CFLAGS += -I${corosyncincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${cmanlibdir} -lcman -L${ccslibdir} -lccs
-LDFLAGS += -L${corosynclibdir} -lconfdb
-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 e1250ee..0000000
--- a/cman/cman_tool/cman_tool.h
+++ /dev/null
@@ -1,112 +0,0 @@
-#ifndef __CMAN_TOOL_DOT_H__
-#define __CMAN_TOOL_DOT_H__
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <unistd.h>
-
-extern char *prog_name;
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-
-#define die(fmt, args...) \
-do { \
- fprintf(stderr, "%s: ", prog_name); \
- fprintf(stderr, fmt "\n", ##args); \
- exit(EXIT_FAILURE); \
-} while (0)
-
-#define DEFAULT_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,
- FMT_VOTES,
- FMT_EXP,
- FMT_STATE,
-};
-
-enum validate_options
-{
- VALIDATE_FAIL = 0,
- VALIDATE_WARN,
- VALIDATE_NONE,
-};
-
-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 nostderr_debug;
- int nodeid;
- int timeout;
- unsigned int config_version;
-
- int config_version_opt;
- int config_validate_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 addresses_opt;
- int noconfig_opt;
- int nosync_opt;
- int nosetpri_opt;
- int noopenais_opt;
-};
-typedef struct commandline commandline_t;
-
-int join(commandline_t *comline, char *envp[]);
-const 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 b78d5ab..0000000
--- a/cman/cman_tool/join.c
+++ /dev/null
@@ -1,395 +0,0 @@
-#include <sys/wait.h>
-#include <stdint.h>
-#include <signal.h>
-#include <netinet/in.h>
-#include <corosync/confdb.h>
-#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(void)
-{
- 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");
- }
-
- /* We leave stderr open to allow error messags through.
- the cman plugin will close it when it's all started
- up properly.
- */
- setsid();
-}
-
-
-static const char *corosync_exit_reason(signed char status)
-{
- static char reason[256];
- switch (status) {
- case 1:
- return "Could not determine UID to run as";
- break;
- case 2:
- return "Could not determine GID to run as";
- break;
- case 3:
- return "Error initialising memory pool";
- break;
- case 4:
- return "Could not fork";
- break;
- case 5:
- return "Could not bind to libais socket";
- break;
- case 6:
- return "Could not bind to network socket";
- break;
- case 7:
- return "Could not read security key for communications";
- break;
- case 8:
- return "Could not read cluster configuration";
- break;
- case 9:
- return "Could not set up logging";
- break;
- case 11:
- return "Could not dynamically load modules";
- break;
- case 12:
- return "Could not load and initialise object database";
- break;
- case 13:
- return "Could not initialise all required services";
- break;
- case 14:
- return "Out of memory";
- break;
- case 15:
- return "Fatal error";
- break;
- case 16:
- return "Required directory not present /var/lib/corosync.";
- break;
- case 17:
- return "Could not acquire lock";
- break;
- case 18:
- return "Another Corosync instance is already running";
- break;
- default:
- sprintf(reason, "Error, reason code is %d", status);
- return reason;
- break;
- }
-}
-
-static int check_corosync_status(pid_t pid)
-{
- int status;
- int pidstatus;
-
- status = waitpid(pid, &pidstatus, WNOHANG);
- if (status == -1 && errno == ECHILD) {
-
- return 0;
- }
- if (status == pid && pidstatus != 0) {
- if (WIFEXITED(pidstatus))
- fprintf(stderr, "corosync died: %s\n", corosync_exit_reason(WEXITSTATUS(pidstatus)));
- if (WIFSIGNALED(pidstatus))
- fprintf(stderr, "corosync died with signal: %d\n", WTERMSIG(pidstatus));
- exit(1);
- }
- return status;
-}
-
-int join(commandline_t *comline, char *main_envp[])
-{
- int i, err;
- int envptr = 0;
- int argvptr = 0;
- char scratch[1024];
- char config_modules[1024];
- cman_handle_t h = NULL;
- int status;
- hdb_handle_t object_handle;
- confdb_handle_t confdb_handle;
- int res;
- pid_t corosync_pid;
- int p[2];
- confdb_callbacks_t callbacks = {
- .confdb_key_change_notify_fn = NULL,
- .confdb_object_create_change_notify_fn = NULL,
- .confdb_object_delete_change_notify_fn = NULL
- };
-
- /*
- * 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_DEBUG=%d", comline->verbose);
- envp[envptr++] = strdup(scratch);
- }
- if (comline->nostderr_debug) {
- snprintf(scratch, sizeof(scratch), "CMAN_NOSTDERR_DEBUG=true");
- envp[envptr++] = strdup(scratch);
- }
- if (comline->noconfig_opt) {
- envp[envptr++] = strdup("CMAN_NOCONFIG=true");
- snprintf(config_modules, sizeof(config_modules), "cmanpreconfig");
- }
- else {
- snprintf(config_modules, sizeof(config_modules), "%s:cmanpreconfig", comline->config_lcrso);
- }
- if (comline->noopenais_opt) {
- envp[envptr++] = strdup("CMAN_NOOPENAIS=true");
- }
-
- snprintf(scratch, sizeof(scratch), "COROSYNC_DEFAULT_CONFIG_IFACE=%s", config_modules);
- 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;
-
- /* Always run corosync -f because we have already forked twice anyway, and
- we want to return any exit code that might happen */
- /* also strdup strings because it's otherwise virtually impossible to fix
- * build warnings due to the way argv C implementation is done */
- argv[0] = strdup("corosync");
- argv[++argvptr] = strdup("-f");
- if (comline->nosetpri_opt)
- argv[++argvptr] = strdup("-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; i<envptr-1; i++) {
- fprintf(stderr, "%s\n", envp[i]);
- }
- }
- be_daemon();
-
- sprintf(scratch, "FORKED: %d\n", getpid());
- err = write(p[1], scratch, strlen(scratch));
-
- 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];
- char *messageptr = message;
-
- FD_ZERO(&fds);
- FD_SET(p[0], &fds);
-
- status = select(p[0]+1, &fds, NULL, NULL, &tv);
-
- /* Did we get a cman-reported error? */
- if (status == 1) {
- int len;
- if ((len = read(p[0], message, sizeof(message)) > 0)) {
-
- /* Forked OK - get the real corosync pid */
- if (sscanf(messageptr, "FORKED: %d", &corosync_pid) == 1) {
- if (comline->verbose & DEBUG_STARTUP_ONLY)
- fprintf(stderr, "forked process ID is %d\n", corosync_pid);
- status = 0;
-
- /* There might be a SUCCESS or error message in the pipe too. */
- messageptr = strchr(messageptr, '\n');
- if (messageptr && strlen(messageptr) > 1)
- messageptr++;
- else
- continue;
- }
- /* Success! get the new PID of double-forked corosync */
- if (sscanf(messageptr, "SUCCESS: %d", &corosync_pid) == 1) {
- if (comline->verbose & DEBUG_STARTUP_ONLY)
- fprintf(stderr, "corosync running, process ID is %d\n", corosync_pid);
- status = 0;
- break;
- }
- else if (messageptr) {
- fprintf(stderr, "%s\n", messageptr);
- status = 1;
- break;
- }
- }
- else if (len < 0 && errno == EINTR) {
- continue;
- }
- else { /* Error or EOF - check the child status */
- status = check_corosync_status(corosync_pid);
- if (status == 0)
- break;
- }
- }
-
- } 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) {
- status = check_corosync_status(corosync_pid);
- die("corosync died during startup\n");
- }
-
- h = cman_admin_init(NULL);
- if (!h && comline->verbose & DEBUG_STARTUP_ONLY)
- {
- fprintf(stderr, "waiting for cman to start\n");
- status = check_corosync_status(corosync_pid);
- }
- }
- 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);
-
- /* Copy all COROSYNC_* environment variables into objdb so they can be used to validate new configurations later */
- res = confdb_initialize (&confdb_handle, &callbacks);
- if (res != CS_OK)
- goto join_exit;
-
- res = confdb_object_create(confdb_handle, OBJECT_PARENT_HANDLE, "cman_private", strlen("cman_private"), &object_handle);
- if (res == CS_OK) {
- int envnum = 0;
- const char *envvar = main_envp[envnum];
- const char *equal;
- char envname[PATH_MAX];
-
-
- while (envvar) {
- if (strncmp("COROSYNC_", envvar, 9) == 0) {
- equal = strchr(envvar, '=');
- if (equal) {
- strncpy(envname, envvar, PATH_MAX);
- if (equal-envvar < PATH_MAX) {
- envname[equal-envvar] = '\0';
-
- res = confdb_key_create_typed(confdb_handle, object_handle, envname,
- equal+1, strlen(equal+1),CONFDB_VALUETYPE_STRING);
- }
- }
- }
- envvar = main_envp[++envnum];
- }
- }
- res = confdb_key_create_typed(confdb_handle, object_handle,
- "COROSYNC_DEFAULT_CONFIG_IFACE",
- config_modules, strlen(config_modules), CONFDB_VALUETYPE_STRING);
- confdb_finalize (confdb_handle);
-
-join_exit:
- return 0;
-}
diff --git a/cman/cman_tool/main.c b/cman/cman_tool/main.c
deleted file mode 100644
index 958c35b..0000000
--- a/cman/cman_tool/main.c
+++ /dev/null
@@ -1,1290 +0,0 @@
-#include <inttypes.h>
-#include <unistd.h>
-#include <signal.h>
-#include <time.h>
-#include <corosync/confdb.h>
-#include <netinet/in.h>
-#include "copyright.cf"
-#include "libcman.h"
-#include "cman_tool.h"
-
-#define DEFAULT_CONFIG_MODULE "xmlconfig"
-
-#define OPTION_STRING ("m:n:v:e:2p:c:i:N:t:o:k:F:C:VAPwfqazh?XD::Sd::r::")
-#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
-
-static void print_usage(int subcmd)
-{
- printf("Usage:\n");
- printf("\n");
- printf("%s <join|leave|kill|expected|votes|version|wait|status|nodes|services|debug> [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 <addr> Multicast address to use\n");
- printf(" -v <votes> Number of votes this node has\n");
- printf(" -e <votes> Number of expected votes for the cluster\n");
- printf(" -p <port> UDP port number for cman communications\n");
- printf(" -n <nodename> The name of this node (defaults to hostname)\n");
- printf(" -c <clustername> The name of the cluster to join\n");
- printf(" -N <id> Node id\n");
- printf(" -C <module> 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 <file> Private key file for Corosync communications\n");
- printf(" -P Don't set corosync to realtime priority\n");
- printf(" -X Use internal cman defaults for configuration\n");
- printf(" -A Don't load openais services\n");
- printf(" -D<fail|warn|none> What to do about the config. Default (without -D) is to\n");
- printf(" validate the config. with -D no validation will be done.\n");
- printf(" -Dwarn will print errors but allow the operation to continue.\n");
- printf(" -z Disable stderr debugging output.\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 <nodename> The name of the node to kill (can specify multiple times)\n");
- printf("\n");
- }
-
- if (!subcmd || subcmd == OP_EXPECTED) {
- printf("expected\n");
- printf(" -e <votes> New number of expected votes for the cluster\n");
- printf("\n");
- }
-
- if (!subcmd || subcmd == OP_VOTES) {
- printf("votes\n");
- printf(" -v <votes> 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(" -a Also show node address(es)\n");
- printf(" -n <nodename> Only show information for specific node\n");
- printf(" -F <format> 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 Reload cluster.conf and update config version.\n");
- printf(" -D <fail,warn,none> What to do about the config. Default (without -D) is to\n");
- printf(" validate the config. with -D no validation will be done. -Dwarn will print errors\n");
- printf(" but allow the operation to continue\n");
- printf(" -S Don't run ccs_sync to distribute cluster.conf (if appropriate)\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_DISALLOWED_ENABLED)
- printf(" DisallowedEnabled");
- if (einfo->ei_flags & CMAN_EXTRA_FLAG_DIRTY)
- printf(" HaveState");
- 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: %u\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; i<numnodes; i++) {
- printf("%s ", nodes[i].cn_name);
- }
- printf("\n");
- }
- }
- cman_finish(h);
-}
-
-static int node_compare(const void *va, const void *vb)
-{
- const cman_node_t *a = va;
- const cman_node_t *b = vb;
- return a->cn_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;
- if (!strcmp(opt, "votes"))
- return FMT_VOTES;
- if (!strcmp(opt, "exp"))
- return FMT_EXP;
- if (!strcmp(opt, "state"))
- return FMT_STATE;
-
- 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 *jtime;
- int numaddrs;
- struct cman_node_address addrs[MAX_INTERFACES];
- char jstring[1024];
- int i,j,k;
- unsigned int tmpid;
- cman_node_extra_t enode;
-
- 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;
- }
-
- /* Make the name more friendly if cman can't find it in cluster.conf
- * (we really don't want corosync to look up names in DNS so it invents them)
- */
- if (sscanf(node->cn_name, "Node%u", &tmpid) == 1 && tmpid == node->cn_nodeid) {
- if (!cman_get_node_addrs(h, node->cn_nodeid, MAX_INTERFACES, &numaddrs, addrs) && numaddrs) {
- getnameinfo((struct sockaddr *)addrs[0].cna_address, addrs[0].cna_addrlen, node->cn_name, sizeof(node->cn_name), NULL, 0, NI_NAMEREQD);
- }
- }
-
- 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("%4u %c %5d %s %s\n",
- node->cn_nodeid, member_type,
- node->cn_incarnation, jstring, node->cn_name);
- }
-
- 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 && (cman_get_node_extra(h, node->cn_nodeid, &enode) == 0)) {
- for (j = 0; j < MAX_FORMAT_OPTS; j++) {
- switch (format[j]) {
- case FMT_NONE:
- break;
- case FMT_ID:
- printf("%u ", node->cn_nodeid);
- break;
- case FMT_NAME:
- printf("%s ", node->cn_name);
- break;
- case FMT_TYPE:
- printf("%c ", member_type);
- break;
- case FMT_VOTES:
- printf("%d ", enode.cnx_votes);
- break;
- case FMT_EXP:
- printf("%d ", enode.cnx_expected_votes);
- break;
- case FMT_STATE:
- switch (enode.cnx_state)
- {
- case CLUSTER_NODESTATE_JOINING:
- printf("Joining ");
- break;
- case CLUSTER_NODESTATE_MEMBER:
- printf("Member ");
- break;
- case CLUSTER_NODESTATE_DEAD:
- printf("Dead ");
- break;
- case CLUSTER_NODESTATE_LEAVING:
- printf("Leaving ");
- break;
- case CLUSTER_NODESTATE_DISALLOWED:
- printf("Disallowed ");
- break;
- default:
- printf("Unknown ");
- break;
- }
- 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");
-}
-
-
-const char *cman_error(int err)
-{
- const 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 && !comline->wait_opt) {
- die("Error leaving cluster: %s", cman_error(errno));
- }
- cman_finish(h);
-
- /* Wait until cman shuts down */
- if (comline->wait_opt) {
- while ( (h = cman_admin_init(NULL)) ) {
- cman_finish(h);
- sleep(1);
- }
- }
-}
-
-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 int validate_config(commandline_t *comline, int current_version)
-{
- struct stat st;
- char command[PATH_MAX];
- char validator[PATH_MAX];
- char ccs_quiet[8];
- int cmd_res;
-
- /* Look for ccs_config_validate */
- snprintf(validator, sizeof(validator), "%s/ccs_config_validate", SBINDIR);
- if (stat(validator, &st) != 0 || !(st.st_mode & S_IXUSR)) {
- fprintf(stderr, "Cannot find ccs_config_validate, configuration was not checked but assumed to be OK.\n");
- return 0;
- }
-
- if (comline->verbose > 1) {
- snprintf(ccs_quiet, sizeof(ccs_quiet), " ");
- } else {
- snprintf(ccs_quiet, sizeof(ccs_quiet), "-q");
- }
-
- if (current_version) {
- snprintf(command, sizeof(command), "%s %s -R %d",
- validator, ccs_quiet, current_version);
- } else {
- snprintf(command, sizeof(command), "%s %s",
- validator, ccs_quiet);
- }
-
- if (comline->verbose > 1)
- printf("calling '%s'\n", command);
-
- cmd_res = system(command);
-
- return WEXITSTATUS(cmd_res);
-}
-
-/* Here we set the COROSYNC_ variables that might be needed by the corosync
- configuration modules. We just put them into the environment and leave
- them for the sub-process to pick up.
- 'config_modules' is returned separately because it's needed internally to
- and it saves the caller from extracting it all over again.
- We only return 0 (success) if config_modules is returned as without that
- the caller can't really do anything at all.
-*/
-static int get_config_variables(commandline_t *comline, char **config_modules)
-{
- int res;
- int got_iface = 1;
- char key_name[1024];
- char *key_value = NULL;
- size_t key_value_len;
- confdb_value_types_t type;
- hdb_handle_t confdb_handle;
- hdb_handle_t cmanp_handle;
- confdb_callbacks_t callbacks = {
- .confdb_key_change_notify_fn = NULL,
- .confdb_object_create_change_notify_fn = NULL,
- .confdb_object_delete_change_notify_fn = NULL
- };
-
- *config_modules = NULL;
- res = confdb_initialize (&confdb_handle, &callbacks);
- if (res != CS_OK)
- return 0;
-
- res = confdb_object_find_start(confdb_handle, OBJECT_PARENT_HANDLE);
- if (res != CS_OK)
- goto finish;
-
- res = confdb_object_find(confdb_handle, OBJECT_PARENT_HANDLE, "cman_private", strlen("cman_private"), &cmanp_handle);
- if (res != CS_OK)
- goto finish;
-
- res = confdb_key_iter_start(confdb_handle, cmanp_handle);
- if (res != CS_OK)
- goto finish;
-
- while ( (res = confdb_key_iter_typed2(confdb_handle, cmanp_handle, key_name,
- (void**)&key_value, &key_value_len, &type)) == CS_OK) {
- key_value[key_value_len] = '\0';
-
- setenv(key_name, key_value, 1);
- if (strcmp(key_name, "COROSYNC_DEFAULT_CONFIG_IFACE") == 0) {
- *config_modules = strdup(key_value);
- got_iface = 0;
- }
- free(key_value);
- key_value = NULL;
- }
-
-finish:
- confdb_finalize(confdb_handle);
- return got_iface;
-}
-
-static void version(commandline_t *comline)
-{
- struct cman_version ver;
- cman_handle_t h;
- int result;
- char *config_modules = NULL;
-
- 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_opt) {
- printf("%d.%d.%d config %d\n", ver.cv_major, ver.cv_minor, ver.cv_patch,
- ver.cv_config);
- goto out;
- }
-
- if (comline->verbose)
- printf("Getting config variables\n");
- if (get_config_variables(comline, &config_modules))
- die("cannot get COROSYNC_DEFAULT_CONFIG_IFACE");
-
- /* By default we validate the configuration first */
- if (comline->config_validate_opt != VALIDATE_NONE) {
-
- if (comline->verbose)
- printf("Validating configuration\n");
- result = validate_config(comline, ver.cv_config);
- if (result == 253)
- /* Unable to find new config version */
- die("Unable to retrive the new config version\n");
- if (result == 254)
- /* Config regression = fail. */
- die("Not reloading, config version older or equal the running config");
- if (result == 255)
- /* Generic error from ccs_config_validate */
- die("Not reloading, generic error running ccs_config_validate\n"
- "Try re-running with -d options");
- else if (result && comline->config_validate_opt == VALIDATE_FAIL)
- die("Not reloading, configuration is not valid");
- }
-
- /* We don't bother looking for ccs_sync here - just assume it's in /usr/bin and
- that it exists. If this is not true then then user can choose to bypass
- the disibution and do it themselves.
- Note that ccs_sync might prompt on stderr for passwords the first time it is
- run.
- */
- if (strstr(config_modules, "xmlconfig") && !comline->nosync_opt) {
- if (comline->verbose > 1)
- printf("calling ccs_sync\n");
- result = system("/usr/bin/ccs_sync");
- if (result)
- die("ccs_sync failed.\nIf you have distributed the config file yourself, try re-running with -S\n");
- }
-
- if (comline->verbose)
- printf("Telling cman the new version number\n");
-
- ver.cv_config = comline->config_version;
-
- result = cman_set_version(h, &ver);
-
- switch(result) {
- case 0:
- if (comline->verbose)
- printf("Configuration succesfully updated or already running\n");
- break;
- default:
- die("Error loading configuration in corosync/cman");
- break;
- }
- 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; i<comline->num_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);
-}
-
-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 suboptchar;
- int show_help = 0;
- char buf[16];
-
- while (cont) {
- optchar = getopt(argc, argv, OPTION_STRING);
-
- switch (optchar) {
-
- case 'm':
- comline->multicast_addr = strdup(optarg);
- break;
-
- case 'a':
- comline->addresses_opt = 1;
- break;
-
- case 'D':
- /* Just look at the upper-cased version of the first letter of the argument */
- if (optarg) {
- suboptchar = optarg[0] & 0x5F;
- switch (suboptchar)
- {
- case 'F':
- comline->config_validate_opt = VALIDATE_FAIL;
- break;
- case 'W':
- comline->config_validate_opt = VALIDATE_WARN;
- break;
- case 'N':
- comline->config_validate_opt = VALIDATE_NONE;
- break;
- default:
- die("invalid option to -D, it should be 'force', 'warn' or 'none'\n");
- break;
- }
- }
- else {
- comline->config_validate_opt = VALIDATE_NONE;
- }
- break;
- case 'S':
- comline->nosync_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 = 0;
- comline->config_version_opt = TRUE;
- if (optarg) {
- fprintf(stderr, "Warning: specifying a "
- "version for the -r flag is "
- "deprecated and no longer used\n");
- }
- 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 'z':
- comline->nostderr_debug = 1;
- 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;
- };
- }
-
- if (comline->config_lcrso == NULL)
- comline->config_lcrso = strdup(DEFAULT_CONFIG_MODULE);
-
- 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;
- } else if (strcmp(argv[optind], "remove") == 0) {
- comline->remove = TRUE;
- } else if (strcmp(argv[optind], "force") == 0) {
- comline->force = TRUE;
- } else {
- snprintf(buf, sizeof(buf),
- "%d", atoi(argv[optind]));
- if (!strcmp(buf, argv[optind]) &&
- (comline->config_version_opt == TRUE) &&
- comline->operation == OP_VERSION) {
- fprintf(stderr, "Warning: specifying a "
- "version for the -r flag is "
- "deprecated and no longer used\n");
- } 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");
-}
-
-
-static void do_join(commandline_t *comline, char *envp[])
-{
- int ret;
-
- check_arguments(comline);
-
- if (comline->timeout) {
- signal(SIGALRM, sigalarm_handler);
- alarm(comline->timeout);
- }
-
- /* By default we validate the configuration first */
- if (comline->config_validate_opt != VALIDATE_NONE) {
-
- if (comline->verbose)
- printf("Validating configuration\n");
-
- if (validate_config(comline, 0) &&
- comline->config_validate_opt == VALIDATE_FAIL)
- die("Not joining, configuration is not valid\n");
- }
-
- 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);
- }
-}
-
-int main(int argc, char *argv[], char *envp[])
-{
- commandline_t comline;
-
- prog_name = argv[0];
-
- memset(&comline, 0, sizeof(commandline_t));
-
- decode_arguments(argc, argv, &comline);
-
- switch (comline.operation) {
- case OP_JOIN:
- do_join(&comline, envp);
- 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;
- }
-
- exit(EXIT_SUCCESS);
-}
-
-char *prog_name;
diff --git a/cman/daemon/Makefile b/cman/daemon/Makefile
deleted file mode 100644
index 1329de3..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 \
- ais.o \
- commands.o \
- barrier.o \
- cmanconfig.o
-
-OBJS2= cman-preconfig.o \
- fnvhash.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 6b5640a..0000000
--- a/cman/daemon/ais.c
+++ /dev/null
@@ -1,378 +0,0 @@
-#include <sys/poll.h>
-#include <sys/types.h>
-#include <sys/errno.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/socket.h>
-#include <sys/utsname.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <inttypes.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-/* corosync headers */
-#include <corosync/corotypes.h>
-#include <corosync/corotypes.h>
-#include <corosync/coroipc_types.h>
-#include <corosync/coroipcc.h>
-#include <corosync/corodefs.h>
-#include <corosync/mar_gen.h>
-#include <corosync/engine/coroapi.h>
-#include <corosync/engine/logsys.h>
-#include <corosync/engine/quorum.h>
-#include <corosync/lcr/lcr_comp.h>
-
-#include "list.h"
-#include "cnxman-socket.h"
-#include "cnxman-private.h"
-#include "commands.h"
-
-#include "ais.h"
-#include "cman.h"
-#define OBJDB_API struct corosync_api_v1
-#include "nodelist.h"
-#include "cmanconfig.h"
-#include "daemon.h"
-
-extern char cluster_name[MAX_CLUSTER_NAME_LEN+1];
-extern unsigned int quorumdev_poll;
-extern unsigned int ccsd_poll_interval;
-extern unsigned int enable_disallowed;
-extern unsigned int shutdown_timeout;
-extern unsigned int startup_config_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;
-quorum_set_quorate_fn_t corosync_set_quorum;
-struct memb_ring_id cman_ring_id;
-extern unsigned int config_version;
-static hdb_handle_t cluster_parent_handle;
-
-static int startup_pipe;
-static int first_trans = 1;
-struct corosync_api_v1 *corosync;
-
-static hdb_handle_t group_handle;
-static struct corosync_tpg_group cman_group[1] = {
- { .group = "CMAN", .group_len = 4},
-};
-
-LOGSYS_DECLARE_SUBSYS (CMAN_NAME);
-
-/* 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,
- const unsigned int *member_list, size_t member_list_entries,
- const unsigned int *left_list, size_t left_list_entries,
- const unsigned int *joined_list, size_t joined_list_entries,
- const struct memb_ring_id *ring_id);
-static void cman_deliver_fn(unsigned int nodeid, const void *msg, unsigned int msg_len,
- int endian_conversion_required);
-static void cman_quorum_init(struct corosync_api_v1 *api, quorum_set_quorate_fn_t report);
-
-/*
- * 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,
- .sync_mode = CS_SYNC_V1,
-};
-
-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 quorum_services_api_ver1 cman_quorum_iface_ver0 = {
- .init = cman_quorum_init
-};
-
-static struct lcr_iface ifaces_ver0[2] = {
- {
- .name = "corosync_cman",
- .version = 0,
- .versions_replace = 0,
- .versions_replace_count = 0,
- .dependencies = 0,
- .dependency_count = 0,
- .constructor = NULL,
- .destructor = NULL,
- .interfaces = NULL,
- },
- {
- .name = "quorum_cman",
- .version = 0,
- .versions_replace = 0,
- .versions_replace_count = 0,
- .dependencies = 0,
- .dependency_count = 0,
- .constructor = NULL,
- .destructor = NULL,
- .interfaces = (void **)(void *)&cman_quorum_iface_ver0,
- },
-};
-
-static struct lcr_comp cman_comp_ver0 = {
- .iface_count = 2,
- .ifaces = ifaces_ver0,
-};
-
-
-__attribute__ ((constructor)) static void cman_comp_register(void) {
- lcr_interfaces_set(&ifaces_ver0[0], &cman_service_handler_iface);
- lcr_interfaces_set(&ifaces_ver0[1], &cman_quorum_iface_ver0);
- lcr_component_register(&cman_comp_ver0);
-}
-
-/* ------------------------------- */
-
-static void cman_quorum_init(struct corosync_api_v1 *api, quorum_set_quorate_fn_t report)
-{
- corosync = api;
- corosync_set_quorum = report;
-}
-
-static int cman_exec_init_fn(struct corosync_api_v1 *api)
-{
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
- hdb_handle_t totem_handle;
- char pipe_msg[256];
- unsigned int totem_token;
-
- 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);
-
- /*
- * quorum_dev_poll should default to the token timeout so that quorum devices behave
- * like nodes
- */
- corosync->object_find_create(OBJECT_PARENT_HANDLE, "totem", strlen("totem"), &find_handle);
- corosync->object_find_next(find_handle, &totem_handle);
- objdb_get_int(api, totem_handle, "token", &totem_token, 1000);
- 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, totem_token);
- 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, "disallowed", &enable_disallowed, DEFAULT_DISALLOWED);
- objdb_get_int(api, object_handle, "startup_config_timeout", &startup_config_timeout, DEFAULT_STARTUP_CONFIG_TIMEOUT);
- }
- corosync->object_find_destroy(find_handle);
- log_printf(LOGSYS_LEVEL_DEBUG, 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(api);
-
- /* 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);
-
- if (getenv("CMAN_NOSTDERR_DEBUG")) {
- int tmpfd;
- tmpfd = open("/dev/null", O_RDWR);
- if (tmpfd > -1 && tmpfd != STDERR_FILENO) {
- dup2(tmpfd, STDERR_FILENO);
- close(tmpfd);
- }
- }
-
- 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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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);
-}
-
-static void cman_deliver_fn(unsigned int nodeid, const void *msg, unsigned int msg_len,
- int endian_conversion_required)
-{
- const struct cl_protheader *original_header = msg;
- struct cl_protheader header;
- const char *buf = msg;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "ais: deliver_fn source nodeid = %d, len=%d, endian_conv=%d\n",
- nodeid, msg_len, endian_conversion_required);
-
- if (endian_conversion_required) {
- header.srcid = swab32(original_header->srcid);
- header.tgtid = swab32(original_header->tgtid);
- header.flags = swab32(original_header->flags);
- header.srcport = original_header->srcport;
- header.tgtport = original_header->tgtport;
- }
- else {
- memcpy(&header, original_header, sizeof(header));
- }
-
- /* 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), msg_len - sizeof(struct cl_protheader),
- endian_conversion_required);
- }
-}
-
-static void cman_confchg_fn(enum totem_configuration_type configuration_type,
- const unsigned int *member_list, size_t member_list_entries,
- const unsigned int *left_list, size_t left_list_entries,
- const unsigned int *joined_list, size_t joined_list_entries,
- const struct memb_ring_id *ring_id)
-{
- int i;
- static int last_memb_count = 0;
- static size_t saved_left_list_entries;
- static size_t saved_left_list_size;
- static unsigned int *saved_left_list = NULL;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "ais: confchg_fn called type = %d, seq=%lld\n", configuration_type, ring_id->seq);
-
- memcpy(&cman_ring_id, ring_id, sizeof(*ring_id));
- incarnation = ring_id->seq;
- num_ais_nodes = member_list_entries;
-
- /* Tell the cman membership layer */
- for (i=0; i<left_list_entries; i++)
- del_ais_node(left_list[i]);
-
- /* Joining nodes are only added after a valid TRANSITION message
- * is received.
- */
-
- /* Save the left list for later so we can do a consolidated confchg message */
- if (configuration_type == TOTEM_CONFIGURATION_TRANSITIONAL) {
- if (saved_left_list == NULL) {
- saved_left_list_size = left_list_entries*2;
- saved_left_list = malloc(sizeof(int) * saved_left_list_size);
- if (!saved_left_list) {
- log_printf(LOGSYS_LEVEL_CRIT, "cannot allocate memory for confchg message");
- exit(3);
- }
- }
- if (saved_left_list_size < left_list_entries) {
- saved_left_list_size = left_list_entries*2;
- saved_left_list = realloc(saved_left_list, sizeof(int) * saved_left_list_size);
- if (!saved_left_list) {
- log_printf(LOGSYS_LEVEL_CRIT, "cannot reallocate memory for confchg message");
- exit(3);
- }
- }
- saved_left_list_entries = left_list_entries;
- memcpy(saved_left_list, left_list, left_list_entries * sizeof(int));
- }
-
- if (configuration_type == TOTEM_CONFIGURATION_REGULAR) {
- log_printf(LOGSYS_LEVEL_DEBUG, "ais: last memb_count = %d, current = %"PRIuFAST32"\n", last_memb_count, member_list_entries);
- send_transition_msg(last_memb_count, first_trans);
- last_memb_count = member_list_entries;
- if (member_list_entries > 1)
- first_trans = 0;
-
- cman_send_confchg(member_list, member_list_entries,
- saved_left_list, saved_left_list_entries,
- joined_list, joined_list_entries);
- }
-}
-
-void corosync_shutdown(void)
-{
- corosync->shutdown_request();
-}
-
-/* Write an error message down the CMAN startup pipe so
- that cman_tool can display it */
-int write_cman_pipe(const 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 44b1a8c..0000000
--- a/cman/daemon/ais.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <corosync/engine/quorum.h>
-/* 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;
-extern quorum_set_quorate_fn_t corosync_set_quorum;
-extern struct memb_ring_id cman_ring_id;
-extern void corosync_shutdown(void);
diff --git a/cman/daemon/barrier.c b/cman/daemon/barrier.c
deleted file mode 100644
index f4362cf..0000000
--- a/cman/daemon/barrier.c
+++ /dev/null
@@ -1,471 +0,0 @@
-#include <getopt.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/utsname.h>
-#include <sys/un.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/signal.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <sys/errno.h>
-
-#include <corosync/corotypes.h>
-#include <corosync/coroipc_types.h>
-#include <corosync/coroipcc.h>
-#include <corosync/corodefs.h>
-#include <corosync/mar_gen.h>
-#include <corosync/engine/coroapi.h>
-#include <corosync/engine/logsys.h>
-#include "list.h"
-#include "cnxman-socket.h"
-#include "cnxman-private.h"
-#include "daemon.h"
-#include "commands.h"
-#include "barrier.h"
-#include "cman.h"
-#include "ais.h"
-
-extern int we_are_a_cluster_member;
-
-LOGSYS_DECLARE_SUBSYS (CMAN_NAME);
-
-/* 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);
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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)
-{
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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);
- }
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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 99ee80d..0000000
--- a/cman/daemon/cman-preconfig.c
+++ /dev/null
@@ -1,1796 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/utsname.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/errno.h>
-#include <netdb.h>
-#include <fcntl.h>
-#define SYSLOG_NAMES
-#include <sys/syslog.h>
-#include <ifaddrs.h>
-#include <arpa/inet.h>
-
-/* corosync headers */
-#include <corosync/engine/logsys.h>
-#include <corosync/lcr/lcr_comp.h>
-#include <corosync/engine/objdb.h>
-#include <corosync/engine/config.h>
-
-#include "cman.h"
-#define OBJDB_API struct objdb_iface_ver0
-#include "cnxman-socket.h"
-#include "nodelist.h"
-#include "fnvhash.h"
-
-#define MAX_PATH_LEN PATH_MAX
-
-enum tx_mech {
- TX_MECH_UDP,
- TX_MECH_UDPB,
- TX_MECH_UDPU,
- TX_MECH_RDMA,
-};
-
-static unsigned int debug;
-static int cmanpre_readconfig(struct objdb_iface_ver0 *objdb, const char **error_string);
-static int cmanpre_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, const 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 int num_nodenames;
-static char *key_filename=NULL;
-static char *cluster_name;
-static char error_reason[1024] = { '\0' };
-static hdb_handle_t cluster_parent_handle;
-static int use_hashed_cluster_id = 1;
-static unsigned int portnum = 0;
-static unsigned int altportnum = 0;
-static char *mcast_name = NULL;
-static char *altmcast_name = NULL;
-static unsigned int ttl = 1;
-static unsigned int altttl = 1;
-
-
-/*
- * 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;
-
- if (addr1->ss_family != addr2->ss_family)
- return 0;
-
- if (addr1->ss_family == AF_INET) {
- addrlen = sizeof(struct sockaddr_in);
- }
- if (addr1->ss_family == AF_INET6) {
- addrlen = sizeof(struct sockaddr_in6);
- }
- assert(addrlen);
-
- if (memcmp(addr1, addr2, addrlen) == 0)
- return 1;
- else
- return 0;
-
-}
-
-/* Adds a service to objdb for the main corosync engine to load */
-static void add_service(struct objdb_iface_ver0 *objdb, const char *name)
-{
- hdb_handle_t object_handle;
-
- objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
- "service", strlen("service"));
- objdb->object_key_create_typed(object_handle, "name",
- name, strlen(name) + 1, OBJDB_VALUETYPE_STRING);
- objdb->object_key_create_typed(object_handle, "ver",
- "0", 2, OBJDB_VALUETYPE_STRING);
-}
-
-/* Build a localhost ip_address */
-static int get_localhost(int family, struct sockaddr_storage *localhost)
-{
- const 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, int family_hint)
-{
- 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;
- ahints.ai_family = family_hint;
-
- /* 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 hdb_handle_t find_cman_logger(struct objdb_iface_ver0 *objdb, hdb_handle_t object_handle)
-{
- hdb_handle_t subsys_handle;
- hdb_handle_t find_handle;
- char *str;
-
- objdb->object_find_create(object_handle, "logger_subsys", strlen("logger_subsys"), &find_handle);
- while (!objdb->object_find_next(find_handle, &subsys_handle)) {
- if (!objdb_get_string(objdb, subsys_handle, "subsys", &str)) {
- if (strncmp(str, CMAN_NAME, 4) == 0) {
- objdb->object_find_destroy(find_handle);
- return subsys_handle;
- }
- }
- }
- objdb->object_find_destroy(find_handle);
-
- return -1;
-
-}
-
-static int add_udpu_members(struct objdb_iface_ver0 *objdb, hdb_handle_t interface_object_handle)
-{
- char *cur_nodename;
- hdb_handle_t altname_handle;
- hdb_handle_t find_handle = 0;
- hdb_handle_t find_handle2 = 0;
- hdb_handle_t member_object_handle;
- hdb_handle_t nodes_handle;
- int cur_altname_depth;
-
- nodes_handle = nodeslist_init(objdb, cluster_parent_handle, &find_handle);
- while (nodes_handle) {
- if (num_interfaces == 0) {
- if (objdb_get_string(objdb, nodes_handle, "name", &cur_nodename)) {
- nodes_handle = nodeslist_next(objdb, find_handle);
- continue;
- }
- } else {
- objdb->object_find_create(nodes_handle, "altname", strlen("altname"), &find_handle2);
-
- cur_altname_depth = 0;
- while (objdb->object_find_next(find_handle2, &altname_handle) == 0 &&
- cur_altname_depth < num_interfaces)
- cur_altname_depth++;
-
- if (cur_altname_depth == num_interfaces) {
- if (objdb_get_string(objdb, altname_handle, "name", &cur_nodename)) {
- nodes_handle = nodeslist_next(objdb, find_handle);
- continue;
- }
- } else {
- nodes_handle = nodeslist_next(objdb, find_handle);
- continue;
- }
- objdb->object_find_destroy(find_handle2);
- }
-
- if (objdb->object_create(interface_object_handle, &member_object_handle,
- "member", strlen("member")) == 0) {
- objdb->object_key_create_typed(member_object_handle, "memberaddr",
- cur_nodename, strlen(cur_nodename)+1, OBJDB_VALUETYPE_STRING);
- }
-
- nodes_handle = nodeslist_next(objdb, find_handle);
- }
- objdb->object_find_destroy(find_handle);
-
- return 0;
-}
-
-#define PRIMARY_IFACE 0
-#define ALT_IFACE 1
-
-static int add_ifaddr(struct objdb_iface_ver0 *objdb, char *mcast, char *ifaddr, int port, int intttl, int altiface, enum tx_mech transport)
-{
- hdb_handle_t totem_object_handle;
- hdb_handle_t find_handle;
- hdb_handle_t interface_object_handle;
- struct sockaddr_storage if_addr, localhost, mcast_addr;
- char tmp[132];
- char *transportstr;
- int ret = 0;
- const char *tx_mech_to_str[] = {
- [TX_MECH_UDP] = "udp",
- [TX_MECH_UDPB] = "udp",
- [TX_MECH_UDPU] = "udpu",
- [TX_MECH_RDMA] = "iba",
- };
-
- if (num_interfaces >= 2) {
- snprintf(error_reason, sizeof(error_reason) - 1, "Configuration of more than 2 rings is not supported");
- return -1;
- }
-
- /* Check the families match */
- if (address_family(mcast, &mcast_addr, 0) !=
- address_family(ifaddr, &if_addr, mcast_addr.ss_family)) {
- 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 name resolves to localhost, please check /etc/hosts and assign this node a network IP 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 (!altiface) {
- if (objdb_get_string(objdb, totem_object_handle, "transport", &transportstr)) {
- objdb->object_key_create_typed(totem_object_handle, "transport",
- tx_mech_to_str[transport], strlen(tx_mech_to_str[transport]) + 1, OBJDB_VALUETYPE_STRING);
- } else {
- sprintf(error_reason, "Transport should not be specified within <totem .../>, use <cman transport=\"...\" /> instead");
- return -1;
- }
- }
-
- if (objdb->object_create(totem_object_handle, &interface_object_handle,
- "interface", strlen("interface")) == 0) {
- struct sockaddr_in *in = (struct sockaddr_in *)&if_addr;
- struct sockaddr_in6 *in6= (struct sockaddr_in6 *)&if_addr;
- void *addrptr;
-
- sprintf(tmp, "%d", num_interfaces);
- objdb->object_key_create_typed(interface_object_handle, "ringnumber",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- if (if_addr.ss_family == AF_INET)
- addrptr = &in->sin_addr;
- else
- addrptr = &in6->sin6_addr;
- inet_ntop(if_addr.ss_family, addrptr, tmp, sizeof(tmp));
- objdb->object_key_create_typed(interface_object_handle, "bindnetaddr",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- switch (transport) {
- case TX_MECH_UDPB:
- objdb->object_key_create_typed(interface_object_handle, "broadcast",
- "yes", strlen("yes")+1, OBJDB_VALUETYPE_STRING);
- break;
- case TX_MECH_UDP:
- case TX_MECH_RDMA:
- objdb->object_key_create_typed(interface_object_handle, "mcastaddr",
- mcast, strlen(mcast)+1, OBJDB_VALUETYPE_STRING);
- break;
- case TX_MECH_UDPU:
- objdb->object_key_create_typed(interface_object_handle, "mcastaddr",
- mcast, strlen(mcast)+1, OBJDB_VALUETYPE_STRING);
- add_udpu_members(objdb, interface_object_handle);
- break;
- }
-
- sprintf(tmp, "%d", port);
- objdb->object_key_create_typed(interface_object_handle, "mcastport",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- /* paranoia check. corosync already does it */
- if ((intttl < 0) || (intttl > 255)) {
- sprintf(error_reason, "TTL value (%u) out of range (0 - 255)", intttl);
- return -1;
- }
-
- /* add the key to the objdb only if value is not default */
- if (intttl != 1) {
- sprintf(tmp, "%d", intttl);
- objdb->object_key_create_typed(interface_object_handle, "ttl",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
- }
-
- num_interfaces++;
- }
- return ret;
-}
-
-static uint16_t generate_cluster_id(char *name)
-{
- int i;
- int value = 0;
-
- for (i=0; i<strlen(name); i++) {
- value <<= 1;
- value += name[i];
- }
- return value & 0xFFFF;
-}
-
-static char *default_mcast(char *node, int altiface)
-{
- struct addrinfo *ainfo;
- struct addrinfo ahints;
- int ret;
- int family;
- static char addr[132];
- uint16_t clusterid = cluster_id + altiface;
-
- memset(&ahints, 0, sizeof(ahints));
-
- /* Lookup the the nodename address and use it's IP type to
- default a multicast address */
- ret = getaddrinfo(node, NULL, &ahints, &ainfo);
- if (ret) {
- sprintf(error_reason, "Can't determine address family of nodename %s\n", node);
- write_cman_pipe("Can't determine address family of nodename");
- return NULL;
- }
-
- family = ainfo->ai_family;
- freeaddrinfo(ainfo);
-
- if (family == AF_INET) {
- snprintf(addr, sizeof(addr), "239.192.%d.%d", clusterid >> 8, clusterid % 0xFF);
- return strdup(addr);
- }
- if (family == AF_INET6) {
- snprintf(addr, sizeof(addr), "ff15::%x", clusterid);
- return strdup(addr);
- }
-
- return NULL;
-}
-
-static int verify_nodename(struct objdb_iface_ver0 *objdb, char *node)
-{
- 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;
- hdb_handle_t nodes_handle;
- hdb_handle_t find_handle = 0;
- int found = 0;
-
- /* nodename is either from commandline or from uname */
- if (nodelist_byname(objdb, cluster_parent_handle, node))
- return 0;
-
- /* If nodename was from uname, try a domain-less version of it */
- strcpy(nodename2, node);
- dot = strchr(nodename2, '.');
- if (dot) {
- *dot = '\0';
-
- if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
- strcpy(node, 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(node, 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.
- */
- if (getifaddrs(&ifa_list))
- return -1;
-
- for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
- socklen_t salen = 0;
-
- /* Restore this */
- strcpy(nodename2, node);
- sa = ifa->ifa_addr;
- if (!sa)
- continue;
- if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6)
- continue;
-
- if (sa->sa_family == AF_INET)
- salen = sizeof(struct sockaddr_in);
- if (sa->sa_family == AF_INET6)
- salen = sizeof(struct sockaddr_in6);
-
- if (getnameinfo(sa, salen,
- nodename2, sizeof(nodename2),
- NULL, 0, 0) == 0) {
-
- if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
- strcpy(node, nodename2);
- found = 1;
- goto out;
- }
-
- /* Truncate this name and try again */
- dot = strchr(nodename2, '.');
- if (dot) {
- *dot = '\0';
-
- if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
- strcpy(node, nodename2);
- found = 1;
- goto out;
- }
- }
- }
-
- /* See if it's the IP address that's in cluster.conf */
- if (getnameinfo(sa, sizeof(*sa),
- nodename2, sizeof(nodename2),
- NULL, 0, NI_NUMERICHOST))
- continue;
-
- if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
- strcpy(node, nodename2);
- found = 1;
- goto out;
- }
- }
-
- out:
- if (found) {
- freeifaddrs(ifa_list);
- return 0;
- }
-
- /*
- * This section covers the usecase where the nodename specified in cluster.conf
- * is an alias specified in /etc/hosts. For example:
- * <ipaddr> hostname alias1 alias2
- * and <clusternode name="alias2">
- * the above calls use uname and getnameinfo does not return aliases.
- * here we take the name specified in cluster.conf, resolve it to an address
- * and then compare against all known local ip addresses.
- * if we have a match, we found our nodename. In theory this chunk of code
- * could replace all the checks above, but let's avoid any possible regressions
- * and use it as last.
- */
-
- nodes_handle = nodeslist_init(objdb, cluster_parent_handle, &find_handle);
- while (nodes_handle) {
- char *dbnodename = NULL;
- struct addrinfo hints;
- struct addrinfo *result = NULL, *rp = NULL;
-
- if (objdb_get_string(objdb, nodes_handle, "name", &dbnodename)) {
- goto next;
- }
-
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_flags = 0;
- hints.ai_protocol = IPPROTO_UDP;
-
- if (getaddrinfo(dbnodename, NULL, &hints, &result))
- goto next;
-
- for (rp = result; rp != NULL; rp = rp->ai_next) {
- for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
- if (ipaddr_equal((struct sockaddr_storage *)rp->ai_addr,
- (struct sockaddr_storage *)ifa->ifa_addr)) {
- freeaddrinfo(result);
- strncpy(node, dbnodename, sizeof(nodename) - 1);
- found = 1;
- goto out2;
- }
- }
- }
-
- freeaddrinfo(result);
- next:
- nodes_handle = nodeslist_next(objdb, find_handle);
- }
- out2:
- objdb->object_find_destroy(find_handle);
- freeifaddrs(ifa_list);
-
- if (found) {
- return 0;
- }
-
- return -1;
-}
-
-/* Get any environment variable overrides */
-static int get_env_overrides(void)
-{
- 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 alternate port */
- if (getenv("CMAN_IP_ALTPORT")) {
- altportnum = atoi(getenv("CMAN_IP_ALTPORT"));
- }
-
- /* 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_ALTMCAST_ADDR")) {
- altmcast_name = getenv("CMAN_ALTMCAST_ADDR");
- }
-
- if (getenv("CMAN_2NODE")) {
- two_node = 1;
- expected_votes = 1;
- votes = 1;
- }
- if (getenv("CMAN_DEBUG")) {
- debug = atoi(getenv("CMAN_DEBUG"));
- if (debug > 0)
- debug = 1;
- }
- if (getenv("CMAN_NOOPENAIS")) {
- disable_openais = 1;
- }
-
- return 0;
-}
-
-
-static int get_nodename(struct objdb_iface_ver0 *objdb)
-{
- char *nodeid_str = NULL;
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
- hdb_handle_t node_object_handle;
- hdb_handle_t mcast_handle;
- hdb_handle_t alt_object;
- enum tx_mech transport = TX_MECH_UDP;
- char *str;
- int error;
- unsigned int mcast_portnum = DEFAULT_PORT;
- unsigned int altmcast_portnum = DEFAULT_PORT;
- char *altmcast_name_tmp = NULL;
- int broadcast = 0;
-
- 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, uname failed");
- error = -1;
- goto out;
- }
-
- if (strlen(utsname.nodename) >= sizeof(nodename)) {
- sprintf(error_reason, "node name from uname is too long");
- write_cman_pipe("local node name is too long");
- error = -1;
- goto out;
- }
-
- strcpy(nodename, utsname.nodename);
- }
- if (verify_nodename(objdb, nodename)) {
- write_cman_pipe("Cannot find node name in cluster.conf");
- return -1;
- }
-
- }
-
- /* Add <cman> 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)) {
- sprintf(error_reason, "Unable to find cman in config db");
- write_cman_pipe(error_reason);
- return -1;
- }
- objdb->object_find_destroy(find_handle);
-
- /* Check for broadcast */
- if (!objdb_get_string(objdb, object_handle, "broadcast", &str)) {
- if (strcmp(str, "yes") == 0) {
- broadcast = 1;
- transport = TX_MECH_UDPB;
- }
- }
-
- /* Check for transport */
- if (!objdb_get_string(objdb, object_handle, "transport", &str)) {
- if ((broadcast) && (strcmp(str, "udpb"))) {
- sprintf(error_reason, "Transport and broadcast option are mutually exclusive");
- write_cman_pipe(error_reason);
- return -1;
- }
- if (strcmp(str, "udp") == 0) {
- transport = TX_MECH_UDP;
- } else if (strcmp(str, "udpb") == 0) {
- broadcast = 1;
- transport = TX_MECH_UDPB;
- } else if (strcmp(str, "udpu") == 0) {
- transport = TX_MECH_UDPU;
- } else if (strcmp(str, "rdma") == 0) {
- transport = TX_MECH_RDMA;
- } else {
- sprintf(error_reason, "Transport option value can be one of udp, udpb, udpu, rdma");
- write_cman_pipe(error_reason);
- return -1;
- }
- }
-
- if (broadcast) {
- mcast_name = strdup("255.255.255.255");
- if (!mcast_name) {
- sprintf(error_reason, "Unable to set mcast_name");
- write_cman_pipe(error_reason);
- return -1;
- }
- altmcast_name = strdup("255.255.255.255");
- if (!altmcast_name) {
- sprintf(error_reason, "Unable to set altmcast_name");
- write_cman_pipe(error_reason);
- return -1;
- }
- altmcast_portnum = DEFAULT_PORT + 2;
- }
-
- objdb->object_find_create(object_handle, "multicast", strlen("multicast"), &find_handle);
- if (objdb->object_find_next(find_handle, &mcast_handle) == 0) {
- if (!mcast_name)
- objdb_get_string(objdb, mcast_handle, "addr", &mcast_name);
- objdb_get_int(objdb, mcast_handle, "ttl", &ttl, ttl);
- objdb_get_int(objdb, mcast_handle, "port", &mcast_portnum, DEFAULT_PORT);
- }
- objdb->object_find_destroy(find_handle);
-
- if (!mcast_name) {
- mcast_name = default_mcast(nodename, PRIMARY_IFACE);
- }
-
- if (!mcast_name) {
- sprintf(error_reason, "Unable to set mcast_name");
- write_cman_pipe(error_reason);
- return -1;
- }
-
- objdb->object_find_create(object_handle, "altmulticast", strlen("altmulticast"), &find_handle);
- if (objdb->object_find_next(find_handle, &mcast_handle) == 0) {
- objdb_get_string(objdb, mcast_handle, "addr", &altmcast_name_tmp);
- objdb_get_int(objdb, mcast_handle, "ttl", &altttl, ttl);
- if (!broadcast) {
- objdb_get_int(objdb, mcast_handle, "port", &altmcast_portnum, DEFAULT_PORT);
- } else {
- objdb_get_int(objdb, mcast_handle, "port", &altmcast_portnum, DEFAULT_PORT + 2);
- }
- }
- objdb->object_find_destroy(find_handle);
-
- /* 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_typed(object_handle, "nodename",
- nodename, strlen(nodename)+1, OBJDB_VALUETYPE_STRING);
-
- nodeid = atoi(nodeid_str);
- error = 0;
-
- /* optional port */
- if (!portnum) {
- objdb_get_int(objdb, object_handle, "port", &portnum, mcast_portnum);
- }
-
- if (add_ifaddr(objdb, mcast_name, nodename, portnum, ttl,
- PRIMARY_IFACE, transport)) {
- write_cman_pipe(error_reason);
- 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) {
- char *node;
-
- if (objdb_get_string(objdb, alt_object, "name", &node)) {
- continue;
- }
-
- objdb_get_int(objdb, alt_object, "port", &altportnum, altmcast_portnum);
-
- objdb_get_int(objdb, alt_object, "ttl", &altttl, altttl);
-
- if (!altmcast_name) {
- if (objdb_get_string(objdb, alt_object, "mcast", &altmcast_name)) {
- if (altmcast_name_tmp) {
- altmcast_name = altmcast_name_tmp;
- } else {
- altmcast_name = default_mcast(nodename, ALT_IFACE);
- }
- }
- }
-
- if (!altmcast_name) {
- sprintf(error_reason, "Unable to determine alternate multicast name");
- write_cman_pipe(error_reason);
- return -1;
- }
-
- if (!strcmp(altmcast_name, mcast_name) &&
- ((altportnum == portnum) || (altportnum == portnum - 1) || (portnum == altportnum - 1))) {
- sprintf(error_reason, "Alternate communication channel (mcast: %s ports: %d,%d) cannot use\n"
- "same address and ports of primary channel (mcast: %s ports: %d,%d)",
- altmcast_name, altportnum, altportnum - 1,
- mcast_name, portnum, portnum - 1);
- write_cman_pipe(error_reason);
- return -1;
- }
-
- if (add_ifaddr(objdb, altmcast_name, node, altportnum, altttl,
- ALT_IFACE, transport)) {
- write_cman_pipe(error_reason);
- return -1;
- }
-
- num_nodenames++;
- }
- objdb->object_find_destroy(find_handle);
-
-out:
- return error;
-}
-
-static void add_logging_overrides(struct objdb_iface_ver0 *objdb)
-{
- char *logstr;
- char *logfacility;
- char *loglevel;
- hdb_handle_t object_handle;
- hdb_handle_t 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);
- loglevel = priority_name_get(SYSLOGLEVEL);
-
- /* enable timestamps on logging */
- if (objdb_get_string(objdb, object_handle, "timestamp", &logstr)) {
- objdb->object_key_create_typed(object_handle, "timestamp",
- "on", strlen("on")+1, OBJDB_VALUETYPE_STRING);
- }
-
- /* configure logfile */
- if (objdb_get_string(objdb, object_handle, "to_logfile", &logstr)) {
- objdb->object_key_create_typed(object_handle, "to_logfile",
- "yes", strlen("yes")+1, OBJDB_VALUETYPE_STRING);
- }
-
- if (objdb_get_string(objdb, object_handle, "logfile", &logstr)) {
- objdb->object_key_create_typed(object_handle, "logfile",
- LOGDIR "/corosync.log", strlen(LOGDIR "/corosync.log")+1, OBJDB_VALUETYPE_STRING);
- }
-
- if (objdb_get_string(objdb, object_handle, "logfile_priority", &logstr)) {
- objdb->object_key_create_typed(object_handle, "logfile_priority",
- loglevel, strlen(loglevel)+1, OBJDB_VALUETYPE_STRING);
- }
-
- /* syslog */
- if (objdb_get_string(objdb, object_handle, "to_syslog", &logstr)) {
- objdb->object_key_create_typed(object_handle, "to_syslog",
- "yes", strlen("yes")+1, OBJDB_VALUETYPE_STRING);
- }
-
- if (objdb_get_string(objdb, object_handle, "syslog_facility", &logstr)) {
- objdb->object_key_create_typed(object_handle, "syslog_facility",
- logfacility, strlen(logfacility)+1, OBJDB_VALUETYPE_STRING);
- }
-
- if (objdb_get_string(objdb, object_handle, "syslog_priority", &logstr)) {
- objdb->object_key_create_typed(object_handle, "syslog_priority",
- loglevel, strlen(loglevel)+1, OBJDB_VALUETYPE_STRING);
- }
-
- if (!debug) {
- hdb_handle_t logger_object_handle;
-
- if (!objdb_get_string(objdb, object_handle, "debug", &logstr)) {
- if (!strncmp(logstr, "on", 2)) {
- debug=1;
- }
- }
-
- logger_object_handle = find_cman_logger(objdb, object_handle);
- if (logger_object_handle > -1) {
- if (!objdb_get_string(objdb, logger_object_handle, "debug", &logstr)) {
- if (!strncmp(logstr, "on", 2)) {
- debug=1;
- }
- if (!strncmp(logstr, "off", 3)) {
- debug=0;
- }
- }
- }
- }
-
- if (debug) {
- objdb->object_key_create_typed(object_handle, "to_stderr",
- "yes", strlen("yes")+1, OBJDB_VALUETYPE_STRING);
- }
-
-
-}
-
-static int count_configured_nodes(struct objdb_iface_ver0 *objdb)
-{
- hdb_handle_t find_handle = 0;
- hdb_handle_t nodes_handle;
- int count = 0;
-
- nodes_handle = nodeslist_init(objdb, cluster_parent_handle, &find_handle);
- while (nodes_handle) {
- count++;
- nodes_handle = nodeslist_next(objdb, find_handle);
- }
- objdb->object_find_destroy(find_handle);
-
- return count;
-}
-
-/* These are basically cman overrides to the totem config bits */
-static void add_cman_overrides(struct objdb_iface_ver0 *objdb)
-{
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
- int node_count = 0;
- 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_typed(object_handle, "version",
- "2", 2, OBJDB_VALUETYPE_STRING);
-
- sprintf(tmp, "%d", nodeid);
- objdb->object_key_create_typed(object_handle, "nodeid",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- objdb->object_key_create_typed(object_handle, "vsftype",
- "none", strlen("none")+1, OBJDB_VALUETYPE_STRING);
-
- /* 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)) {
- snprintf(tmp, sizeof(tmp), "%d", DEFAULT_TOKEN_TIMEOUT);
- objdb->object_key_create_typed(object_handle, "token",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
- }
-
- /* Extend join timeouts per bz#214290 */
- if (objdb_get_string(objdb, object_handle, "join", &value)) {
- objdb->object_key_create_typed(object_handle, "join",
- "60", strlen("60")+1, OBJDB_VALUETYPE_STRING);
- }
- /* Extend fail_to_recv_const, see bz#587078 */
- if (objdb_get_string(objdb, object_handle, "fail_recv_const", &value)) {
- objdb->object_key_create_typed(object_handle, "fail_recv_const",
- "2500", strlen("2500")+1, OBJDB_VALUETYPE_STRING);
- }
-
- /*
- * consensus should be:
- * 2 nodes - 200 ms <= consensus = token * 0.2 <= 2000
- * > 2 nodes - consensus = token + 2000
- *
- * autoconfig clusters will work as > 2 nodes
- *
- * See 611391#c19
- */
-
- node_count=count_configured_nodes(objdb);
-
- /* if we are running in autoconfig or we can't count the nodes, then play safe */
- if ((getenv("CMAN_NOCONFIG")) || (node_count == 0))
- node_count=3;
-
- if (objdb_get_string(objdb, object_handle, "consensus", &value)) {
- unsigned int token=0;
- unsigned int consensus;
- char calc_consensus[32];
-
- objdb_get_int(objdb, object_handle, "token", &token, DEFAULT_TOKEN_TIMEOUT);
-
- if (node_count > 2) {
- consensus = (float)token+2000;
- } else {
- consensus = (float)token*0.2;
- if (consensus < 200)
- consensus = 200;
- if (consensus > 2000)
- consensus = 2000;
- }
-
- snprintf(calc_consensus, sizeof(calc_consensus), "%d", consensus);
- objdb->object_key_create_typed(object_handle, "consensus",
- calc_consensus, strlen(calc_consensus)+1, OBJDB_VALUETYPE_STRING);
- }
-
- /* Set RRP mode appropriately */
- if (objdb_get_string(objdb, object_handle, "rrp_mode", &value)) {
- if (num_interfaces > 1) {
- objdb->object_key_create_typed(object_handle, "rrp_mode",
- "passive", strlen("passive")+1, OBJDB_VALUETYPE_STRING);
- }
- else {
- objdb->object_key_create_typed(object_handle, "rrp_mode",
- "none", strlen("none")+1, OBJDB_VALUETYPE_STRING);
- }
- }
-
- if (objdb_get_string(objdb, object_handle, "rrp_problem_count_threshold", &value)) {
- if (num_interfaces > 1) {
- objdb->object_key_create_typed(object_handle, "rrp_problem_count_threshold",
- "3", 2, OBJDB_VALUETYPE_STRING);
- }
- }
-
- if (objdb_get_string(objdb, object_handle, "secauth", &value)) {
- sprintf(tmp, "%d", 1);
- objdb->object_key_create_typed(object_handle, "secauth",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
- }
-
- /* optional security key filename */
- if (!key_filename) {
- objdb_get_string(objdb, object_handle, "keyfile", &key_filename);
- }
- else {
- objdb->object_key_create_typed(object_handle, "keyfile",
- key_filename, strlen(key_filename)+1, OBJDB_VALUETYPE_STRING);
- }
- 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_typed(object_handle, "key",
- tmp, keylen, OBJDB_VALUETYPE_STRING);
- }
- }
- objdb->object_find_destroy(find_handle);
-
- add_logging_overrides(objdb);
-
- /* Make sure we allow connections from user/group "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_typed(object_handle, "user",
- "ais", strlen("ais") + 1, OBJDB_VALUETYPE_STRING);
- objdb->object_key_create_typed(object_handle, "group",
- "ais", strlen("ais") + 1, OBJDB_VALUETYPE_STRING);
-
- 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_typed(object_handle, "cluster_id",
- str, strlen(str) + 1, OBJDB_VALUETYPE_STRING);
-
- if (two_node) {
- sprintf(str, "%d", 1);
- objdb->object_key_create_typed(object_handle, "two_node",
- str, strlen(str) + 1, OBJDB_VALUETYPE_STRING);
- }
- }
- objdb->object_find_destroy(find_handle);
-
- /* Load the quorum service */
- objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
- "service", strlen("service"));
- objdb->object_key_create_typed(object_handle, "name",
- "corosync_quorum", strlen("corosync_quorum") + 1, OBJDB_VALUETYPE_STRING);
- objdb->object_key_create_typed(object_handle, "ver",
- "0", 2, OBJDB_VALUETYPE_STRING);
-
- /* Make sure we load our alter-ego - the main cman module */
- add_service(objdb, "corosync_cman");
-
- /* Define cman as the quorum provider for corosync */
- objdb->object_find_create(OBJECT_PARENT_HANDLE, "quorum", strlen("quorum"), &find_handle);
- if (objdb->object_find_next(find_handle, &object_handle) != 0) {
- objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
- "quorum", strlen("quorum"));
- }
- objdb->object_find_destroy(find_handle);
-
- objdb->object_key_create_typed(object_handle, "provider",
- "quorum_cman", strlen("quorum_cman") + 1, OBJDB_VALUETYPE_STRING);
-
- /* Load openais services we need (unless told not to) */
- if (!disable_openais) {
- add_service(objdb, "openais_ckpt");
- }
-
-}
-
-/* If ccs is not available then use some defaults */
-static int set_noccs_defaults(struct objdb_iface_ver0 *objdb)
-{
- char tmp[255];
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
-
- /* Enforce key */
- key_filename = strdup(NOCCS_KEY_FILENAME);
- if (!key_filename) {
- sprintf(error_reason, "cannot allocate memory for key file name");
- write_cman_pipe("cannot allocate memory for key file name");
- return -1;
- }
-
- if (!cluster_name)
- cluster_name = strdup(DEFAULT_CLUSTER_NAME);
-
- if (!cluster_name) {
- sprintf(error_reason, "cannot allocate memory for cluster_name");
- write_cman_pipe("cannot allocate memory for cluster_name");
- return -1;
- }
-
- if (!cluster_id) {
- if (use_hashed_cluster_id)
- cluster_id = fnv_hash(cluster_name);
- else
- cluster_id = generate_cluster_id(cluster_name);
-
- sprintf(error_reason, "Generated cluster id for '%s' is %d\n", cluster_name, cluster_id);
- }
-
- 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, PRIMARY_IFACE);
- }
-
- /* 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 <clusternode> 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_typed(object_handle, "name",
- nodename, strlen(nodename)+1, OBJDB_VALUETYPE_STRING);
-
- sprintf(tmp, "%d", votes);
- objdb->object_key_create_typed(object_handle, "votes",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- sprintf(tmp, "%d", nodeid);
- objdb->object_key_create_typed(object_handle, "nodeid",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- /* Write the default cluster name & ID in here too */
- objdb->object_key_create_typed(cluster_parent_handle, "name",
- cluster_name, strlen(cluster_name)+1, OBJDB_VALUETYPE_STRING);
-
-
- 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_typed(object_handle, "cluster_id",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- sprintf(tmp, "%d", expected_votes);
- objdb->object_key_create_typed(object_handle, "expected_votes",
- tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
-
- objdb->object_find_destroy(find_handle);
- return 0;
-}
-
-/* Move an object/key tree */
-static int copy_config_tree(struct objdb_iface_ver0 *objdb, hdb_handle_t source_object, hdb_handle_t target_parent_object, int always_create)
-{
- hdb_handle_t object_handle;
- hdb_handle_t new_object;
- hdb_handle_t find_handle;
- char object_name[1024];
- size_t object_name_len;
- void *key_name;
- size_t key_name_len;
- void *key_value;
- size_t 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, &new_object))
- 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_typed(new_object, key_name,
- key_value, key_value_len, OBJDB_VALUETYPE_STRING);
- }
-
- /* 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 %ud: %d\n", (unsigned int)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, always_create);
- }
- 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, const char *name, int always_create)
-{
- hdb_handle_t find_handle;
- hdb_handle_t 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)
-{
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
- char *use_hash;
-
- objdb_get_string(objdb, cluster_parent_handle, "name", &cluster_name);
- if (!cluster_name) {
- sprintf(error_reason, "Unable to determine cluster name.\n");
- write_cman_pipe("Unable to determine cluster name.\n");
- return -1;
- }
-
- if (strlen(cluster_name) > 15) {
- sprintf(error_reason, "%s\n", "Invalid cluster name. It must be 15 characters or fewer\n");
- write_cman_pipe("Invalid cluster name. It must be 15 characters or fewer\n");
- return -1;
- }
-
- /* Get the <cman> bits that override <totem> bits */
- objdb->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle);
- if (objdb->object_find_next(find_handle, &object_handle) == 0) {
- if (!key_filename)
- objdb_get_string(objdb, object_handle, "keyfile", &key_filename);
-
- objdb_get_string(objdb, object_handle, "hash_cluster_id", &use_hash);
- if (use_hash) {
- if (strncasecmp(use_hash, "yes", 3) == 0 || strncasecmp(use_hash, "on", 2) == 0)
- use_hashed_cluster_id = 1;
- }
-
- if (!cluster_id)
- objdb_get_int(objdb, object_handle, "cluster_id", &cluster_id, 0);
-
- if (!cluster_id) {
- if (use_hashed_cluster_id)
- cluster_id = fnv_hash(cluster_name);
- else
- cluster_id = generate_cluster_id(cluster_name);
-
- sprintf(error_reason, "Generated cluster id for '%s' is %d\n", cluster_name, cluster_id);
- }
- }
- objdb->object_find_destroy(find_handle);
- return 0;
-}
-
-static int cmanpre_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, const char **error_string)
-{
- int ret = -1;
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
- hdb_handle_t cluster_parent_handle_new;
- unsigned int config_version = 0, config_version_new = 0;
- char *config_value = NULL;
- char str[255];
-
- /* 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);
- objdb->object_find_next(find_handle, &cluster_parent_handle_new);
- objdb->object_find_destroy(find_handle);
- if (!cluster_parent_handle) {
- sprintf (error_reason, "%s", "Cannot find old /cluster/ key in configuration\n");
- goto err;
- }
- if (!cluster_parent_handle_new) {
- sprintf (error_reason, "%s", "Cannot find new /cluster/ key in configuration\n");
- goto err;
- }
-
- if (!objdb->object_key_get(cluster_parent_handle, "config_version", strlen("config_version"), (void *)&config_value, NULL)) {
- if (config_value) {
- config_version = atoi(config_value);
- } else {
- /* it should never ever happen.. */
- sprintf (error_reason, "%s", "Cannot find old /cluster/config_version key in configuration\n");
- goto err;
- }
- }
-
- config_value = NULL;
-
- if (!objdb->object_key_get(cluster_parent_handle_new, "config_version", strlen("config_version"), (void *)&config_value, NULL)) {
- if (config_value) {
- config_version_new = atoi(config_value);
- } else {
- objdb->object_destroy(cluster_parent_handle_new);
- sprintf (error_reason, "%s", "Cannot find new /cluster/config_version key in configuration\n");
- goto err;
- }
- }
-
- if (config_version_new <= config_version) {
- objdb->object_destroy(cluster_parent_handle_new);
- sprintf (error_reason, "%s", "New configuration version has to be newer than current running configuration\n");
- goto err;
- }
-
- /* destroy the old one */
- objdb->object_destroy(cluster_parent_handle);
-
- /*
- * create cluster.cman in the new config if it doesn't exist
- */
- objdb->object_find_create(cluster_parent_handle_new, "cman", strlen("cman"), &find_handle);
- if (objdb->object_find_next(find_handle, &object_handle)) {
- objdb->object_create(cluster_parent_handle_new, &object_handle,
- "cman", strlen("cman"));
- }
- objdb->object_find_destroy(find_handle);
-
- /*
- * write cluster_id/two_node/nodename
- */
- snprintf(str, sizeof(str) - 1, "%d", cluster_id);
- objdb->object_key_create_typed(object_handle, "cluster_id",
- str, strlen(str) + 1, OBJDB_VALUETYPE_STRING);
-
- if (two_node) {
- snprintf(str, sizeof(str) - 1, "%d", 1);
- objdb->object_key_create_typed(object_handle, "two_node",
- str, strlen(str) + 1, OBJDB_VALUETYPE_STRING);
- }
-
- objdb->object_key_create_typed(object_handle, "nodename",
- nodename, strlen(nodename)+1, OBJDB_VALUETYPE_STRING);
-
- /* 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);
- ret = objdb->object_find_next(find_handle, &object_handle);
- objdb->object_find_destroy(find_handle);
- if (!ret) {
- objdb->object_destroy(object_handle);
- }
-
- /* copy /cluster/logging to /logging */
- ret = copy_tree_to_root(objdb, "logging", 1);
-
- /* Note: we do NOT delete /totem as corosync stores other things in there that
- it needs! */
-
- /* copy /cluster/totem to /totem */
- ret = copy_tree_to_root(objdb, "totem", 0);
-
- add_logging_overrides(objdb);
-
- return 0;
-
-err:
- *error_string = error_reason;
- return ret;
-}
-
-
-static hdb_handle_t find_or_create_object(struct objdb_iface_ver0 *objdb, const char *name, hdb_handle_t parent_handle)
-{
- hdb_handle_t find_handle;
- hdb_handle_t ret_handle = 0;
-
- objdb->object_find_create(parent_handle, name, strlen(name), &find_handle);
- objdb->object_find_next(find_handle, &ret_handle);
- objdb->object_find_destroy(find_handle);
-
- if (!ret_handle) {
- objdb->object_create(parent_handle, &ret_handle, name, strlen(name));
- }
-
- return ret_handle;
-}
-
-static const char *groupd_compat="groupd_compat";
-static const char *clvmd_interface="interface";
-static const char *cman_disallowed="disallowed";
-static const char *totem_crypto="crypto_accept";
-static const char *plock_ownership="plock_ownership";
-
-/*
- * Flags to set:
- * - groupd:
- * - clvmd
- * - disallowed (on)
- * - rgmanager
- */
-static void setup_old_compat(struct objdb_iface_ver0 *objdb, hdb_handle_t cluster_handle)
-{
- hdb_handle_t groupd_handle;
- hdb_handle_t clvmd_handle;
- hdb_handle_t cman_handle;
- hdb_handle_t totem_handle;
- hdb_handle_t gfs_handle;
- char *value;
-
- use_hashed_cluster_id = 0;
-
- /* Set groupd to backwards compatibility mode */
- groupd_handle = find_or_create_object(objdb, "group", cluster_handle);
- if (objdb->object_key_get(groupd_handle, groupd_compat, strlen(groupd_compat),
- (void *)&value, NULL) ||
- !value) {
- objdb->object_key_create_typed(groupd_handle, groupd_compat,
- "1", 2, OBJDB_VALUETYPE_STRING);
- }
-
- /* Make clvmd use cman */
- clvmd_handle = find_or_create_object(objdb, "clvmd", cluster_handle);
- if (objdb->object_key_get(clvmd_handle, clvmd_interface, strlen(clvmd_interface),
- (void *)&value, NULL) ||
- !value) {
- objdb->object_key_create_typed(clvmd_handle, clvmd_interface,
- "cman", 5, OBJDB_VALUETYPE_STRING);
- }
-
- /* Make cman use disallowed mode */
- cman_handle = find_or_create_object(objdb, "cman", cluster_handle);
- if (objdb->object_key_get(cman_handle, cman_disallowed, strlen(cman_disallowed),
- (void *)&value, NULL) ||
- !value) {
- objdb->object_key_create_typed(cman_handle, cman_disallowed,
- "1", 2, OBJDB_VALUETYPE_STRING);
- }
-
- /* Make totem use the old communications method */
- totem_handle = find_or_create_object(objdb, "totem", OBJECT_PARENT_HANDLE);
- if (objdb->object_key_get(totem_handle, totem_crypto, strlen(totem_crypto),
- (void *)&value, NULL) ||
- !value) {
- objdb->object_key_create_typed(totem_handle, totem_crypto,
- "old", 4, OBJDB_VALUETYPE_STRING);
- }
-
- /* Disable plock ownership */
- gfs_handle = find_or_create_object(objdb, "gfs_controld", OBJECT_PARENT_HANDLE);
- if (objdb->object_key_get(gfs_handle, plock_ownership, strlen(plock_ownership),
- (void *)&value, NULL) ||
- !value) {
- objdb->object_key_create_typed(gfs_handle, plock_ownership,
- "0", 2, OBJDB_VALUETYPE_STRING);
- }
-
- /* Load a full set of openais services */
- if (!disable_openais) {
- add_service(objdb, "openais_clm");
- add_service(objdb, "openais_evt");
- add_service(objdb, "openais_msg");
- add_service(objdb, "openais_lck");
- add_service(objdb, "openais_tmr");
- /* ckpt is added as part of normal startup */
- }
-}
-
-static int cmanpre_readconfig(struct objdb_iface_ver0 *objdb, const char **error_string)
-{
- int ret = 0;
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
- char *str;
-
- 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", 1);
- 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);
- ret = copy_tree_to_root(objdb, "uidgid", 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);
-
- /* Set up STABLE2/RHEL5 compatibility modes */
- objdb_get_string(objdb, object_handle, "upgrading", &str);
- if (str && (strcasecmp(str, "on")==0 || strcasecmp(str, "yes")==0)) {
- setup_old_compat(objdb, cluster_parent_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_typed(object_handle, "next_handle",
- &next_handle, sizeof(uint32_t), OBJDB_VALUETYPE_UINT32);
- }
- 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;
-
-
- /* nullify stderr, because cman_tool tells corosync not to.
- This helps pass error messages back to the command-line, when
- debug is enabled.
- */
- if (!debug) {
- int tmpfd;
- tmpfd = open("/dev/null", O_RDWR);
- if (tmpfd > -1 && tmpfd != STDERR_FILENO) {
- dup2(tmpfd, STDERR_FILENO);
- close(tmpfd);
- }
-
- }
- return ret;
-}
-
-/* Write an error message down the CMAN startup pipe so
- that cman_tool can display it */
-int write_cman_pipe(const 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 1ec7eca..0000000
--- a/cman/daemon/cman.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* General cman bits */
-extern int write_cman_pipe(const char *message);
-extern void close_cman_pipe(void);
-extern int our_nodeid(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_TOKEN_TIMEOUT 10000
-#define DEFAULT_QUORUMDEV_POLL 10000
-#define DEFAULT_SHUTDOWN_TIMEOUT 5000
-#define DEFAULT_CCSD_POLL 1000
-#define DEFAULT_DISALLOWED 0
-#define DEFAULT_STARTUP_CONFIG_TIMEOUT 0
diff --git a/cman/daemon/cmanconfig.c b/cman/daemon/cmanconfig.c
deleted file mode 100644
index 16ef65f..0000000
--- a/cman/daemon/cmanconfig.c
+++ /dev/null
@@ -1,304 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <netinet/in.h>
-#include <syslog.h>
-#include <string.h>
-#include <errno.h>
-#include <netdb.h>
-
-#include <corosync/corotypes.h>
-#include <corosync/coroipc_types.h>
-#include <corosync/coroipcc.h>
-#include <corosync/corodefs.h>
-#include <corosync/mar_gen.h>
-#include <corosync/engine/coroapi.h>
-#include <corosync/engine/logsys.h>
-
-#include "list.h"
-#include "cnxman-socket.h"
-#include "cnxman-private.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);
-
-/* 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;
- unsigned int total_votes = 0;
- hdb_handle_t object_handle;
- hdb_handle_t nodes_handle;
- hdb_handle_t find_handle;
- char *nodename;
- int this_nodeid;
- hdb_handle_t 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 *)&this_nodeid, 0);
- if (check_nodeids && this_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;
- }
-
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: Got node %s from ccs (id=%d, votes=%d)\n", nodename, this_nodeid, votes);
- add_ccs_node(nodename, this_nodeid, votes, expected);
- nodes_handle = nodeslist_next(corosync, find_handle);
- total_votes += votes;
- } while (nodes_handle);
- corosync->object_find_destroy(find_handle);
-
- if (!expected)
- expected = total_votes;
-
- 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;
- hdb_handle_t object_handle;
- hdb_handle_t node_object;
- hdb_handle_t nodes_handle;
- hdb_handle_t find_handle;
- hdb_handle_t 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 nodevotes;
-
- node_count++;
-
- objdb_get_int(corosync, nodes_handle, "votes", (unsigned int *)&nodevotes, 1);
- if (nodevotes < 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 += nodevotes;
- 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 e6bb5dd..0000000
--- a/cman/daemon/cnxman-socket.h
+++ /dev/null
@@ -1,289 +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_UPDATE_QUORUMDEV 0x800000b8
-#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_GETNODE_EXTRA 0x000000c5
-
-#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 */
-#define CLUSTER_PORT_QDISKD 178 /* Quorum disk 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
-#define CMAN_EXTRA_FLAG_DISALLOWED_ENABLED 32
-
-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
- <n>*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;
-};
-
-struct cl_node_extra
-{
- int nodeid;
- int state;
- int votes;
- int expected_votes;
- int leave_reason;
-};
-
-
-/* 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 f8f8114..0000000
--- a/cman/daemon/commands.c
+++ /dev/null
@@ -1,2469 +0,0 @@
-#include <getopt.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <syslog.h>
-#include <string.h>
-#include <time.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/utsname.h>
-#include <sys/un.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/signal.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <sys/errno.h>
-#include <dlfcn.h>
-
-#include <corosync/corotypes.h>
-#include <corosync/coroipc_types.h>
-#include <corosync/coroipcc.h>
-#include <corosync/corodefs.h>
-#include <corosync/mar_gen.h>
-#include <corosync/engine/coroapi.h>
-#include <corosync/engine/logsys.h>
-#include "list.h"
-#include "cman.h"
-#include "cnxman-socket.h"
-#include "cnxman-private.h"
-#include "daemon.h"
-#include "barrier.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);
-
-/* 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;
- unsigned int enable_disallowed=DEFAULT_DISALLOWED;
- unsigned int startup_config_timeout=DEFAULT_STARTUP_CONFIG_TIMEOUT;
-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 int local_first_trans;
-
-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 int ccsd_timer_active = 0;
-
-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 const char *killmsg_reason(int reason);
-static void ccsd_timer_fn(void *arg);
-static int reload_config(int new_version, int should_broadcast);
-
-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<<bit;
-}
-
-static void clear_port_bit(struct cluster_node *node, uint8_t port)
-{
- int byte;
- int bit;
-
- byte = port/8;
- bit = port%8;
-
- node->port_bits[byte] &= ~(1<<bit);
-}
-
-static int get_port_bit(struct cluster_node *node, uint8_t port)
-{
- int byte;
- int bit;
-
- byte = port/8;
- bit = port%8;
-
- return ((node->port_bits[byte] & (1<<bit)) != 0);
-}
-
-static int have_disallowed(void)
-{
- struct cluster_node *node;
-
- if (!enable_disallowed)
- return 0;
-
- list_iterate_items(node, &cluster_members_list) {
- if (node->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;
- unsigned int nodelist[PROCESSOR_COUNT_MAX];
- int nodecount = 0;
- struct cluster_node *node = NULL;
- struct list *tmp;
-
- 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) {
-
- 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;
-
- /* Inform corosync subsystems */
- list_iterate(tmp, &cluster_members_list) {
- node = list_item(tmp, struct cluster_node);
- if (node->state == NODESTATE_MEMBER) {
- nodelist[nodecount++] = node->node_id;
- }
- }
-
- corosync_set_quorum(nodelist, nodecount, quorate, &cman_ring_id);
-}
-
-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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- return reload_config(version->config, 1);
-}
-
-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;
- hdb_handle_t totem_object_handle;
- hdb_handle_t object_handle;
- hdb_handle_t totem_find_handle;
- hdb_handle_t 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));
- if (*retbuf == NULL)
- return -ENOMEM;
- outbuf = *retbuf + offset;
- einfo = (struct cl_extra_info *)outbuf;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
- if (enable_disallowed)
- einfo->flags |= CMAN_EXTRA_FLAG_DISALLOWED_ENABLED;
-
- 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);
- /* If this fails, it must be using broadcast*/
- if (!mcast)
- mcast = (char*)"255.255.255.255";
- 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; i<num_interfaces; i++) {
- ss = (struct sockaddr_storage *)ptr;
- totemip_to_sockaddr(&node_ifs[i], 0, ss, &addrlen);
- ptr += sizeof(struct sockaddr_storage);
- }
-
- *retlen = ptr - outbuf;
- return 0;
-}
-
-static int do_cmd_get_all_members(char *cmdbuf, char **retbuf, int retsize, int *retlen, int offset)
-{
- struct cluster_node *node;
- struct cl_cluster_node *user_node;
- struct list *nodelist;
- char *outbuf = *retbuf + offset;
- int num_nodes = 0;
- int total_nodes = 0;
- int highest_node;
-
- if (!we_are_a_cluster_member)
- return -ENOENT;
-
- highest_node = get_highest_nodeid();
-
- /* Count nodes */
- list_iterate(nodelist, &cluster_members_list) {
- total_nodes++;
- }
- if (quorum_device)
- total_nodes++;
-
- /* if retsize == 0 then don't return node information */
- if (retsize) {
- /* If there is not enough space in the default buffer, allocate some more. */
- if ((retsize / sizeof(struct cl_cluster_node)) < total_nodes) {
- *retbuf = malloc(sizeof(struct cl_cluster_node) * total_nodes + offset);
- if (!*retbuf)
- return -ENOMEM;
- outbuf = *retbuf + offset;
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: get_all_members: allocated new buffer (retsize=%d)\n", retsize);
- }
- }
- user_node = (struct cl_cluster_node *)outbuf;
-
- /* This returns the full list */
- list_iterate_items(node, &cluster_members_list) {
- if (retsize) {
- copy_to_usernode(node, user_node);
-
- user_node++;
- num_nodes++;
- }
- }
-
- if (quorum_device) {
- copy_to_usernode(quorum_device, user_node);
- user_node++;
- num_nodes++;
- }
-
- *retlen = sizeof(struct cl_cluster_node) * num_nodes;
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: get_all_members: retlen = %d\n", *retlen);
- return num_nodes;
-}
-
-
-static int do_cmd_get_cluster(char *cmdbuf, char *retbuf, int *retlen)
-{
- struct cl_cluster_info *info = (struct cl_cluster_info *)retbuf;
-
- info->number = 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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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_get_node_extra(char *cmdbuf, char *retbuf, int *retlen)
-{
- struct cluster_node *node;
- struct cl_node_extra *r_node = (struct cl_node_extra *)retbuf;
- int nodeid;
-
- if (!we_are_a_cluster_member)
- return -ENOENT;
-
- memcpy(&nodeid, cmdbuf, sizeof(int));
-
- if (nodeid == CLUSTER_GETNODE_QUORUMDEV) {
- return -EINVAL;
- }
- node = find_node_by_nodeid(nodeid);
- if (nodeid == 0)
- node = us;
- if (!node)
- return -EINVAL;
-
- r_node->votes = node->votes;
- r_node->expected_votes = node->expected_votes;
- r_node->state = node->state;
- r_node->leave_reason = node->leave_reason;
- r_node->nodeid = nodeid;
-
- *retlen = sizeof(struct cl_node_extra);
-
- 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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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)) {
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: islistening, no data for node %d, sending PORTENQ\n", nodeid);
- send_port_enquire(rem_node->node_id);
-
- /* Admit our ignorance */
- return -EBUSY;
- }
- else {
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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));
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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) {
- cman_finish();
- 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(void)
-{
- int reply;
- int leaveflags = CLUSTER_LEAVEFLAG_DOWN;
-
- /* All replies safely gathered in ? */
- if (shutdown_yes + shutdown_no >= shutdown_expected) {
-
- if (shutdown_timer)
- 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;
- }
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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)
-{
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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 || quit_threads)
- 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) {
- shutdown_timer = 0;
- check_shutdown_status();
- }
- 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;
- }
- return 0;
-}
-
-static void free_quorum_device(void)
-{
- if (!quorum_device)
- return;
-
- if (quorum_device->name)
- free(quorum_device->name);
-
- free(quorum_device);
-
- quorum_device = NULL;
-}
-
-static void quorum_device_update_votes(int votes)
-{
- int oldvotes;
-
- /* Update votes even if it existed before */
- oldvotes = quorum_device->votes;
- quorum_device->votes = votes;
-
- /* If it is a member and votes changed, recalculate quorum */
- if (quorum_device->state == NODESTATE_MEMBER &&
- oldvotes != votes) {
- recalculate_quorum(1, 0);
- }
-}
-
-static int do_cmd_register_quorum_device(char *cmdbuf, int *retlen)
-{
- int votes;
- char *name = cmdbuf+sizeof(int);
-
- if (!ais_running) {
- log_printf(LOG_ERR, "unable to register quorum device: corosync is not running\n");
- return -ENOTCONN;
- }
-
- if (!we_are_a_cluster_member) {
- log_printf(LOG_ERR, "unable to register quorum device: this node is not part of a cluster\n");
- return -ENOENT;
- }
-
- if (strlen(name) > MAX_CLUSTER_MEMBER_NAME_LEN) {
- log_printf(LOG_ERR, "unable to register quorum device: name is too long\n");
- /* this should probably return -E2BIG? */
- return -EINVAL;
- }
-
- /* Allow re-registering of a quorum device if the name is the same */
- if (quorum_device && strcmp(name, quorum_device->name)) {
- log_printf(LOG_ERR, "unable to re-register quorum device: device names do not match\n");
- log_printf(LOG_DEBUG, "memb: old name: %s new name: %s\n", quorum_device->name, name);
- return -EBUSY;
- }
-
- if (find_node_by_name(name)) {
- log_printf(LOG_ERR, "unable to register quorum device: a node with the same name (%s) already exists\n", name);
- return -EALREADY;
- }
-
- memcpy(&votes, cmdbuf, sizeof(int));
-
- /* A new quorum device */
- if (!quorum_device)
- {
- quorum_device = malloc(sizeof(struct cluster_node));
- if (!quorum_device) {
- log_printf(LOG_ERR, "unable to register quorum device: not enough memory\n");
- return -ENOMEM;
- }
- memset(quorum_device, 0, sizeof(struct cluster_node));
-
- quorum_device->name = strdup(name);
- if (!quorum_device->name) {
- log_printf(LOG_ERR, "unable to register quorum device: not enough memory\n");
- free_quorum_device();
- return -ENOMEM;
- }
-
- 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");
- }
- else
- {
- log_printf(LOG_INFO, "quorum device re-registered\n");
- }
-
- quorum_device_update_votes(votes);
-
- return 0;
-}
-
-static int do_cmd_unregister_quorum_device(char *cmdbuf, int *retlen)
-{
- if (!quorum_device) {
- log_printf(LOG_DEBUG, "memb: failed to unregister a non existing quorum device\n");
- return -EINVAL;
- }
-
- if (quorum_device->state == NODESTATE_MEMBER) {
- log_printf(LOG_DEBUG, "memb: failed to unregister: quorum device still active.\n");
- return -EBUSY;
- }
-
- free_quorum_device();
-
- log_printf(LOG_INFO, "quorum device unregistered\n");
- return 0;
-}
-
-static int do_cmd_update_quorum_device(char *cmdbuf, int *retlen)
-{
- int votes, ret = 0;
- char *name = cmdbuf+sizeof(int);
-
- if (!quorum_device) {
- log_printf(LOG_DEBUG, "memb: failed to update a non-existing quorum device\n");
- return -EINVAL;
- }
-
- memcpy(&votes, cmdbuf, sizeof(int));
-
- /* allow name change of the quorum device */
- if (quorum_device && strcmp(name, quorum_device->name)) {
- char *newname = NULL;
- char *oldname = NULL;
-
- log_printf(LOG_DEBUG, "memb: old name: %s new name: %s\n", quorum_device->name, name);
- newname = strdup(name);
- if (!newname) {
- log_printf(LOG_ERR, "memb: unable to update quorum device name: out of memory\n");
- ret = -ENOMEM;
- goto out;
- }
- log_printf(LOG_INFO, "quorum device name changed to %s\n", name);
- oldname = quorum_device->name;
- quorum_device->name = newname;
- free(oldname);
- }
-
-out:
- quorum_device_update_votes(votes);
-
- return ret;
-}
-
-static int reload_config(int new_version, int should_broadcast)
-{
- const char *reload_err = NULL;
-
- if (config_version == new_version) {
- log_printf(LOG_DEBUG, "We are already using config version [%d]\n",
- config_version);
- return 0;
- }
-
- if (new_version > 0 && new_version < config_version) {
- log_printf(LOG_ERR, "Requested version [%d] older than running version [%d]\n",
- new_version, config_version);
- return -1;
- }
-
- wanted_config_version = new_version;
-
- /* Tell objdb to reload */
- config_error = corosync->object_reload_config(1, &reload_err);
- if (config_error)
- log_printf(LOG_ERR, "Unable to load new config in corosync: %s\n",
- reload_err);
-
- if (!config_error)
- config_error = read_cman_nodes(corosync, &config_version, 0);
-
- if (config_error) {
- if (wanted_config_version) {
- log_printf(LOG_ERR, "Can't get updated config version %d: %s.\n",
- wanted_config_version, reload_err?reload_err:"version mismatch on this node");
- } else {
- log_printf(LOG_ERR, "Can't get updated config version: %s.\n",
- reload_err?reload_err:"version mismatch on this node");
- }
-
- if (should_broadcast) {
- log_printf(LOG_ERR, "Continuing activity with old configuration\n");
- config_error=0;
- return -2;
- } else {
- log_printf(LOG_ERR, "Activity suspended on this node\n");
-
- if (!ccsd_timer_active) {
- log_printf(LOG_ERR, "Error reloading the configuration, will retry every second\n");
- corosync->timer_add_duration((unsigned long long)ccsd_poll_interval*1000000, NULL,
- ccsd_timer_fn, &ccsd_timer);
- ccsd_timer_active = 1;
- }
- }
- } else {
-
- /*
- * at this point we know:
- * config is loaded in objdb with a newer version than the previous one
- * we have been able to activate it in cman (via read_cman_nodes)
- */
-
- if (should_broadcast) {
- log_printf(LOG_DEBUG, "Sending reconfigure message to all nodes\n");
- send_reconfigure(us->node_id, RECONFIG_PARAM_CONFIG_VERSION, config_version);
- }
-
- log_printf(LOG_DEBUG, "Recalculating quorum\n");
- recalculate_quorum(1, 0);
-
- log_printf(LOG_DEBUG, "Notify all listeners\n");
- notify_listeners(NULL, EVENT_REASON_CONFIG_UPDATE, config_version);
- }
- return config_error;
-}
-
-static void ccsd_timer_fn(void *arg)
-{
- log_printf(LOG_DEBUG, "Polling configuration for updated information\n");
-
- ccsd_timer_active = 0;
-
- if (!reload_config(wanted_config_version, 0) &&
- config_version >= wanted_config_version) {
- log_printf(LOG_DEBUG, "ccsd_timer_fn got the new config\n");
- config_error = 0;
- return;
- }
-
- if (local_first_trans) {
- time_t now;
- now = time(NULL);
-
- if (now > join_time+startup_config_timeout) {
- log_printf(LOG_ERR, "Checking for startup failure: time=%d\n", (int)(now - join_time));
- log_printf(LOG_ERR, "Failed to get an up-to-date config file, wanted %d, only got %d. Will exit\n",
- wanted_config_version, config_version);
- log_printf(LOG_ERR, "Check your configuration distribution method is working correctly\n");
- cman_finish();
- corosync_shutdown();
- }
- }
-}
-
-static void quorum_device_timer_fn(void *arg)
-{
- struct timeval now;
- unsigned long long timediff_us;
- if (!quorum_device || quorum_device->state == NODESTATE_DEAD)
- return;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: quorum_device_timer_fn\n");
- gettimeofday(&now, NULL);
- timediff_us=((now.tv_sec - quorum_device->last_hello.tv_sec)*1000000 + (now.tv_usec - quorum_device->last_hello.tv_usec));
- if (timediff_us >= quorumdev_poll*1000) {
- quorum_device->state = NODESTATE_DEAD;
- log_printf(LOG_INFO, "lost contact with quorum device\n");
- recalculate_quorum(0, 0);
- }
- else {
- corosync->timer_add_duration(1000*(quorumdev_poll*1000 - timediff_us),
- 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);
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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) {
- addrs->numaddrs = 0;
- *retlen = sizeof(struct cl_get_node_addrs);
- return 0;
- }
-
- if (corosync->totem_ifaces_get(nodeid, node_ifs, &status, (unsigned int *)&addrs->numaddrs))
- return -errno;
-
- for (i=0; i<addrs->numaddrs; 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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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));
- /* sanitize input value */
- if (value > 0)
- value = 1;
-
- logsys_config_debug_set(CMAN_NAME, value);
- err = 0;
- break;
- 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_GETNODE_EXTRA:
- err = do_cmd_get_node_extra(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_UPDATE_QUORUMDEV:
- err = do_cmd_update_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;
- }
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: command return code is %d\n", err);
- return err;
-}
-
-
-int send_to_userport(unsigned char fromport, unsigned char toport,
- int nodeid, int tgtid,
- const char *recv_buf, int len,
- int endian_conv)
-{
- int ret = -1;
-
- if (toport == 0) {
-
- /* We need to make a private copy here so that the internal command
- * processors can do byteswapping.
- */
- char *newmsg = alloca(len);
- if (!newmsg)
- return -1;
- memcpy(newmsg, recv_buf, len);
- process_internal_message(newmsg, nodeid, endian_conv);
- ret = 0;
- }
- else {
- /* Send to external listener */
- if (port_array[toport]) {
- struct connection *c = port_array[toport];
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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(const unsigned int *member_list, size_t member_list_entries,
- const unsigned int *left_list, size_t left_list_entries,
- const unsigned int *joined_list, size_t 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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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(void)
-{
- 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;
- }
-
- if (local_first_trans) {
- time_t now;
- now = time(NULL);
-
- if (now > join_time+startup_config_timeout) {
- log_printf(LOG_DEBUG, "ccs: disable startup transition check\n");
- local_first_trans = 0;
- }
- }
-
- /* New config version - try to read new file */
- if (msg->config_version > config_version) {
- log_printf(LOG_DEBUG, "Reloading config from TRANSITION message\n");
- if (reload_config(msg->config_version, 0)) {
- 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;
- }
- }
- }
-
- if ((msg->config_version == config_version) && (nodeid != us->node_id)) {
- log_printf(LOG_DEBUG, "Completed first transition with nodes on the same config versions\n");
- local_first_trans = 0;
- }
-
- 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;
- local_first_trans = first_trans;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- /* We must be fully started by now */
- local_first_trans = 0;
-
- 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:
- reload_config(msg->value, 0);
- break;
- }
-}
-
-static void do_fence_msg(void *data)
-{
- struct cl_fencemsg *msg = data;
- struct cluster_node *node;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
- unsigned int old_expected;
- nodestate_t old_state;
-
- if (valid_transition_msg(nodeid, msg) != 0) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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 and we want to join,
- then we can't, as we don't know the full state */
- if (enable_disallowed &&
- local_first_trans && 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");
- cman_finish();
- 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);
- old_expected = node->expected_votes;
- old_state = node->state;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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 (enable_disallowed) {
- if ( (msg->flags & NODE_FLAGS_DIRTY && (node->flags & NODE_FLAGS_BEENDOWN)) ||
- (msg->flags & NODE_FLAGS_DIRTY && msg->first_trans && !node->us && (us->flags & NODE_FLAGS_DIRTY))) {
- /* Don't duplicate messages */
- if (node->state != NODESTATE_AISONLY) {
- if (cluster_is_quorate) {
- node->state = NODESTATE_AISONLY;
-
- /* Oh, this gets even more complicated. Don't send a KILL message if we are in a two_node
- * cluster and that node has a lower node ID than us.
- * This allows fencing time to startup and caters for the situation where
- * a node rejoins REALLY quickly, before fencing has had time to work.
- * I've split this up a bit partly for clarity, but mainly so allow us to
- * print out helpful messages as to what we are up to here.
- */
- if (two_node) {
- if (node->node_id > us->node_id) {
- log_printf(LOG_CRIT, "Killing node %s because it has rejoined the cluster with existing state and has higher node ID", node->name);
- send_kill(nodeid, CLUSTER_KILL_REJOIN);
- }
- else {
- log_printf(LOG_CRIT, "Not killing node %s despite it rejoining the cluster with existing state, it has a lower node ID", node->name);
- }
- }
- else {
- log_printf(LOG_CRIT, "Killing node %s because it has rejoined the cluster with existing state", node->name);
- send_kill(nodeid, CLUSTER_KILL_REJOIN);
- }
- }
- else {
- 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) {
- 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 {
- 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);
- }
- }
- else {
- add_ais_node(nodeid, incarnation, num_ais_nodes);
- }
-
- /* If the new node is joining and the existing 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 (enable_disallowed &&
- msg->first_trans && !node->us && have_disallowed())
- 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;
- us->expected_votes = max(us->expected_votes, msg->expected_votes);
-
- if (old_state != node->state || old_expected != node->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 fencemsg[sizeof(struct cl_fencemsg)+strlen(node->fence_agent)+1];
- struct cl_fencemsg *fence_msg = (struct cl_fencemsg *)fencemsg;
-
- 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(fencemsg, sizeof(fencemsg), 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];
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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);
- log_printf(LOGSYS_LEVEL_DEBUG, "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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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:
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: got TRANSITION from node %d\n", nodeid);
- do_process_transition(nodeid, data);
- break;
-
- case CLUSTER_MSG_KILLNODE:
- killmsg = (struct cl_killmsg *)data;
- log_printf(LOGSYS_LEVEL_DEBUG, "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));
- cman_finish();
- exit(1);
- }
- break;
-
- case CLUSTER_MSG_LEAVE:
- leavemsg = (struct cl_leavemsg *)data;
- log_printf(LOGSYS_LEVEL_DEBUG, "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);
- cman_finish();
- corosync_shutdown();
- }
-
- /* 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 *node, int nodeid, int votes, int expected_votes)
-{
- /* Update node entry */
- add_new_node(node, nodeid, votes, expected_votes, NODESTATE_DEAD);
-}
-
-void add_ais_node(int nodeid, uint64_t incar, int total_members)
-{
- struct cluster_node *node;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: add_ais_node ID=%d, incarnation = %" PRIu64 "\n",nodeid, incar);
-
- node = find_node_by_nodeid(nodeid);
- if (!node && total_members == 1) {
- node = us;
- log_printf(LOGSYS_LEVEL_DEBUG, "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 = incar;
- node->state = NODESTATE_MEMBER;
- node->leave_reason = 0;
- cluster_members++;
- recalculate_quorum(0, 0);
- }
-}
-
-void del_ais_node(int nodeid)
-{
- struct cluster_node *node;
- time_t t;
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
- memset(&node->port_bits, 0, sizeof(node->port_bits));
- cluster_members--;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "memb: del_ais_node %s, leave_reason=%x\n", node->name, node->leave_reason);
- if (node->leave_reason == 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 const 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 af0b17a..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,
- const 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(const unsigned int *member_list, size_t member_list_entries,
- const unsigned int *left_list, size_t left_list_entries,
- const unsigned int *joined_list, size_t 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 92cfd47..0000000
--- a/cman/daemon/daemon.c
+++ /dev/null
@@ -1,528 +0,0 @@
-#include <getopt.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <sys/stat.h>
-#include <sys/poll.h>
-#include <sys/socket.h>
-#include <sys/signal.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <sys/errno.h>
-
-#include <corosync/corotypes.h>
-#include <corosync/coroipc_types.h>
-#include <corosync/coroipcc.h>
-#include <corosync/corodefs.h>
-#include <corosync/mar_gen.h>
-#include <corosync/engine/coroapi.h>
-#include <corosync/engine/logsys.h>
-#include <corosync/totem/coropoll.h>
-
-#include "list.h"
-#include "cnxman-socket.h"
-#include "cnxman-private.h"
-#include "daemon.h"
-#include "commands.h"
-#include "barrier.h"
-#include "ais.h"
-#include "cman.h"
-
-LOGSYS_DECLARE_SUBSYS (CMAN_NAME);
-
-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;
-hdb_handle_t cs_poll_handle;
-uint32_t max_outstanding_messages = DEFAULT_MAX_QUEUED;
-
-static int process_client(hdb_handle_t handle, int fd, int revent, void *data);
-static void remove_client(hdb_handle_t 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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "daemon: Disconnecting. client has more that %d replies outstanding (%d)\n", max_outstanding_messages, con->num_write_msgs);
- remove_client(cs_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++;
- log_printf(LOGSYS_LEVEL_DEBUG, "daemon: queued last message, count is %d\n", con->num_write_msgs);
- poll_dispatch_modify(cs_poll_handle, con->fd, POLLIN | POLLOUT, process_client);
- }
- return 0;
-}
-
-static void remove_client(hdb_handle_t 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++;
- }
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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 */
- log_printf(LOGSYS_LEVEL_DEBUG, "daemon: Removing POLLOUT from fd %d\n", con->fd);
- poll_dispatch_modify(cs_poll_handle, con->fd, POLLIN, process_client);
- }
-}
-
-/* Dispatch a request from a CLIENT or ADMIN socket */
-static int process_client(hdb_handle_t 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));
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "daemon: bad magic in client command %x\n", msg->magic);
- send_status_return(con, msg->command, -EINVAL);
- return 0;
- }
- if (msg->version != CMAN_VERSION) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
- }
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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) {
- log_printf(LOGSYS_LEVEL_DEBUG, "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 *databuf = (char *)msg;
- int ret;
- uint8_t port;
- struct sock_data_header *dmsg = (struct sock_data_header *)msg;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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);
-
- databuf += 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(databuf, 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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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(hdb_handle_t 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, hdb_handle_t 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;
-
- log_printf(LOGSYS_LEVEL_DEBUG, "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, const 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);
- }
-}
-
-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;
-}
-
-int cman_init(struct corosync_api_v1 *api)
-{
- int fd;
- struct sigaction sa;
-
- cs_poll_handle = api->poll_handle_get();
- 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, cs_poll_handle, CON_CLIENT);
- if (fd < 0)
- return -2;
-
- fd = open_local_sock(ADMIN_SOCKNAME, sizeof(ADMIN_SOCKNAME), 0600, cs_poll_handle, CON_ADMIN);
- if (fd < 0)
- return -2;
-
- /* Shutdown trap */
- sa.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &sa, NULL);
- sigaction(SIGINT, &sa, NULL);
- sigaction(SIGTERM, &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 49611b1..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, const 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(struct corosync_api_v1 *api);
-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/fnvhash.c b/cman/daemon/fnvhash.c
deleted file mode 100644
index 47e221a..0000000
--- a/cman/daemon/fnvhash.c
+++ /dev/null
@@ -1,93 +0,0 @@
-#include <stdint.h>
-#include "fnvhash.h"
-
-/***
- *
- * Fowler/Noll/Vo hash
- *
- * The basis of this hash algorithm was taken from an idea sent
- * as reviewer comments to the IEEE POSIX P1003.2 committee by:
- *
- * Phong Vo (http://www.research.att.com/info/kpv/)
- * Glenn Fowler (http://www.research.att.com/~gsf/)
- *
- * In a subsequent ballot round:
- *
- * Landon Curt Noll (http://www.isthe.com/chongo/)
- *
- * improved on their algorithm. Some people tried this hash
- * and found that it worked rather well. In an EMail message
- * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash.
- *
- * FNV hashes are designed to be fast while maintaining a low
- * collision rate. The FNV speed allows one to quickly hash lots
- * of data while maintaining a reasonable collision rate. See:
- *
- * http://www.isthe.com/chongo/tech/comp/fnv/index.html
- *
- * for more details as well as other forms of the FNV hash.
- ***
- *
- * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the
- * Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str().
- *
- ***
- *
- * Please do not copyright this code. This code is in the public domain.
- *
- * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
- * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
- * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * By:
- * chongo <Landon Curt Noll> /\oo/\
- * http://www.isthe.com/chongo/
- *
- * Share and Enjoy! :-)
- */
-
-/*
- * Modified to be a little more simple to understand and to provide a 16 bit
- * value rather then 32 bit for cluster id generation
- *
- * sdake(a)redhat.com
- */
-
-/* 32 bit magic FNV-1a prime */
-#define FNV_32_PRIME ((uint32_t)0x01000193)
-
-/* Default initialization for FNV-1a */
-#define FNV_32_INIT ((uint32_t)0x811c9dc5)
-
-uint16_t fnv_hash(char *str)
-{
- unsigned char *s = (unsigned char *)str;
- uint32_t hval = FNV_32_INIT;
- uint32_t ret;
-
- /*
- * FNV-1a hash each octet in the buffer
- */
- while (*s) {
- /*
- * xor the bottom with the current octet
- */
- hval ^= (uint32_t)*s++;
- /*
- * multiply by the 32 bit FNV magic prime mod 2^32
- */
- hval *= FNV_32_PRIME;
- }
-
- /*
- * Use XOR folding as recommended by authors of algorithm
- * to create a different hash size that is a power of two
- */
- ret = (hval >> 16) ^ (hval & 0xFFFF);
-
- return (ret);
-}
diff --git a/cman/daemon/fnvhash.h b/cman/daemon/fnvhash.h
deleted file mode 100644
index 65e9c11..0000000
--- a/cman/daemon/fnvhash.h
+++ /dev/null
@@ -1 +0,0 @@
-uint16_t fnv_hash(char *str);
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 <assert.h>
-
-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/nodelist.h b/cman/daemon/nodelist.h
deleted file mode 100644
index bbf2628..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, hdb_handle_t object_service_handle,
- const 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, hdb_handle_t object_service_handle,
- const 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 hdb_handle_t nodeslist_init(OBJDB_API *corosync,
- hdb_handle_t cluster_parent_handle,
- hdb_handle_t *find_handle)
-{
- hdb_handle_t object_handle;
- hdb_handle_t find_handle1;
- hdb_handle_t find_handle2;
-
- corosync->object_find_create(cluster_parent_handle,"clusternodes", strlen("clusternodes"), &find_handle1);
- if (corosync->object_find_next(find_handle1, &object_handle) == 0)
- {
- hdb_handle_t 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 hdb_handle_t nodeslist_next(OBJDB_API *corosync, hdb_handle_t find_handle)
-{
- hdb_handle_t nodes_handle;
-
- if (corosync->object_find_next(find_handle, &nodes_handle) == 0)
- return nodes_handle;
- else
- return 0;
-}
-
-static inline hdb_handle_t nodelist_byname(OBJDB_API *corosync,
- hdb_handle_t cluster_parent_handle,
- char *name)
-{
- char *nodename;
- hdb_handle_t nodes_handle;
- hdb_handle_t 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 1ce42d6..0000000
--- a/cman/init.d/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-TARGET=cman cman.init.defaults
-
-INITDT=cman
-
-all: $(TARGET)
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-%: $(S)/%.in
- cat $^ | sed \
- -e 's#@SBINDIR@#${sbindir}#g' \
- -e 's#@INITDDIR@#${initddir}#g' \
- -e 's#@NOTIFYDDIR@#${notifyddir}#g' \
- -e 's#@CONFDIR@#${CONFDIR}#g' \
- -e 's#@CONFFILE@#${CONFFILE}#g' \
- > $@
-
-clean: generalclean
diff --git a/cman/init.d/cman.in b/cman/init.d/cman.in
deleted file mode 100644
index 384fa2f..0000000
--- a/cman/init.d/cman.in
+++ /dev/null
@@ -1,980 +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 fence_sanlockd
-# Required-Stop: $network $time fence_sanlockd
-# Default-Start:
-# Default-Stop:
-# Short-Description: Starts and stops cman
-# Description: Starts and stops the Cluster Manager set of daemons
-### END INIT INFO
-
-# set secure PATH
-PATH="/bin:/usr/bin:/sbin:/usr/sbin:@SBINDIR@"
-
-# save invokation for rollback ops
-thisinvokation="$0"
-
-local_chkconfig()
-{
- case "$1" in
- --levels)
- ls /etc/rc${2}.d/S*${3} > /dev/null 2>/dev/null
- return $?
- ;;
- *)
- ls /etc/rc*.d/S*${1} > /dev/null 2>/dev/null
- return $?
- ;;
- esac
-}
-
-success()
-{
- echo -ne "[ OK ]\r"
-}
-
-failure()
-{
- echo -ne "[FAILED]\r"
-}
-
-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
-}
-
-# 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"
-fi
-
-# deb based distros
-if [ ! -d /etc/sysconfig ]; then
- [ -f /etc/default/cluster ] && . /etc/default/cluster
- [ -f /etc/default/cman ] && . /etc/default/cman
- [ -z "$LOCK_FILE" ] && LOCK_FILE="/var/lock/cman"
- type chkconfig > /dev/null 2>&1 || alias chkconfig=local_chkconfig
-fi
-
-# 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=60
-
-# 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 zero, quorum will
-# be ignored.
-[ -z "$CMAN_QUORUM_TIMEOUT" ] && CMAN_QUORUM_TIMEOUT=45
-
-# 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
-
-# CMAN_NOTIFYD_START - control the startup behaviour for cmannotifyd
-# the variable can take 3 values:
-# yes | will always start cmannotifyd
-# no | will never start cmannotifyd
-# conditional (default) | will start cmannotifyd only if scriptlets
-# are found in @NOTIFYDDIR@
-[ -z "$CMAN_NOTIFYD_START" ] && CMAN_NOTIFYD_START=conditional
-
-# CMAN_SSHD_START - control sshd startup behaviour
-# the variable can take 2 values:
-# yes | cman will start sshd as early as possible
-# no (default) | cman will not start sshd
-[ -z "$CMAN_SSHD_START" ] && CMAN_SSHD_START=no
-
-# DLM_CONTROLD_OPTS -- allow extra options to be passed to dlm_controld daemon.
-[ -z "$DLM_CONTROLD_OPTS" ] && DLM_CONTROLD_OPTS=""
-
-# Allow tuning of DLM kernel config.
-# do NOT change unless instructed to do so.
-[ -z "$DLM_LKBTBL_SIZE" ] && DLM_LKBTBL_SIZE=""
-[ -z "$DLM_RSBTBL_SIZE" ] && DLM_RSBTBL_SIZE=""
-[ -z "$DLM_DIRTBL_SIZE" ] && DLM_DIRTBL_SIZE=""
-[ -z "$DLM_TCP_PORT" ] && DLM_TCP_PORT=""
-
-# FENCE_JOIN_TIMEOUT -- seconds to wait for fence domain join to
-# complete. If the join hasn't completed in this time, fence_tool join
-# exits with an error, and this script exits with an error. To wait
-# indefinitely set the value to -1.
-[ -z "$FENCE_JOIN_TIMEOUT" ] && FENCE_JOIN_TIMEOUT=20
-
-# 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").
-# When setting FENCE_JOIN to "no", it is important to also set
-# DLM_CONTROLD_OPTS="-f0" (at least) for correct operation.
-# Please note that clusters without fencing are not
-# supported by Red Hat except for MRG installations.
-[ -z "$FENCE_JOIN" ] && FENCE_JOIN="yes"
-
-# FENCED_OPTS -- allow extra options to be passed to fence daemon.
-[ -z "$FENCED_OPTS" ] && FENCED_OPTS=""
-
-# 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"
-
-# CMAN_JOIN_OPTS -- allows extra options to be passed to cman_tool when join
-# operation is performed.
-# NOTES:
-# $CLUSTERNAME automatically appends "-c $CLUSTERNAME"
-# $NODENAME automatically appends "-n $NODENAME"
-# $CONFIG_LOADER automatically appends "-C $CONFIG_LOADER"
-
-[ -n "$CMAN_JOIN_OPTS" ] && cman_join_opts="$CMAN_JOIN_OPTS"
-
-[ -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)
-[ -n "$CONFIG_LOADER" ] && cman_join_opts+=" -C $CONFIG_LOADER"
-
-# CONFIG_VALIDATION -- select default config validation behaviour
-# This can be:
-# FAIL - Use a very strict checking. The config will not be loaded if there
-# for any kind of warnings/errors.
-# WARN - Same as FAIL, but will allow the config to load (this is temporary
-# the default behaviour)
-# NONE - Disable config validation. Highly discouraged.
-[ -z "$CONFIG_VALIDATION" ] && CONFIG_VALIDATION=WARN
-cman_join_opts+=" -D$CONFIG_VALIDATION"
-
-# CMAN_LEAVE_OPTS -- allows extra options to be passed to cman_tool when leave
-# operation is performed.
-[ -n "$CMAN_LEAVE_OPTS" ] && cman_leave_opts="$CMAN_LEAVE_OPTS"
-
-# INITLOGLEVEL -- select how verbose the init script should be
-# possible values:
-# quiet - only one line notification for start/stop operations
-# terse (default) - show only required activity
-# full - show everything
-[ -z "$INITLOGLEVEL" ] && INITLOGLEVEL=terse
-
-### generic wrapper functions
-
-ok() {
- if [ "$INITLOGLEVEL" != "quiet" ]; then
- success
- echo
- fi
-}
-
-nok() {
- echo -e "$errmsg"
- failure
- echo
- if [ "$currentaction" = "start" ]; then
- $thisinvokation stop
- fi
- exit 1
-}
-
-none()
-{
- return 0
-}
-
-runwrap()
-{
- function=$1
- shift
- conditional=$1
- shift
- message="$@"
-
- if ! $conditional; then
- if [ "$INITLOGLEVEL" = "full" ]; then
- echo " $message... action not required"
- fi
- return 0
- fi
-
- if [ "$INITLOGLEVEL" != "quiet" ]; then
- echo -n " $message... "
- fi
- if $function; then
- ok
- else
- nok
- fi
-}
-
-check_exec()
-{
- exec=$1
-
- realexec="$(type -p $exec)"
- if [ -z "$realexec" ]; then
- errmsg="Unable to find $exec in PATH"
- return 1
- fi
- if [ ! -x "$realexec" ]; then
- errmsg="$realexec not executable"
- return 1
- fi
- return 0
-}
-
-start_daemon()
-{
- daemon=$1
- shift
- args="$@"
-
- check_exec $daemon || return $?
- status $daemon > /dev/null 2>&1 && return 0
- errmsg=$( $daemon $args 2>&1 )
-}
-
-check_sleep()
-{
- if ! sleep 0.01 > /dev/null 2>&1; then
- return 1
- fi
-}
-
-stop_daemon()
-{
- daemon=$1
- shift
- retryforsec=$1
-
- [ -z "$retryforsec" ] && retryforsec=30
- retries=0
-
- if check_sleep; then
- sleepfor=0.25
- retryforsec=$(($retryforsec * 4))
- else
- sleepfor=1
- fi
-
- while status $daemon > /dev/null 2>&1 && \
- [ $retries -lt $retryforsec ]; do
-
- errmsg=$( pkill -TERM $daemon ) || return 1
- sleep $sleepfor
- ((retries++))
- done
-
- ! status $daemon > /dev/null 2>&1
-}
-
-### check functions (enable/disable) (on/off)
-
-sshd_enabled()
-{
- case "$CMAN_SSHD_START" in
- yes)
- return 0
- ;;
- esac
- return 1
-}
-
-cluster_disabled_at_boot()
-{
- if grep -q nocluster /proc/cmdline && \
- [ "$(tty)" = "/dev/console" ]; then
- errmsg="not configured to run at boot"
- return 1
- fi
- return 0
-}
-
-network_manager_enabled()
-{
- if status NetworkManager > /dev/null 2>&1 || \
- chkconfig NetworkManager; then
- errmsg="\nNetwork Manager is either running or configured to run. Please disable it in the cluster."
- return 1
- fi
- return 0
-}
-
-mtab_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
-}
-
-cman_running()
-{
- cman_tool status > /dev/null 2>&1
-}
-
-# NOTE: this could probably grow a bit to do config sanity checks
-cman_checkconfig()
-{
- case "$CONFIG_LOADER" in
- xmlconfig|"")
- configfile=@CONFDIR@/@CONFFILE@
- [ -n "$COROSYNC_CLUSTER_CONFIG_FILE" ] && \
- configfile=$COROSYNC_CLUSTER_CONFIG_FILE
-
- if [ ! -f $configfile ]; then
- errmsg="xmlconfig cannot find $configfile"
- return 1
- fi
- ;;
- esac
-}
-
-xend_bridged_net_enabled() {
- # Not a xen kernel
- [ -d /proc/xen ] || return 1
-
- # uanble to determine current runlevel
- current_runlevel=$( runlevel 2>/dev/null | \
- awk '{ print $2 }' 2>/dev/null )
- [ -z "$current_runlevel" ] && return 1
-
- # xend doesn't start at this runlevel.
- ! chkconfig --levels "$current_runlevel" xend 2>/dev/null && return 1
-
- # xend isn't configured to use bridged networking.
- [ ! -f /etc/xen/xend-config.sxp ] && return 1
-
- # xend isn't configured to use bridged networking.
- ! egrep \
- "^[[:blank:]]*\([[:blank:]]*network-script[[:blank:]]+(')?[[:blank:]]*${NETWORK_BRIDGE_SCRIPT}([[:blank:]]*\)|[[:blank:]]+)" \
- /etc/xen/xend-config.sxp >&/dev/null && return 1
-}
-
-qdiskd_enabled()
-{
- ccs_tool query /cluster/quorumd >/dev/null 2>&1
-}
-
-groupd_enabled()
-{
- groupd_compat="$(ccs_tool query /cluster/group/@groupd_compat \
- 2>/dev/null || true)"
-
- [ -z "$groupd_compat" ] && return 1
- [ "$groupd_compat" = 0 ] && return 1
- return 0
-}
-
-ocfs2_enabled()
-{
- ocfs2_cluster="$(cat /sys/fs/ocfs2/cluster_stack 2>/dev/null || true)"
- [ "$ocfs2_cluster" != cman ] && return 1
- return 0
-}
-
-cmannotifyd_enabled()
-{
- case "$CMAN_NOTIFYD_START" in
- yes)
- return 0
- ;;
- conditional)
- if [ -n "$(ls -1 @NOTIFYDDIR@ 2>/dev/null)" ]; then
- return 0
- fi
- ;;
- esac
- return 1
-}
-
-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
- fi
-}
-
-### the real stuff starts here
-
-start_global()
-{
- ## global bits
- # guarantee enough limits
- ulimit -c unlimited
- # required for distributions that use tmpfs for /var/run
- mkdir -p /var/run/cluster
-}
-
-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
-
- modprobe netbk >& /dev/null || true
- modprobe netloop >& /dev/null || true
-
- 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 )
-}
-
-load_kernel_modules()
-{
- errmsg=$( modprobe configfs 2>&1 ) || return 1
- errmsg=$( modprobe dlm 2>&1 ) || return 1
- errmsg=$( modprobe lock_dlm 2>&1 ) || true
-}
-
-unload_kernel_modules()
-{
- modprobe -r lock_dlm > /dev/null 2>&1 || true
- modprobe -r dlm > /dev/null 2>&1 || true
-}
-
-start_configfs()
-{
- mtab_configfs && return 0
- errmsg=$( mount -t configfs none /sys/kernel/config 2>&1 )
-}
-
-stop_configfs()
-{
- if mtab_configfs && [ -z "$(ls -1 /sys/kernel/config)" ]; then
- errmsg=$( umount /sys/kernel/config 2>&1 ) || return 1
- modprobe -r configfs > /dev/null 2>&1 || true
- fi
-}
-
-corosync_running()
-{
- [ -f /var/run/corosync.pid ] || return 1
-
- read corosync_pid foo < /var/run/corosync.pid
- if [ "$(pidof corosync)" == "$corosync_pid" ];then
- errmsg="Corosync Cluster Engine is already running"
- return 0
- fi
-
- return 1
-}
-
-start_cman()
-{
- check_exec cman_tool || return $?
- cman_running && return 0
- cman_checkconfig || return 1
- corosync_running && return 1
-
- tmpfile=$(mktemp -t cmanstartup.XXXXXXXXXX)
- if [ -z "$tmpfile" ]; then
- errmsg="Unable to create temporary file"
- return 1
- fi
-
- cman_tool -z -t $CMAN_CLUSTER_TIMEOUT -w join $cman_join_opts > $tmpfile 2>&1 &
-
- while status cman_tool >/dev/null 2>&1; do
- sleep 0.2
- done
-
- sleep 2
-
- if ! cman_running; then
- errmsg="$(cat $tmpfile) Check cluster logs for details"
- ret=1
- else
- if [ "$CONFIG_VALIDATION" = "WARN" ] && \
- [ -s $tmpfile ] && \
- grep -q Relax-NG $tmpfile ; then
- cat $tmpfile >&2
- fi
- pidof /usr/sbin/corosync > /var/run/cman.pid
- ret=0
- fi
-
- rm -f $tmpfile
- return $ret
-}
-
-wait_for_quorum()
-{
- if [ $CMAN_QUORUM_TIMEOUT -gt 0 ]; then
- errmsg=$( cman_tool -t $CMAN_QUORUM_TIMEOUT \
- -q wait 2>&1 ) || return 1
- fi
-}
-
-stop_cman()
-{
- if cman_running; then
- errmsg=$( cman_tool $cman_leave_opts -t $CMAN_SHUTDOWN_TIMEOUT \
- -w leave $cmanremove 2>&1 ) || return 1
- ok
- echo -n " Waiting for corosync to shutdown:"
- while status corosync > /dev/null 2>&1; do
- sleep 1
- echo -n "."
- done
- rm -f /var/run/cman.pid
- fi
- return 0
-}
-
-start_qdiskd()
-{
- start_daemon qdiskd "-Q" || return 1
-
- if [ "$INITLOGLEVEL" = "full" ]; then
- ok
- echo -n " Waiting for qdiskd to be active: "
- fi
- retries=0
- while ! cman_tool status |grep -q "Quorum device" && \
- status qdiskd > /dev/null 2>&1 && \
- [ $retries -lt 10 ]; do
- sleep 2
- if [ "$INITLOGLEVEL" = "full" ]; then
- echo -n "$retries "
- fi
- ((retries++))
- done
- status qdiskd > /dev/null 2>&1
-}
-
-stop_qdiskd()
-{
- stop_daemon qdiskd
-}
-
-start_groupd()
-{
- start_daemon groupd || return 1
-
- if [ "$INITLOGLEVEL" = "full" ]; then
- ok
- echo -n " Waiting groupd protocol negotiation: "
- fi
- retries=0
- while group_tool ls | \
- grep -q pending && [ $retries -lt 10 ]; do
- sleep 1
- if [ "$INITLOGLEVEL" = "full" ]; then
- echo -n "$retries "
- fi
- ((retries++))
- done
- return 0
-}
-
-stop_groupd()
-{
- stop_daemon groupd
-}
-
-start_fenced()
-{
- start_daemon fenced "$FENCED_OPTS"
-}
-
-stop_fenced()
-{
- stop_daemon fenced
-}
-
-start_dlm_controld()
-{
- start_daemon dlm_controld "$DLM_CONTROLD_OPTS" || return 1
-
- if [ "$INITLOGLEVEL" = "full" ]; then
- ok
- echo -n " Waiting dlm_controld to complete initialization: "
- fi
-
- retries=0
- while ! dlm_tool ls >/dev/null 2>&1 && [ $retries -lt 10 ]; do
- sleep 1
- if [ "$INITLOGLEVEL" = "full" ]; then
- echo -n "$retries "
- fi
- ((retries++))
- done
-
- return 0
-}
-
-stop_dlm_controld()
-{
- stop_daemon dlm_controld
-}
-
-start_gfs_controld()
-{
- start_daemon gfs_controld
-}
-
-stop_gfs_controld()
-{
- stop_daemon gfs_controld
-}
-
-start_ocfs2_controld()
-{
- start_daemon ocfs2_controld.cman
-}
-
-start_cmannotifyd()
-{
- start_daemon cmannotifyd
-}
-
-stop_cmannotifyd()
-{
- stop_daemon cmannotifyd
-}
-
-fence_sanlock_check()
-{
- service fence_sanlockd status > /dev/null 2>&1 &&
- echo " fence_sanlockd detected. Unfencing might take several minutes!"
- return 0
-}
-
-unfence_self()
-{
- # fence_node returns 0 on success, 1 on failure, 2 if unconfigured
- # 0 and 2 are ok. Everything else should report error.
- fence_err=$(fence_node -U 2>&1)
- case $? in
- 0|2)
- return 0
- ;;
- esac
- errmsg="$fence_err"
- return 1
-}
-
-join_fence_domain()
-{
- if ! cman_tool status | grep Flags | grep 2node \
- > /dev/null 2>&1; then
- errmsg=$( fence_tool join -w $FENCE_JOIN_TIMEOUT \
- 2>&1 ) || return 1
- else
- errmsg=$( fence_tool join -w $FENCE_JOIN_TIMEOUT \
- -m $FENCED_MEMBER_DELAY join \
- 2>&1 ) || return 1
- fi
-}
-
-leave_fence_domain()
-{
- if status fenced > /dev/null 2>&1; then
- errmsg=$( fence_tool leave -w 30 2>&1 )
- return $?
- fi
-}
-
-tune_dlm_config()
-{
- dlmdir="/sys/kernel/config/dlm/cluster"
-
- [ -n "$DLM_LKBTBL_SIZE" ] && [ -f $dlmdir/lkbtbl_size ] && \
- echo $DLM_LKBTBL_SIZE > $dlmdir/lkbtbl_size
-
- [ -n "$DLM_RSBTBL_SIZE" ] && [ -f $dlmdir/rsbtbl_size ] && \
- echo $DLM_RSBTBL_SIZE > $dlmdir/rsbtbl_size
-
- [ -n "$DLM_DIRTBL_SIZE" ] && [ -f $dlmdir/dirtbl_size ] && \
- echo $DLM_DIRTBL_SIZE > $dlmdir/dirtbl_size
-
- [ -n "$DLM_TCP_PORT" ] && [ -f $dlmdir/tcp_port ] && \
- echo $DLM_TCP_PORT > $dlmdir/tcp_port
-
- return 0
-}
-
-start()
-{
- currentaction="start"
- breakpoint="$1"
-
- sshd_enabled && service sshd start
-
- if [ "$INITLOGLEVEL" = "quiet" ]; then
- echoarg="-n"
- fi
-
- echo $echoarg "Starting cluster: "
-
- runwrap cluster_disabled_at_boot \
- none \
- "Checking if cluster has been disabled at boot"
-
- runwrap network_manager_enabled \
- none \
- "Checking Network Manager"
-
- runwrap start_global \
- none \
- "Global setup"
-
- runwrap xend_bridged_net_start \
- xend_bridged_net_enabled \
- "Enable Xend bridge net workaround"
-
- runwrap load_kernel_modules \
- none \
- "Loading kernel modules"
-
- runwrap start_configfs \
- none \
- "Mounting configfs"
-
- [ "$breakpoint" = "setup" ] && return 0
-
- runwrap start_cman \
- none \
- "Starting cman"
-
- [ "$breakpoint" = "join" ] && return 0
-
- runwrap start_qdiskd \
- qdiskd_enabled \
- "Starting qdiskd"
-
- runwrap wait_for_quorum \
- none \
- "Waiting for quorum"
-
- [ "$breakpoint" = "quorum" ] && return 0
-
- runwrap start_groupd \
- groupd_enabled \
- "Starting groupd"
-
- runwrap start_fenced \
- none \
- "Starting fenced"
-
- runwrap start_dlm_controld \
- none \
- "Starting dlm_controld"
-
- runwrap tune_dlm_config \
- none \
- "Tuning DLM kernel config"
-
- runwrap start_gfs_controld \
- none \
- "Starting gfs_controld"
-
- runwrap start_ocfs2_controld \
- ocfs2_enabled \
- "Starting ocfs2_controld"
-
- runwrap start_cmannotifyd \
- cmannotifyd_enabled \
- "Starting cmannotifyd"
-
- [ "$breakpoint" = "daemons" ] && return 0
-
- fence_sanlock_check
-
- runwrap unfence_self \
- none \
- "Unfencing self"
-
- runwrap join_fence_domain \
- fence_join_enabled \
- "Joining fence domain"
-
-}
-
-stop()
-{
- if [ "$INITLOGLEVEL" = "quiet" ]; then
- echoarg="-n"
- fi
-
- echo $echoarg "Stopping cluster: "
-
- runwrap leave_fence_domain \
- fence_join_enabled \
- "Leaving fence domain"
-
- runwrap stop_gfs_controld \
- none \
- "Stopping gfs_controld"
-
- runwrap stop_dlm_controld \
- none \
- "Stopping dlm_controld"
-
- runwrap stop_fenced \
- none \
- "Stopping fenced"
-
- runwrap stop_groupd \
- groupd_enabled \
- "Stopping groupd"
-
- runwrap stop_qdiskd \
- qdiskd_enabled \
- "Stopping qdiskd"
-
- runwrap stop_cman \
- none \
- "Stopping cman"
-
- runwrap stop_cmannotifyd \
- cmannotifyd_enabled \
- "Stopping cmannotifyd"
-
- runwrap unload_kernel_modules \
- none \
- "Unloading kernel modules"
-
- runwrap stop_configfs \
- none \
- "Unmounting configfs"
-}
-
-cmanstatus()
-{
- errmsg=$( status corosync 2>&1 )
- ret=$?
- if [ "$ret" != "0" ]; then
- if [ -f /var/run/cman.pid ]; then
- errmsg="Found stale pid file"
- return 1
- fi
- if [ -f $LOCK_FILE ]; then
- errmsg="Found stale lock file"
- return 2
- fi
- return $ret
- fi
-
- if ! cman_running; then
- errmsg="cman is not running"
- return 3
- fi
-
- if qdiskd_enabled; then
- errmsg=$( status qdiskd 2>&1 ) || return $?
- fi
-
- if groupd_enabled; then
- errmsg=$( status groupd 2>&1 ) || return $?
- fi
-
- errmsg=$( status fenced 2>&1 ) || return $?
- errmsg=$( status dlm_controld 2>&1 ) || return $?
- errmsg=$( status gfs_controld 2>&1 ) || return $?
-
- if cmannotifyd_enabled; then
- errmsg=$( status cmannotifyd 2>&1 ) || return $?
- fi
-}
-
-rtrn=0
-
-if [ "$EUID" != "0" ]; then
- echo "Only root can execute $0 script"
- exit 4
-fi
-
-# See how we were called.
-case "$1" in
-start)
- start "$2" && touch $LOCK_FILE
- if [ "$INITLOGLEVEL" = "quiet" ]; then
- success
- echo
- fi
-;;
-stop)
- cmanremove=""
- if [ -n "$2" ] && [ "$2" = "remove" ]; then
- cmanremove=remove
- fi
- stop && rm -f $LOCK_FILE
- if [ "$INITLOGLEVEL" = "quiet" ]; then
- success
- echo
- fi
-;;
-restart|reload|force-reload)
- cmanremove=remove
- stop && rm -f $LOCK_FILE
- start && touch $LOCK_FILE
-;;
-condrestart|try-restart)
- if cmanstatus; then
- cmanremove=remove
- stop && rm -f $LOCK_FILE
- start && touch $LOCK_FILE
- fi
-;;
-status)
- cmanstatus
- rtrn=$?
- if [ "$rtrn" = 0 ]; then
- echo "cluster is running."
- else
- echo -e "$errmsg"
- fi
-;;
-*)
- echo "Usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
- rtrn=2
-;;
-esac
-
-exit $rtrn
diff --git a/cman/init.d/cman.init.defaults.in b/cman/init.d/cman.init.defaults.in
deleted file mode 100644
index c42672c..0000000
--- a/cman/init.d/cman.init.defaults.in
+++ /dev/null
@@ -1,104 +0,0 @@
-# CMAN_CLUSTER_TIMEOUT -- amount of time to wait to join a cluster
-# before giving up. If CMAN_CLUSTER_TIMEOUT is positive, then we will
-# wait CMAN_CLUSTER_TIMEOUT seconds before giving up and failing if
-# we can't join a cluster. If CMAN_CLUSTER_TIMEOUT is zero, then we
-# will wait indefinitely for a cluster join. If CMAN_CLUSTER_TIMEOUT is
-# negative, do not check to see if we have joined a cluster.
-#CMAN_CLUSTER_TIMEOUT=60
-
-# 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 zero, quorum will
-# be ignored.
-#CMAN_QUORUM_TIMEOUT=45
-
-# 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
-#CMAN_SHUTDOWN_TIMEOUT=60
-
-# CMAN_NOTIFYD_START - control the startup behaviour for cmannotifyd,
-# the variable can take 3 values:
-# yes | will always start cmannotifyd
-# no | will never start cmannotifyd
-# conditional (default) | will start cmannotifyd only if scriptlets
-# are found in @NOTIFYDDIR@
-#CMAN_NOTIFYD_START=conditional
-
-# CMAN_SSHD_START -- control sshd startup behaviour,
-# the variable can take 2 values:
-# yes | cman will start sshd as early as possible
-# no (default) | cman will not start sshd
-#CMAN_SSHD_START=no
-
-# DLM_CONTROLD_OPTS -- allow extra options to be passed to dlm_controld daemon.
-#DLM_CONTROLD_OPTS=""
-
-# Allow tuning of DLM kernel config.
-# do NOT change unless instructed to do so.
-#DLM_LKBTBL_SIZE=""
-#DLM_RSBTBL_SIZE=""
-#DLM_DIRTBL_SIZE=""
-#DLM_TCP_PORT=""
-
-# FENCE_JOIN_TIMEOUT -- seconds to wait for fence domain join to
-# complete. If the join hasn't completed in this time, fence_tool join
-# exits with an error, and this script exits with an error. To wait
-# indefinitely set the value to -1.
-#FENCE_JOIN_TIMEOUT=20
-
-# FENCED_MEMBER_DELAY -- amount of time to delay fence_tool join to allow
-# all nodes in cluster.conf to become cluster members. In seconds.
-#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").
-# When setting FENCE_JOIN to "no", it is important to also set
-# DLM_CONTROLD_OPTS="-f0" (at least) for correct operation.
-# Please note that clusters without fencing are not
-# supported by Red Hat except for MRG installations.
-#FENCE_JOIN="yes"
-
-# FENCED_OPTS -- allow extra options to be passed to fence daemon.
-#FENCED_OPTS=""
-
-# 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".
-#NETWORK_BRIDGE_SCRIPT="network-bridge"
-
-# CLUSTERNAME -- override clustername as specified in cluster.conf
-#CLUSTERNAME=""
-
-# NODENAME -- specify the nodename of this node. Default autodetected.
-#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)
-#CONFIG_LOADER=xmlconfig
-
-# CONFIG_VALIDATION -- select default config validation behaviour.
-# This can be:
-# FAIL - Use a very strict checking. The config will not be loaded if there
-# are any kind of warnings/errors
-# WARN - Same as FAIL, but will allow the config to load (this is temporarily
-# the default behaviour)
-# NONE - Disable config validation. Highly discouraged
-#CONFIG_VALIDATION=WARN
-
-# CMAN_LEAVE_OPTS -- allows extra options to be passed to cman_tool when leave
-# operation is performed.
-#CMAN_LEAVE_OPTS=""
-
-# INITLOGLEVEL -- select how verbose the init script should be.
-# Possible values:
-# quiet - only one line notification for start/stop operations
-# terse (default) - show only required activity
-# full - show everything
-#INITLOGLEVEL=terse
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 a99f5a0..0000000
--- a/cman/lib/libcman.c
+++ /dev/null
@@ -1,1133 +0,0 @@
-#include <sys/types.h>
-#include <sys/un.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#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;
- struct msghdr msg;
-
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
-
- while (iovlen > 0)
- {
- msg.msg_iov = iovptr;
- msg.msg_iovlen = iovlen;
-
- len = sendmsg(fd, &msg, MSG_NOSIGNAL);
- 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 = (char *)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;
- }
- fcntl(h->zero_fd, F_SETFD, 1); /* Set close-on-exec */
-
- 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->msg);
- 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->msg);
- 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->msg);
- 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_node_extra(cman_handle_t handle, int nodeid, cman_node_extra_t *node)
-{
- struct cman_handle *h = (struct cman_handle *)handle;
- int status;
- VALIDATE_HANDLE(h);
-
- status = info_call(h, CMAN_CMD_GETNODE_EXTRA, &nodeid, sizeof(int),
- node, sizeof(cman_node_extra_t));
- if (status < 0)
- return -1;
-
- 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;
-}
-
-static int cman_set_quorum_device(cman_handle_t handle,
- int ops,
- char *name, int votes)
-{
- struct cman_handle *h = (struct cman_handle *)handle;
- char buf[strlen(name)+1 + sizeof(int)];
- VALIDATE_HANDLE(h);
-
- if ((!name) || (strlen(name) > MAX_CLUSTER_MEMBER_NAME_LEN) || (votes < 0))
- {
- errno = EINVAL;
- return -1;
- }
-
- memcpy(buf, &votes, sizeof(int));
- strcpy(buf+sizeof(int), name);
- return info_call(h, ops, buf, strlen(name)+1+sizeof(int), NULL, 0);
-}
-
-int cman_register_quorum_device(cman_handle_t handle, char *name, int votes)
-{
- return cman_set_quorum_device(handle, CMAN_CMD_REG_QUORUMDEV, name, votes);
-}
-
-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_update_quorum_device(cman_handle_t handle, char *name, int votes)
-{
- return cman_set_quorum_device(handle, CMAN_CMD_UPDATE_QUORUMDEV, name, votes);
-}
-
-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);
-}
diff --git a/cman/lib/libcman.h b/cman/lib/libcman.h
deleted file mode 100644
index 9f97875..0000000
--- a/cman/lib/libcman.h
+++ /dev/null
@@ -1,457 +0,0 @@
-#ifndef _LIBCMAN_H_
-#define _LIBCMAN_H_
-
-#include <netinet/in.h>
-
-#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;
-
-/*
- * Return from cman_get_node_extra()
- */
-typedef struct cman_node_extra
-{
- int cnx_nodeid;
- int cnx_state;
- int cnx_votes;
- int cnx_expected_votes;
- int cnx_leave_reason;
-} cman_node_extra_t;
-
-#define CLUSTER_LEAVEREASON_DOWN 0 /* Normal shutdown */
-#define CLUSTER_LEAVEREASON_KILLED 1 /* probably buy cman_tool */
-#define CLUSTER_LEAVEREASON_PANIC 2 /* Just disappeared */
-#define CLUSTER_LEAVEREASON_REMOVED 3 /* This one can reduce quorum */
-#define CLUSTER_LEAVEREASON_REJECTED 4 /* Not allowed into the cluster in the first place */
-#define CLUSTER_LEAVEREASON_INCONSISTENT 5 /* Our view of the cluster is in a minority */
-#define CLUSTER_LEAVEREASON_DEAD 6 /* Discovered to be dead */
-#define CLUSTER_LEAVEREASON_NORESPONSE 7 /* Didn't ACK message */
-
-#define CLUSTER_NODESTATE_JOINING 1
-#define CLUSTER_NODESTATE_MEMBER 2
-#define CLUSTER_NODESTATE_DEAD 3
-#define CLUSTER_NODESTATE_LEAVING 4
-#define CLUSTER_NODESTATE_DISALLOWED 5
-
-
-/*
- * 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
-#define CMAN_EXTRA_FLAG_DISALLOWED_ENABLED 32
-
-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);
-
-/*
- * This always gets info by nodeid.
- */
-int cman_get_node_extra(cman_handle_t handle, int nodeid, cman_node_extra_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);
-
-/*
- * These two fencing-related API calls are DEPRECATED from cluster3.
- * libfenced should be used instead.
- */
-int cman_get_fenceinfo(cman_handle_t handle, int nodeid, uint64_t *fence_time, int *fenced, char *agent);
-int cman_node_fenced(cman_handle_t handle, int nodeid, uint64_t fence_time, 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);
-
-/*
- * -----------------------------------------------------------------------------
- * 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);
-
-/*
- * 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
- *
- * register_quorum and update_quorum arguments are mandatory.
- * name has to be a valid null-terminated string and votes >= 0.
- *
- * 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);
-int cman_update_quorum_device(cman_handle_t handle, char *name, int votes);
-
-/*
- * 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/lib/libcman.pc.in b/cman/lib/libcman.pc.in
deleted file mode 100644
index 6084efd..0000000
--- a/cman/lib/libcman.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: libcman
-Version: @VERSION@
-Description: Cluster Manager library
-Requires:
-Libs: -L${libdir} -lcman
-Cflags: -I${includedir}
diff --git a/cman/man/Makefile b/cman/man/Makefile
deleted file mode 100644
index f7fbebf..0000000
--- a/cman/man/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-MANTARGET= \
- cman.5 \
- qdisk.5 \
- cman_tool.8 \
- qdiskd.8 \
- mkqdisk.8 \
- cmannotifyd.8 \
- cman_notify.8 \
- checkquorum.8
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-all:
-
-clean:
diff --git a/cman/man/checkquorum.8 b/cman/man/checkquorum.8
deleted file mode 100644
index 96f61f0..0000000
--- a/cman/man/checkquorum.8
+++ /dev/null
@@ -1,29 +0,0 @@
-.TH "checkquorum" "8" "February 2011" "" "Check Quorum Watchdog Script"
-.SH "NAME"
-checkquorum \- Check Quorum Watchdog Script
-.SH "SYNOPSIS"
-\fBcheckquorum
-.SH "DESCRIPTION"
-.PP
-The \fBcheckquorum\fP watchdog script, when copied to the
-.IR /etc/watchdog.d
-directory and after enabling/starting the watchdog daemon causes the node to reboot if quorum is
-lost and not regained within a user configurable amount of time (default: 60 seconds).
-.SH "OPTIONS"
-The checkquorum script includes several options which can be set by editing
-the script with a text editor.
-.TP
-.BR $wait_time
-Amount of time in seconds to wait after quorum is lost before trigger a reboot
-(Default: 60 seconds).
-.TP
-.BR $hardreboot
-Instantly reboot the machine without cleanly shutting down the system.
-Useful when the machine may hang on reboot. Set to 1 to hard reboot the
-system, 0 to do a normal reboot.
-.SH "NOTES"
-\fBcheckquorum\fP should never be called outside of watchdog except for
-debugging purposes.
-
-.SH "SEE ALSO"
-watchdog(8)
diff --git a/cman/man/cman.5 b/cman/man/cman.5
deleted file mode 100644
index 84c86be..0000000
--- a/cman/man/cman.5
+++ /dev/null
@@ -1,211 +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 <cman> </cman> section of
-\fBcluster.conf\fP. Per-node configuration related to cman is placed
-in the standard <clusternode> </clusternode> sections. All cman
-configuration settings are optional; usually none are used. The <cman>
-section is placed under the <cluster> section in cluster.conf.
-
- <cluster>
- <cman>
- </cman>
- ...
- </cluster>
-.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:
-
- <cman port="6809">
- </cman>
-
-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:
-
- <cman expected_votes="3">
- </cman>
-
-If the cluster becomes partitioned, improper use of this option can result
-in more than one partition gaining quorum. In that event, nodes in each
-partition will enable cluster services.
-.in -7
-
-
-\fITwo node clusters\fR
-.in +7
-Ordinarily, the loss of quorum after one out of two nodes fails will prevent
-the remaining node from continuing (if both nodes have one vote.) Special
-configuration options can be set to allow the one remaining node to continue
-operating if the other fails. To do this only two nodes, each with one vote,
-can be defined in cluster.conf. The two_node and expected_votes values must
-then be set to 1 in the cman section as follows.
-
- <cman two_node="1" expected_votes="1">
- </cman>
-.in -7
-
-
-\fINode votes\fR
-.in +7
-By default, a node is given one vote toward the calculation of quorum.
-This can be changed by giving a node a specific number of votes as
-follows:
-
- <clusternode name="nd1" votes="2">
- </clusternode>
-.in -7
-
-
-\fINode ID\fR
-.in +7
-
-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.
-
- <clusternode name="nd1" nodeid="1">
- </clusternode>
-
-.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 corosync 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/corosync then you MUST tell it
-to use SCTP as it's communications protocol as TCP does not support multihoming.
-
- <clusternode name="nd1" nodeid="1">
- <altname name="nd1a" port="6809" mcast="239.192.0.2"/>
- </clusternode>
-
- <dlm protocol="sctp"/>
-.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:
-
- <cman>
- <multicast addr="239.192.0.1"/>
- </cman>
-
-.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.
-
- <cman cluster_id="669">
- </cman>
-
-.in -7
-
-\fIcorosync security key\fR
-.in +7
-All traffic sent out by cman/corosync 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.
-
- <cman keyfile="/etc/cluster/corosync.key">
- </cman>
-
-Note that this only applies to cluster communication. The DLM does not encrypt
-traffic.
-.in -7
-
-
-\fIOther corosync parameters\fR
-.in +7
-When corosync is started by cman (cman_tool runs corosync), the corosync.conf
-file is not used. Many of the configuration parameters listed in
-corosync.conf can be set in cluster.conf instead. Cman will read
-corosync parameters from the following sections in cluster.conf and load
-them into corosync:
-
- <cluster>
- <totem />
- <event />
- <aisexec />
- <group />
- </cluster>
-
-See the
-.B corosync.conf(5)
-man page for more information on keys that are valid for these sections.
-Note that settings in the <clusternodes> 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 <clusternodes>.
-
-Cman uses different defaults for some of the corosync parameters listed in
-corosync.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:
-
- <totem
- vsftype="none"
- token="10000"
- token_retransmits_before_loss_const="20"
- join="60"
- consensus="4800"
- rrp_mode="none"
- <!-- or rrp_mode="active" if altnames are present >
- />
- <aisexec user="root" group="root" />
-
-Here's how to set the token timeout to five seconds:
-
- <totem token="5000"/>
-
-.in -7
-
-
-.sp
-
-.SH "SEE ALSO"
-
-cluster.conf(5), corosync.conf(5), cman_tool(8)
-
diff --git a/cman/man/cman_notify.8 b/cman/man/cman_notify.8
deleted file mode 100644
index 446bf12..0000000
--- a/cman/man/cman_notify.8
+++ /dev/null
@@ -1,17 +0,0 @@
-.TH "cman_notify" "8" "November 2008" "" "CMAN Notification Daemon"
-.SH "NAME"
-cman_notify \- CMAN Notification Daemon run-part alike script
-.SH "SYNOPSIS"
-\fBcman_notify
-.SH "DESCRIPTION"
-.PP
-The \fBcmannotifyd\fP daemon talks to CMAN and provides a mechanism to notify
-external entities about cluster changes.
-\fBcman_notify\fP script is in charge to execute all notification scripts
-in a run-part alike way.
-.SH "NOTES"
-\fBcman_notify\fP should never be called standalone except for debugging
-purposes.
-
-.SH "SEE ALSO"
-cmannotifyd(8)
diff --git a/cman/man/cman_tool.8 b/cman/man/cman_tool.8
deleted file mode 100644
index d08ccd0..0000000
--- a/cman/man/cman_tool.8
+++ /dev/null
@@ -1,436 +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 the cluster configuration.
-.br
-If -r is specified, cman will read the configuration file,
-validate it, distribute it around the cluster (if necessary) an
-activate it. See the VERSION OPTIONS section below for additional
-options to the \fBversion\fP command.
-
-.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 <seconds>
-If -w is also specified then -t dictates the maximum amount of time cman_tool
-is prepared to wait. If the operation times out then a status of 2 is returned.
-.TP
-.I force
-Shuts down the cluster manager without first telling any of the subsystems
-to close down. Use this option with extreme care as it could easily cause data
-loss.
-.TP
-.I remove
-Tells the rest of the cluster to recalculate quorum such that activity can
-continue without this node.
-
-.SH "EXPECTED" OPTIONS
-.TP
-.I -e <expected-votes>
-The new value of expected votes to use. This will usually be enough
-to bring the cluster back to life. Values that would cause incorrect
-quorum will be rejected.
-
-.SH "KILL" OPTIONS
-.TP
-.I -n <nodename>
-The node name of the node to be killed. This should be the unqualified node
-name as it appears in 'cman_tool nodes'.
-
-.SH "VERSION" OPTIONS
-.TP
-.I -r
-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. The version present in the
-new configuration must be higher than the one currently in use by cman.
-.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 possibly not update immediately after you have run
-cman_tool version -r.
-.TP
-.I -D<option>
-see "JOIN" options
-.TP
-.I -S
-By default cman_tool version will try to distribute the new cluster.conf
-file using ccs_sync and ricci. If you have distributed the file yourself
-and/or do not have ricci installed then the -S option will skip this step.
-NOTE: it is still important that all nodes in the cluster have the
-same version of the file. Make sure that this is the case before using
-this option.
-.SH "WAIT" OPTIONS
-.TP
-.I -q
-Waits until the cluster is quorate before returning.
-.I -t <seconds>
-Dictates the maximum amount of time cman_tool is prepared to wait.
-If the operation times out then a status of 2 is returned.
-
-.br
-.SH "JOIN" OPTIONS
-.TP
-.I -c <clustername>
-Provides a text name for the cluster. You can have several clusters on one
-LAN and they are distinguished by this name. Note that the name is hashed to
-provide a unique number which is what actually distinguishes the cluster, so
-it is possible that two different names can clash. If this happens, the node
-will not be allowed into the existing cluster and you will have to pick
-another name or use different port number for cluster communication.
-.TP
-.I -p <port>
-UDP port number used for cluster communication. This defaults to 5405.
-.TP
-.I -v <votes>
-Number of votes this node has in the cluster. Defaults to 1.
-.TP
-.I -e <expected votes>
-Number of expected votes for the whole cluster. If different nodes
-provide different values then the highest is used. The cluster will
-only operate when quorum is reached - that is more than half the
-available votes are available to the cluster. 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 <nodename>
-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 <nodeid>
-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 <nodename>
-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 <multicast-address>
-Specifies a multicast address to use for cluster communication. This
-is required for IPv6 operation. You should also specify an ethernet
-interface to bind to this multicast address using the -i option.
-.TP
-.I -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 <keyfile>
-All traffic sent out by cman/corosync 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 <seconds>
-If -w or -q is also specified then -t dictates the maximum amount of time cman_tool
-is prepared to wait. If the operation times out then a status of 2 is returned.
-Note that just because cman_tool has given up, does not mean that cman itself
-has stopped trying to join a cluster.
-.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<nodeid>. 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
-corosync-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 xmlconfig (cluster.conf) 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) 'configloader' and 'configpreproc' to the chain start cman with
--C configloader:configpreproc
-.br
-The default value for this is 'xmlconfig'. 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 'openaisserviceenablestable' 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.
-.TP
-.I -D
-Tells cman_tool whether to validate the configuration before loading or reloading it.
-By default the configuration
-.B is
-validated, which is equivalent to -Dfail.
-.br
--Dwarn will validate the configuration and print any messages arising, but will attempt
-to use it regardless of its validity.
-.br
--Dnone (or just -D) will skip the validation completely.
-.br
-The -D switch does not take a space between -D and the parameter. so '-D fail' will cause
-an error. Use -Dfail.
-.SH "NODES" OPTIONS
-.TP
-.I -a
-Shows the IP address(es) the nodes are communicating on.
-.br
-.TP
-.I -n <nodename>
-Shows node information for a specific node. This should be the unqualified node
-name as it appears in 'cman_tool nodes'.
-.br
-.TP
-.I -F <format>
-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<value>
-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 Corosync
-.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 Corosync, 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 corosync.
-.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 corosync 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 corosync. 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 corosync. The first, 'xmlconfig', 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 corosync node name and nodeID
-and formats the information in a similar manner to corosync.conf(5). Corosync 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 xmlconfig, ie when 'cman_tool join' is run with -X switch (this removes xmlconfig 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 corosync 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.
-.br
-Most of the extra keys that cmanpreconfig adds are outside of the /cluster/ tree and will only be seen if you dump the whole of
-corosync's object database. However it does add some keys into /cluster/cman that you would not normally see in a normal cluster.conf
-file. These are harmless, though could be confusing. The most obvious of these is the "nodename" option which is passed from
-cmanpreconfig to the name cman module, to save it recalculating the node name again.
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 938ed69..0000000
--- a/cman/man/qdisk.5
+++ /dev/null
@@ -1,530 +0,0 @@
-.TH "QDisk" "5" "12 Oct 2011" "" "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 must all be 1.
-
-* 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. See section 3.3.1 for specific
-details.
-
-* 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 leave qdisk's vote count unset. 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
-.bi
-(b) that node has made enough consecutive, timely writes
-.in 16
-to the quorum disk, and
-.in 12
-(c) the node has a high enough score to consider itself online.
-.in 0
-
-.SH "3. Configuration"
-.SH "3.1. The <quorumd> tag"
-This tag is a child of the top-level <cluster> tag.
-
-.in 8
-\fB<quorumd\fP
-.in 9
-\fIinterval\fP\fB="\fP1\fB"\fP
-.in 12
-This is the frequency of read/write cycles, in seconds.
-
-.in 9
-\fItko\fP\fB="\fP10\fB"\fP
-.in 12
-This is the number of cycles a node must miss in order to be declared dead.
-The default for this number is dependent on the configured token timeout.
-
-.in 9
-\fItko_up\fP\fB="\fPX\fB"\fP
-.in 12
-This is the number of cycles a node must be seen in order to be declared
-online. Default is \fBfloor(tko/3)\fP.
-
-.in 9
-\fIupgrade_wait\fP\fB="\fP2\fB"\fP
-.in 12
-This is the number of cycles a node must wait before initiating a bid
-for master status after heuristic scoring becomes sufficient. The
-default is 2. This can not be set to 0, and should not exceed \fBtko\fP.
-
-.in 9
-\fImaster_wait\fP\fB="\fPX\fB"\fP
-.in 12
-This is the number of cycles a node must wait for votes before declaring
-itself master after making a bid. Default is \fBfloor(tko/2)\fP.
-This can not be less than 2, must be greater than tko_up, and should not
-exceed \fBtko\fP.
-
-.in 9
-\fIvotes\fP\fB="\fP3\fB"\fP
-.in 12
-This is the number of votes the quorum daemon advertises to CMAN when it
-has a high enough score. The default is the number of nodes in the cluster
-minus 1. For example, in a 4 node cluster, the default is 3. This value
-may change during normal operation, for example when adding or removing
-a node from the cluster.
-
-.in 9
-\fIlog_level\fP\fB="\fP4\fB"\fP
-.in 12
-This controls the verbosity of the quorum daemon in the system logs.
-0 = emergencies; 7 = debug. This option is deprecated.
-
-.in 9
-\fIlog_facility\fP\fB="\fPdaemon\fB"\fP
-.in 12
-This controls the syslog facility used by the quorum daemon when logging.
-For a complete list of available facilities, see \fBsyslog.conf(5)\fP.
-The default value for this is 'daemon'. This option is deprecated.
-
-.in 9
-\fIstatus_file\fP\fB="\fP/foo\fB"\fP
-.in 12
-Write internal states out to this file periodically ("-" = use stdout).
-This is primarily used for debugging. The default value for this
-attribute is undefined. This option can be changed while qdiskd is
-running.
-
-.in 9
-\fImin_score\fP\fB="\fP3\fB"\fP
-.in 12
-Absolute minimum score to be consider one's self "alive". If omitted,
-or set to 0, the default function "floor((n+1)/2)" is used, where \fIn\fP
-is the total of all of defined heuristics' \fIscore\fP attribute. This
-must never exceed the sum of the heuristic scores, or else the quorum
-disk will never be available.
-
-.in 9
-\fIreboot\fP\fB="\fP1\fB"\fP
-.in 12
-If set to 0 (off), qdiskd will *not* reboot after a negative transition
-as a result in a change in score (see section 2.2). The default for
-this value is 1 (on). This option can be changed while qdiskd is
-running.
-
-.in 9
-\fImaster_wins\fP\fB="\fP0\fB"\fP
-.in 12
-If set to 1 (on), only the qdiskd master will advertise its votes
-to CMAN. In a network partition, only the qdisk master will provide
-votes to CMAN. Consequently, that node will automatically "win" in
-a fence race.
-
-This option requires careful tuning of the CMAN timeout, the qdiskd
-timeout, and CMAN's quorum_dev_poll value. As a rule of thumb,
-CMAN's quorum_dev_poll value should be equal to Totem's token timeout
-and qdiskd's timeout (interval*tko) should be less than half of
-Totem's token timeout. See section 3.3.1 for more information.
-
-This option only takes effect if there are no heuristics
-configured and it is valid only for 2 node cluster.
-This option is automatically disabled if heuristics are
-defined or cluster has more than 2 nodes configured.
-
-In a two-node cluster with no heuristics and no defined vote
-count (see above), this mode is turned by default. If enabled in
-this way at startup and a node is later added to the cluster
-configuration or the vote count is set to a value other than 1, this
-mode will be disabled.
-
-.in 9
-\fIallow_kill\fP\fB="\fP1\fB"\fP
-.in 12
-If set to 0 (off), qdiskd will *not* instruct to kill nodes it thinks
-are dead (as a result of not writing to the quorum disk). The default
-for this value is 1 (on). This option can be changed while qdiskd
-is running.
-
-.in 9
-\fIparanoid\fP\fB="\fP0\fB"\fP
-.in 12
-If set to 1 (on), qdiskd will watch internal timers and reboot the node
-if it takes more than (interval * tko) seconds to complete a quorum disk
-pass. The default for this value is 0 (off). This option can be changed
-while qdiskd is running.
-
-.in 9
-\fIio_timeout\fP\fB="\fP0\fB"\fP
-.in 12
-If set to 1 (on), qdiskd will watch internal timers and reboot the node
-if qdisk is not able to write to disk after (interval * tko) seconds.
-The default for this value is 0 (off). If io_timeout is active
-max_error_cycles is overridden and set to off.
-
-.in 9
-\fIscheduler\fP\fB="\fPrr\fB"\fP
-.in 12
-Valid values are 'rr', 'fifo', and 'other'. Selects the scheduling queue
-in the Linux kernel for operation of the main & score threads (does not
-affect the heuristics; they are always run in the 'other' queue). Default
-is 'rr'. See sched_setscheduler(2) for more details.
-
-.in 9
-\fIpriority\fP\fB="\fP1\fB"\fP
-.in 12
-Valid values for 'rr' and 'fifo' are 1..100 inclusive. Valid values
-for 'other' are -20..20 inclusive. Sets the priority of the main & score
-threads. The default value is 1 (in the RR and FIFO queues, higher numbers
-denote higher priority; in OTHER, lower values denote higher priority).
-This option can be changed while qdiskd is running.
-
-.in 9
-\fIstop_cman\fP\fB="\fP0\fB"\fP
-.in 12
-Ordinarily, cluster membership is left up to CMAN, not qdisk.
-If this parameter is set to 1 (on), qdiskd will tell CMAN to leave the
-cluster if it is unable to initialize the quorum disk during startup. This
-can be used to prevent cluster participation by a node which has been
-disconnected from the SAN. The default for this value is 0 (off).
-This option can be changed while qdiskd is running.
-
-.in 9
-\fIuse_uptime\fP\fB="\fP1\fB"\fP
-.in 12
-If this parameter is set to 1 (on), qdiskd will use values from
-/proc/uptime for internal timings. This is a bit less precise
-than \fBgettimeofday(2)\fP, but the benefit is that changing the
-system clock will not affect qdiskd's behavior - even if \fBparanoid\fP
-is enabled. If set to 0, qdiskd will use \fBgettimeofday(2)\fP, which
-is more precise. The default for this value is 1 (on / use uptime).
-
-.in 9
-\fIdevice\fP\fB="\fP/dev/sda1\fB"\fP
-.in 12
-This is the device the quorum daemon will use. This device must be the
-same on all nodes.
-
-.in 9
-\fIlabel\fP\fB="\fPmylabel\fB"\fP
-.in 12
-This overrides the device field if present. If specified, the quorum
-daemon will read /proc/partitions and check for qdisk signatures
-on every block device found, comparing the label against the specified
-label. This is useful in configurations where the block device name
-differs on a per-node basis.
-
-.in 9
-\fIcman_label\fP\fB="\fPmylabel\fB"\fP
-.in 12
-This overrides the label advertised to CMAN if present. If specified,
-the quorum daemon will register with this name instead of the actual
-device name.
-
-.in 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). This option can be changed while
-qdiskd is running. This option is ignored if io_timeout is set to 1.
-
-.in 8
-\fB/>\fP
-.in 0
-
-.SH "3.3.1. Quorum Disk Timings"
-Qdiskd should not be used in environments requiring failure detection
-times of less than approximately 10 seconds.
-
-Qdiskd will attempt to automatically configure timings based on the
-totem timeout and the TKO. If configuring manually, Totem's token
-timeout \fBmust\fP be set to a value at least 1 interval greater than
-the the following function:
-
- interval * (tko + master_wait + upgrade_wait)
-
-So, if you have an interval of 2, a tko of 7, master_wait of 2 and
-upgrade_wait of 2, the token timeout should be at least 24 seconds
-(24000 msec).
-
-It is recommended to have at least 3 intervals to reduce the risk of
-quorum loss during heavy I/O load. As a rule of thumb, using a totem
-timeout more than 2x of qdiskd's timeout will result in good behavior.
-
-An improper timing configuration will cause CMAN to give up on qdiskd,
-causing a temporary loss of quorum during master transition.
-
-.SH "3.2. The <heuristic> tag"
-This tag is a child of the <quorumd> tag. Heuristics may not be changed
-while qdiskd is running.
-
-.in 8
-\fB<heuristic\fP
-.in 9
-\fIprogram\fP\fB="\fP/test.sh\fB"\fP
-.in 12
-This is the program used to determine if this heuristic is alive. This
-can be anything which may be executed by \fI/bin/sh -c\fP. A return
-value of zero indicates success; anything else indicates failure. This
-is required.
-
-.in 9
-\fIscore\fP\fB="\fP1\fB"\fP
-.in 12
-This is the weight of this heuristic. Be careful when determining scores
-for heuristics. The default score for each heuristic is 1.
-
-.in 9
-\fIinterval\fP\fB="\fP2\fB"\fP
-.in 12
-This is the frequency (in seconds) at which we poll the heuristic. The
-default interval is determined by the qdiskd timeout.
-.in 0
-
-.in 9
-\fItko\fP\fB="\fP1\fB"\fP
-.in 12
-After this many failed attempts to run the heuristic, it is considered DOWN,
-and its score is removed. The default tko for each heuristic is determined
-by the qdiskd timeout.
-.in 8
-\fB/>\fP
-.in 0
-
-
-.SH "3.3. Examples"
-.SH "3.3.1. 3 cluster nodes & 3 routers"
-.in 8
-<cman expected_votes="6" .../>
-.br
-<clusternodes>
-.in 12
-<clusternode name="node1" votes="1" ... />
-.br
-<clusternode name="node2" votes="1" ... />
-.br
-<clusternode name="node3" votes="1" ... />
-.in 8
-</clusternodes>
-.br
-<quorumd interval="1" tko="10" votes="3" label="testing">
-.in 12
-<heuristic program="ping A -c1 -w1" score="1" interval="2" tko="3"/>
-.br
-<heuristic program="ping B -c1 -w1" score="1" interval="2" tko="3"/>
-.br
-<heuristic program="ping C -c1 -w1" score="1" interval="2" tko="3"/>
-.br
-.in 8
-</quorumd>
-
-.SH "3.3.2. 2 cluster nodes & 1 IP tiebreaker"
-.in 8
-<cman two_node="0" expected_votes="3" .../>
-.br
-<clusternodes>
-.in 12
-<clusternode name="node1" votes="1" ... />
-.br
-<clusternode name="node2" votes="1" ... />
-.in 8
-</clusternodes>
-.br
-<quorumd interval="1" tko="10" votes="1" label="testing">
-.in 12
-<heuristic program="ping A -c1 -w1" score="1" interval="2" tko="3"/>
-.br
-.in 8
-</quorumd>
-.in 0
-
-
-.SH "3.4. Heuristic score considerations"
-* Heuristic timeouts should be set high enough to allow the previous run
-of a given heuristic to complete.
-
-* Heuristic scripts returning anything except 0 as their return code
-are considered failed.
-
-* The worst-case for improperly configured quorum heuristics is a race
-to fence where two partitions simultaneously try to kill each other.
-
-.SH "3.5. Creating a quorum disk partition"
-The mkqdisk utility can create and list currently configured quorum disks
-visible to the local node; see
-.B mkqdisk(8)
-for more details.
-
-.SH "SEE ALSO"
-mkqdisk(8), qdiskd(8), cman(5), syslog.conf(5), gettimeofday(2)
diff --git a/cman/man/qdiskd.8 b/cman/man/qdiskd.8
deleted file mode 100644
index 21bccbf..0000000
--- a/cman/man/qdiskd.8
+++ /dev/null
@@ -1,25 +0,0 @@
-.TH "qdiskd" "8" "July 2006" "" "Quorum Disk Management"
-.SH "NAME"
-qdiskd \- Cluster Quorum Disk Daemon
-.SH "SYNOPSIS"
-\fBqdiskd [\-f] [\-d]
-.SH "DESCRIPTION"
-.PP
-The \fBqdiskd\fP daemon talks to CMAN and provides a mechanism for determining
-node-fitness in a cluster environment. See
-.B
-qdisk(5)
-for configuration information.
-.SH "OPTIONS"
-.IP "\-f"
-Run in the foreground (do not fork / daemonize).
-.IP "\-d"
-Enable debug output.
-.IP "\-Q"
-Close stdin/out/err immediately before doing validations. This
-is primarily for use when being called from an init script. Using
-this option will stop all output, and can not be used with the -d
-option.
-
-.SH "SEE ALSO"
-mkqdisk(8), qdisk(5), cman(5)
diff --git a/cman/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 a5fe323..0000000
--- a/cman/notifyd/main.c
+++ /dev/null
@@ -1,440 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <limits.h>
-#include <sched.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/select.h>
-
-#include <libcman.h>
-#include <ccs.h>
-#include <liblogthread.h>
-
-#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(void)
-{
- 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;
-
- }
-
- }
-
- if (getenv("CMANNOTIFYD_DEBUG"))
- debug = 1;
-
-}
-
-static void remove_lockfile(void)
-{
- unlink(LOCKFILE_NAME);
-}
-
-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);
- }
-
- atexit(remove_lockfile);
-}
-
-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;
- int syslog_facility = SYSLOGFACILITY;
- int syslog_priority = SYSLOGLEVEL;
- char logfile[PATH_MAX];
- int logfile_priority = SYSLOGLEVEL;
-
- memset(logfile, 0, PATH_MAX);
- sprintf(logfile, LOGDIR "/cmannotifyd.log");
-
- ccs_handle = ccs_connect();
- if (ccs_handle > 0) {
- ccs_read_logging(ccs_handle, "cmannotifyd", &debug, &mode,
- &syslog_facility, &syslog_priority, &logfile_priority, logfile);
- ccs_disconnect(ccs_handle);
- } else {
- if (debug) {
- logfile_priority = LOG_DEBUG;
- }
- }
-
- if (!daemonize)
- mode |= LOG_MODE_OUTPUT_STDERR;
-
- if (!reconf)
- logt_init("cmannotifyd", mode, syslog_facility, syslog_priority, logfile_priority, logfile);
- else
- logt_conf("cmannotifyd", mode, syslog_facility, syslog_priority, logfile_priority, logfile);
-}
-
-static void dispatch_notification(const 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;
- int err = 0;
-
- 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++] = strdup("cman_notify");
-
- argv[argvptr--] = NULL;
-
- switch ( (notify_pid = fork()) )
- {
- case -1:
- /* unable to fork */
- err = 1;
- goto out;
- break;
-
- case 0: /* child */
- execve(SBINDIR "/cman_notify", argv, envp);
- /* unable to execute cman_notify */
- err = 1;
- goto out;
- break;
-
- default: /* parent */
- waitpid(notify_pid, &pidstatus, 0);
- break;
- }
-
-out:
- while(envptr >= 0) {
- if (envp[envptr])
- free(envp[envptr]);
-
- envptr--;
- }
- while(argvptr >= 0) {
- if (argv[argvptr])
- free(argv[argvptr]);
-
- argvptr--;
- }
- if (err)
- exit(EXIT_FAILURE);
-}
-
-static void cman_callback(cman_handle_t ch, void *private, int reason, int arg)
-{
- const 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(void)
-{
- if (!cman_handle)
- return;
-
- cman_finish(cman_handle);
- cman_handle = NULL;
-}
-
-static void setup_cman(int forever)
-{
- int init = 0, active = 0;
- int quorate;
- const char *str = NULL;
-
-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);
- }
-
- logt_print(LOG_DEBUG, "Dispatching first cluster status\n");
- init_logging(1);
- str = "CMAN_REASON_CONFIG_UPDATE";
- dispatch_notification(str, 0);
- str = "CMAN_REASON_STATECHANGE";
- quorate = cman_is_quorate(cman_handle);
- dispatch_notification(str, &quorate);
-
- return;
-
-out:
- byebye_cman();
- exit(EXIT_SUCCESS);
-}
-
-static void loop(void)
-{
- int cd_result, se_result;
- fd_set read_fds;
- int cman_fd;
-
- do {
- FD_ZERO (&read_fds);
- cman_fd = cman_get_fd(cman_handle);
- FD_SET (cman_fd, &read_fds);
- se_result = select((cman_fd + 1), &read_fds, 0, 0, 0);
-
- if (daemon_quit)
- goto out;
-
- if (se_result == -1) {
- logt_print(LOG_CRIT, "Unable to select on cman_fd: %s\n", strerror(errno));
- byebye_cman();
- exit(EXIT_FAILURE);
- }
-
- if (FD_ISSET(cman_fd, &read_fds)) {
- cd_result = 1;
- while (cd_result > 0) {
- cd_result = cman_dispatch(cman_handle, CMAN_DISPATCH_ONE);
- if (cd_result == -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");
- }
- }
- }
- } while (se_result && !daemon_quit);
-
-out:
- logt_print(LOG_DEBUG, "shutting down...\n");
- byebye_cman();
-}
-
-int main(int argc, char **argv)
-{
-
- read_arguments(argc, argv);
- if (daemonize) {
- if (daemon(0, 0) < 0) {
- perror("Unable to daemonize");
- exit(EXIT_FAILURE);
- }
- }
- lockfile();
- 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 e3bb5f7..0000000
--- a/cman/qdisk/Makefile
+++ /dev/null
@@ -1,52 +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 += -I${ccsincdir} -I${cmanincdir} -I${logtincdir}
-CFLAGS += -I${zlibincdir}
-CFLAGS += -I$(S)
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${logtlibdir} -llogthread -lpthread
-LDFLAGS += -L${zliblibdir} -lz -lrt
-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 \
- disk_util.o \
- proc.o \
- scandisk.o \
- iostate.o
-
-${TARGET1}: ${SHAREDOBJS} ${OBJS1}
- $(CC) -o $@ $^ $(EXTRA_LDFLAGS) $(LDFLAGS)
-
-${TARGET2}: ${SHAREDOBJS} ${OBJS2}
- $(CC) -o $@ $^ $(EXTRA_LDFLAGS) $(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/bitmap.c b/cman/qdisk/bitmap.c
deleted file mode 100644
index 094ad2f..0000000
--- a/cman/qdisk/bitmap.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/** @file
- * Bitmap and membership mask handling routines.
- */
-#include <stdint.h>
-
-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);
-
-/**
- * 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/daemon_init.c b/cman/qdisk/daemon_init.c
deleted file mode 100644
index d5926f9..0000000
--- a/cman/qdisk/daemon_init.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/** @file
- * daemon_init function, does sanity checks and calls daemon().
- *
- * Author: Jeff Moyer <jmoyer(a)redhat.com>
- */
-/*
- * TODO: Clean this up so that only one function constructs the
- * pidfile /var/run/loggerd.PID, and perhaps only one function
- * forms the /proc/PID/ path.
- *
- * Also need to add file locking for the pid file.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <sys/mman.h>
-#include <sys/errno.h>
-#include <libgen.h>
-#include <signal.h>
-#include <liblogthread.h>
-
-/*
- * This should ultimately go in a header file.
- */
-void daemon_init(char *prog);
-void daemon_cleanup(void);
-int check_process_running(char *prog, pid_t * pid);
-
-/*
- * Local prototypes.
- */
-static void update_pidfile(char *prog);
-static int setup_sigmask(void);
-static char pid_filename[PATH_MAX];
-
-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;
-
- memset(pid_filename, 0, PATH_MAX);
-
- cmd = basename(prog);
- snprintf(pid_filename, sizeof (pid_filename), "/var/run/%s.pid", cmd);
-
- fp = fopen(pid_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) {
- logt_print(LOG_ERR,
- "daemon_init: Sorry, only root wants to run this.\n");
- exit(1);
- }
-
- if (check_process_running(prog, &pid) && (pid != getpid())) {
- logt_print(LOG_ERR,
- "daemon_init: Process \"%s\" already running.\n",
- prog);
- exit(1);
- }
- if (setup_sigmask() < 0) {
- logt_print(LOG_ERR, "daemon_init: Unable to set signal mask.\n");
- exit(1);
- }
-
- if(daemon(0, 0)) {
- logt_print(LOG_ERR, "daemon_init: Unable to daemonize.\n");
- exit(1);
- }
-
-
- update_pidfile(prog);
-}
-
-
-void
-daemon_cleanup(void)
-{
- if (strlen(pid_filename))
- unlink(pid_filename);
-}
diff --git a/cman/qdisk/disk.c b/cman/qdisk/disk.c
deleted file mode 100644
index 9884ea7..0000000
--- a/cman/qdisk/disk.c
+++ /dev/null
@@ -1,790 +0,0 @@
-/** @file
- * Single-block Raw/Direct I/O Functions
- */
-/*
- * author: Tim Burke <tburke at redhat.com>
- * description: Raw IO Interfaces.
- *
- * The RAW IO code we are using from 2.2.13 requires user buffers and
- * disk offsets to be 512 byte aligned. So this code consists of a
- * read and write routine which check to see if the user buffer is
- * aligned. If it isn't a temporary aligned buffer is allocated, a data
- * copy is performed along with the IO operation itself.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <string.h>
-#include <errno.h>
-#include <disk.h>
-#include <platform.h>
-#include <unistd.h>
-#include <time.h>
-#include <linux/types.h>
-#include <linux/fs.h>
-#include <liblogthread.h>
-#include <zlib.h>
-#include "iostate.h"
-
-static int diskRawRead(target_info_t *disk, char *buf, int len);
-
-/**
- * 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.
- */
-static uint32_t clu_crc32(const char *data, size_t count)
-{
- return (uint32_t)crc32(0L, (const Bytef *)data, (uInt)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 == le_swap32(SHARED_HEADER_MAGIC))
- return;
-
- hdr->h_magic = le_swap32(hdr->h_magic);
- hdr->h_hcrc = le_swap32(hdr->h_hcrc);
- hdr->h_dcrc = le_swap32(hdr->h_dcrc);
- hdr->h_length = le_swap32(hdr->h_length);
- hdr->h_view = le_swap64(hdr->h_view);
- hdr->h_timestamp = le_swap64(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;
-
- hdr->h_magic = le_swap32(hdr->h_magic);
- hdr->h_hcrc = le_swap32(hdr->h_hcrc);
- hdr->h_dcrc = le_swap32(hdr->h_dcrc);
- hdr->h_length = le_swap32(hdr->h_length);
- hdr->h_view = le_swap64(hdr->h_view);
- hdr->h_timestamp = le_swap64(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) {
- logt_print(LOG_ERR, "Invalid CRC32 generated on data!\n");
- return -1;
- }
- }
-
- hdr->h_timestamp = (uint64_t)time(NULL);
- header_encode(hdr);
- hdr->h_hcrc = 0;
- hdr->h_hcrc = le_swap32(clu_crc32((char *)hdr, sizeof(*hdr)));
-
- if (hdr->h_hcrc == 0) {
- logt_print(LOG_ERR, "Invalid CRC32 generated on header!\n");
- return -1;
- }
-
- 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;
-
- /*
- * 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;
-
- /* BUG: Headers are stored in little-endian form */
- bkupcrc = le_swap32(hdr->h_hcrc);
-
- hdr->h_hcrc = 0;
- crc = clu_crc32((char *)hdr, sizeof(*hdr));
- hdr->h_hcrc = bkupcrc;
- if (bkupcrc != crc) {
- logt_print(LOG_DEBUG, "Header CRC32 mismatch; Exp: 0x%08x "
- "Got: 0x%08x\n", bkupcrc, crc);
- return -1;
- }
-
- header_decode(hdr);
-
- /*
- * Verify the magic number.
- */
- if (hdr->h_magic != SHARED_HEADER_MAGIC) {
- logt_print(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) {
- logt_print(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) {
- logt_print(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.*/
- io_state(STATE_LSEEK);
- ret = lseek(disk->d_fd, END_OF_DISK(disk->d_blksz), SEEK_SET);
- io_state(STATE_NONE);
- if (ret < 0) {
- logt_print(LOG_DEBUG, "open_partition: seek");
- close(disk->d_fd);
- return -1;
- }
-
- if (ret < END_OF_DISK(disk->d_blksz)) {
- logt_print(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) {
- logt_print(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) {
- logt_print(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) {
- logt_print(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;
-*/
- logt_print(LOG_WARNING, "Warning: %s is not a block device\n",
- name);
- }
-
- /*
- * Verify read/write permission.
- */
- if (qdisk_open(name, &disk) < 0) {
- logt_print(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;
-
- io_state(STATE_LSEEK);
- ret = lseek(disk->d_fd, readOffset, SEEK_SET);
- io_state(STATE_NONE);
- if (ret != readOffset) {
- logt_print(LOG_DEBUG,
- "diskRawReadShadow: can't seek to offset %d.\n",
- (int) readOffset);
- errno = ENODATA;
- return -1;
- }
-
- ret = diskRawRead(disk, buf, len);
- if (ret != len) {
- logt_print(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);
-
- if (header_verify(hdrp, data, len)) {
- logt_print(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. */
- io_state(STATE_READ);
- readret = read(disk->d_fd, buf, len);
- io_state(STATE_NONE);
- return readret;
- }
-
- if (len > disk->d_blksz) {
- logt_print(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;
- }
-
- io_state(STATE_READ);
- readret = read(disk->d_fd, alignedBuf, readlen);
- io_state(STATE_NONE);
- if (readret > 0) {
- if (readret > len) {
- memcpy(alignedBuf, buf, len);
- readret = len;
- } else {
- memcpy(alignedBuf, buf, readret);
- }
- }
-
- free(alignedBuf);
- if (readret != len) {
- logt_print(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. */
- io_state(STATE_WRITE);
- ret = write(disk->d_fd, buf, len);
- io_state(STATE_NONE);
- return ret;
- }
-
- if (len > disk->d_blksz) {
- logt_print(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) {
- logt_print(LOG_ERR,
- "diskRawWrite: not setup for larger than %d.\n",
- (int)disk->d_blksz);
- return (-1);
- }
-
- memcpy(buf, alignedBuf, len);
- io_state(STATE_WRITE);
- ret = write(disk->d_fd, alignedBuf, writelen);
- io_state(STATE_NONE);
- if (ret > len) {
- ret = len;
- }
-
- free(alignedBuf);
- if (ret != len) {
- logt_print(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)) {
- logt_print(LOG_ERR,
- "diskRawWriteShadow: writeOffset=%08x, "
- "len=%08x.\n", (int)writeOffset, len);
- return (-1);
- }
-
- io_state(STATE_LSEEK);
- retval_seek = lseek(disk->d_fd, writeOffset, SEEK_SET);
- io_state(STATE_NONE);
- if (retval_seek != writeOffset) {
- logt_print(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) {
- logt_print(LOG_ERR, "%s: %s\n", __FUNCTION__,
- strerror(errno));
- }
- logt_print(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 *bufin, int count)
-{
- shared_header_t *hdrp;
- void *ptr;
- char *data;
- size_t total;
- int rv;
- char *buf = (char *)bufin;
-
- /*
- * 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))) {
- logt_print(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) {
- logt_print(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;
- }
-
- /*
- * 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)
- logt_print(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) {
- logt_print(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) {
- logt_print(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) {
- logt_print(LOG_DEBUG, "qdisk_validate: %s\n", strerror(errno));
- return -1;
- }
-
- ret = qdisk_open(partname, &disk);
- if (ret < 0) {
- logt_print(LOG_ERR, "qdisk_open: %s\n", strerror(errno));
- 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 1d8f7c8..0000000
--- a/cman/qdisk/disk.h
+++ /dev/null
@@ -1,298 +0,0 @@
-/**
- @file Main quorum daemon include file
- */
-#ifndef _QUORUM_DISK_H
-#define _QUORUM_DISK_H
-
-#include <stdint.h>
-#include <pthread.h>
-#include <arpa/inet.h>
-#include <libcman.h>
-
-#define MAX_NODES_DISK 16
-#define MEMB_MASK_LEN ((MAX_NODES_DISK / 8) + \
- (!!(MAX_NODES_DISK % 8)))
-#define DISK_MEMB_MASK_LEN ((MEMB_MASK_LEN + 7) & ~7)
-
-/** The membership bitmask type */
-typedef uint8_t memb_mask_t [DISK_MEMB_MASK_LEN];
-
-typedef enum {
- S_NONE = 0x0, // Shutdown / not quorate / not running
- S_EVICT = 0x1, // Voted out / about to be fenced.
- /* ^^^ Fencing OK */
- S_INIT = 0x2, // Initializing. Hold your fire.
- /* vvv Fencing will kill a node */
- S_RUN = 0x5, // I think I'm running.
- S_MASTER= 0x6, // I know I'm running, and have advertised to
- // CMAN the availability of the disk vote for my
- // partition.
- S_EXIT = 0x7 // trigger master re-election before exit
- // status is set only by master in master-win | auto-masterwin
- // and next status _must_ be S_NONE
-} disk_node_state_t;
-
-
-typedef enum {
- M_NONE = 0x0,
- M_BID = 0x1,
- M_ACK = 0x2,
- M_NACK = 0x3,
- M_MASK = 0x4
-} disk_msg_id_t;
-
-
-typedef enum {
- FL_MSG = 0x1,
- FL_BID = 0x2,
- FL_VOTE = 0x4
-} disk_state_flag_t;
-
-
-typedef enum {
- RF_REBOOT = 0x1, /* Reboot if we go from master->none */
- RF_STOP_CMAN = 0x2,
- RF_DEBUG = 0x4,
- RF_PARANOID = 0x8,
- RF_ALLOW_KILL = 0x10,
- RF_UPTIME = 0x20,
- RF_CMAN_LABEL = 0x40,
- RF_IOTIMEOUT = 0x80,
- RF_MASTER_WINS = 0x100,
- RF_AUTO_VOTES = 0x200,
- RF_AUTO_MASTER_WINS = 0x400
-} 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_master; /* Master?! */
- int qc_config;
- int qc_token_timeout;
- int qc_auto_votes;
- disk_node_state_t qc_disk_status;
- disk_node_state_t qc_status;
- run_flag_t qc_flags;
- cman_handle_t qc_cman_admin;
- cman_handle_t qc_cman_user;
- 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;
-
-typedef struct {
- qd_ctx *ctx;
- node_info_t *ni;
- size_t ni_len;
-} qd_priv_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_admin,
- cman_handle_t ch_user, 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 6d6e93e..0000000
--- a/cman/qdisk/disk_util.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/**
- @file Misc. Quorum daemon context utilities / high-level functions
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <string.h>
-#include <errno.h>
-#include <disk.h>
-#include <platform.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <time.h>
-#include <liblogthread.h>
-
-inline void _diff_tv(struct timeval *dest, struct timeval *start, struct timeval *end);
-inline int get_time(struct timeval *tv, int use_uptime);
-
-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) {
- logt_print(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_admin, 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_cman_admin = ch_admin;
- ctx->qc_cman_user = ch;
- ctx->qc_my_id = me;
- ctx->qc_config = 0;
-
- 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/iostate.c b/cman/qdisk/iostate.c
deleted file mode 100644
index 9050276..0000000
--- a/cman/qdisk/iostate.c
+++ /dev/null
@@ -1,154 +0,0 @@
-#include <pthread.h>
-#include <libcman.h>
-#include <iostate.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/time.h>
-#include <liblogthread.h>
-#include <stdint.h>
-#include "platform.h"
-#include "iostate.h"
-#include "../daemon/cnxman-socket.h"
-
-static iostate_t main_state = 0;
-static int main_incarnation = 0;
-static int qdisk_timeout = 0, sleeptime = 0;
-static int thread_active = 0;
-static pthread_t io_nanny_tid = 0;
-static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t state_cond = PTHREAD_COND_INITIALIZER;
-
-struct state_table {
- iostate_t state;
- const char *value;
-};
-
-static struct state_table io_state_table[] = {
-{ STATE_NONE, "none" },
-{ STATE_WRITE, "write" },
-{ STATE_READ, "read" },
-{ STATE_LSEEK, "seek" },
-{ -1, NULL } };
-
-const char *
-state_to_string(iostate_t state)
-{
- static const char *ret = "unknown";
- int i;
-
- for (i=0; io_state_table[i].value; i++) {
- if (io_state_table[i].state == state) {
- ret = io_state_table[i].value;
- break;
- }
- }
-
- return ret;
-}
-
-
-void
-io_state(iostate_t state)
-{
- pthread_mutex_lock(&state_mutex);
- main_state = state;
- main_incarnation++; /* it does not matter if this wraps. */
-
- /* Optimization: Don't signal on STATE_NONE */
- if (state != STATE_NONE)
- pthread_cond_broadcast(&state_cond);
-
- pthread_mutex_unlock(&state_mutex);
-}
-
-
-static void *
-io_nanny_thread(void *arg)
-{
- struct timespec wait_time;
- iostate_t last_main_state = 0, current_main_state = 0;
- int last_main_incarnation = 0, current_main_incarnation = 0;
- int logged_incarnation = 0;
- cman_handle_t ch = (cman_handle_t)arg;
- int32_t whine_state;
-
- /* Start with wherever we're at now */
- pthread_mutex_lock(&state_mutex);
- current_main_state = last_main_state = main_state;
- current_main_incarnation = last_main_incarnation = main_incarnation;
- pthread_mutex_unlock(&state_mutex);
-
- while (thread_active) {
- pthread_mutex_lock(&state_mutex);
- clock_gettime(CLOCK_REALTIME, &wait_time);
- wait_time.tv_sec += sleeptime;
- pthread_cond_timedwait(&state_cond, &state_mutex, &wait_time);
- current_main_state = main_state;
- current_main_incarnation = main_incarnation;
- pthread_mutex_unlock(&state_mutex);
-
- if (!thread_active)
- break;
-
- if (!current_main_state)
- continue;
-
- /* if the state or incarnation changed, the main qdiskd
- * thread is healthy */
- if (current_main_state != last_main_state ||
- current_main_incarnation != last_main_incarnation) {
- last_main_state = current_main_state;
- last_main_incarnation = current_main_incarnation;
- continue;
- }
-
- /* Whine on CMAN api */
- whine_state = (int32_t)current_main_state;
- swab32(whine_state);
- cman_send_data(ch, &whine_state, sizeof(int32_t), 0, CLUSTER_PORT_QDISKD , 0);
-
- /* Don't log things twice */
- if (logged_incarnation == current_main_incarnation)
- continue;
- logged_incarnation = current_main_incarnation;
-
- logt_print(LOG_WARNING, "qdiskd: %s "
- "(system call) has hung for %d seconds\n",
- state_to_string(current_main_state), sleeptime);
- logt_print(LOG_WARNING,
- "In %d more seconds, we will be evicted\n",
- (qdisk_timeout-sleeptime));
- }
-
- return NULL;
-}
-
-
-int
-io_nanny_start(cman_handle_t ch, int timeout)
-{
- int ret;
-
- pthread_mutex_lock(&state_mutex);
-
- sleeptime = timeout / 2;
- qdisk_timeout = timeout;
- thread_active = 1;
-
- ret = pthread_create(&io_nanny_tid, NULL, io_nanny_thread, ch);
- pthread_mutex_unlock(&state_mutex);
-
- return ret;
-}
-
-
-int
-io_nanny_stop(void)
-{
- thread_active = 0;
- pthread_cond_broadcast(&state_cond);
- pthread_join(io_nanny_tid, NULL);
- io_nanny_tid = 0;
-
- return 0;
-}
diff --git a/cman/qdisk/iostate.h b/cman/qdisk/iostate.h
deleted file mode 100644
index a65b1d4..0000000
--- a/cman/qdisk/iostate.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _IOSTATE_H
-#define _IOSTATE_H
-
-typedef enum {
- STATE_NONE = 0,
- STATE_READ = 1,
- STATE_WRITE = 2,
- STATE_LSEEK = 3,
- STATE_UNKNOWN = 4
-} iostate_t;
-
-void io_state(iostate_t state);
-
-int io_nanny_start(cman_handle_t ch, int timeout);
-int io_nanny_stop(void);
-
-const char * state_to_string(iostate_t state);
-
-#endif
diff --git a/cman/qdisk/main.c b/cman/qdisk/main.c
deleted file mode 100644
index 49ea3da..0000000
--- a/cman/qdisk/main.c
+++ /dev/null
@@ -1,2254 +0,0 @@
-/**
- @file Main loop / functions for disk-based quorum daemon.
- */
-#define SYSLOG_NAMES
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <string.h>
-#include <errno.h>
-#include <disk.h>
-#include <platform.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/reboot.h>
-#include <sys/time.h>
-#include <sys/un.h>
-#include <linux/reboot.h>
-#include <sched.h>
-#include <signal.h>
-#include <ccs.h>
-#include <liblogthread.h>
-#include "score.h"
-#include "../daemon/cman.h"
-#include "../daemon/cnxman-socket.h"
-#include <sys/syslog.h>
-
-#define LOG_DAEMON_NAME "qdiskd"
-#define LOG_MODE_DEFAULT LOG_MODE_OUTPUT_SYSLOG|LOG_MODE_OUTPUT_FILE
-#include "iostate.h"
-
-
-/* from main.c */
-void set_priority(int queue, int prio);
-
-/* from daemon_init.c */
-extern int daemon_init(char *);
-extern void daemon_cleanup(void);
-extern int check_process_running(char *, pid_t *);
-
-/* from proc.c */
-extern const 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 */
-extern int clear_bit(uint8_t *mask, uint32_t bitidx, uint32_t masklen);
-extern int set_bit(uint8_t *mask, uint32_t bitidx, uint32_t masklen);
-extern int is_bit_set(uint8_t *mask, uint32_t bitidx, uint32_t masklen);
-
-/* From disk_utils.c */
-extern inline int get_time(struct timeval *tv, int use_uptime);
-extern inline void _diff_tv(struct timeval *dest, struct timeval *start,
- struct timeval *end);
-
-static int _running = 1, _reconfig = 0, _cman_shutdown = 0;
-static int _debug = 0, _foreground = 0;
-
-/* */
-#define DEBUG_CONF 0x1
-#define DEBUG_CMDLINE 0x2
-
-static void update_local_status(qd_ctx *ctx, node_info_t *ni, int max, int score,
- int score_req, int score_max);
-static int get_config_data(qd_ctx *ctx, struct h_data *h, int maxh, int *cfh);
-static int cman_wait(cman_handle_t ch, struct timeval *_tv);
-
-
-static void
-int_handler(int sig)
-{
- _running = 0;
-}
-
-
-static void
-hup_handler(int sig)
-{
- _reconfig = 1;
-}
-
-
-static void
-usr1_handler(int sig)
-{
- if (_debug)
- /* Shut up debug mode */
- _debug = 0;
- else
- _debug = DEBUG_CMDLINE;
-}
-
-
-/**
- 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:
- logt_print(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.
- */
-static 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) {
- logt_print(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) &&
- (ni[x].ni_state != S_EXIT)) {
- if (ni[x].ni_state != S_NONE) {
- /* XXX check for average + allow grace */
- ni[x].ni_misses++;
- if (ni[x].ni_misses > 1) {
- logt_print(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 0: check if master node is about to leave
- */
- if (ni[x].ni_state == S_EXIT) {
- logt_print(LOG_NOTICE, "Node %d is about to leave\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;
- if (mask)
- clear_bit(mask, (ni[x].ni_status.ps_nodeid-1),
- sizeof(memb_mask_t));
- continue;
- }
-
- /*
- 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) {
- logt_print(LOG_NOTICE, "Node %d evicted\n",
- ni[x].ni_status.ps_nodeid);
- } else {
- /* State == S_NONE or incarnation change */
- logt_print(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) {
- logt_print(LOG_DEBUG, "Node %d DOWN\n",
- ni[x].ni_status.ps_nodeid);
- ni[x].ni_seen = 0;
- }
-
- ni[x].ni_state = S_EVICT;
- ni[x].ni_status.ps_state = S_EVICT;
- ni[x].ni_evil_incarnation =
- ni[x].ni_incarnation;
-
- /*
- Write eviction notice if we're the master.
- */
- if (ctx->qc_status == S_MASTER) {
- logt_print(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) {
- logt_print(LOG_DEBUG, "Telling CMAN to "
- "kill the node\n");
- cman_kill_node(ctx->qc_cman_admin,
- ni[x].ni_status.ps_nodeid);
- }
- }
-
- /* Clear our master mask for the node after eviction */
- if (mask)
- clear_bit(mask, (ni[x].ni_status.ps_nodeid-1),
- sizeof(memb_mask_t));
- continue;
- }
-
- /*
- Case 3: Check for node who is supposed to be dead, but
- has started writing to the disk again with the same
- incarnation.
-
- Transition from Offline -> Undead (BAD!!!)
- */
- if (ni[x].ni_evil_incarnation &&
- (ni[x].ni_evil_incarnation ==
- ni[x].ni_status.ps_incarnation) &&
- (ni[x].ni_status.ps_updatenode ==
- ni[x].ni_status.ps_nodeid)) {
- logt_print(LOG_CRIT, "Node %d is undead.\n",
- ni[x].ni_status.ps_nodeid);
-
- logt_print(LOG_ALERT,
- "Writing eviction notice (again) for node %d\n",
- ni[x].ni_status.ps_nodeid);
- qd_write_status(ctx, ni[x].ni_status.ps_nodeid,
- S_EVICT, NULL, NULL, NULL);
- ni[x].ni_status.ps_state = S_EVICT;
-
- /* XXX Need to fence it again */
- if (ctx->qc_flags & RF_ALLOW_KILL) {
- logt_print(LOG_DEBUG, "Telling CMAN to "
- "kill the node\n");
- cman_kill_node(ctx->qc_cman_admin,
- 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;
- logt_print(LOG_DEBUG, "Node %d is UP\n",
- ni[x].ni_status.ps_nodeid);
- ni[x].ni_incarnation =
- ni[x].ni_status.ps_incarnation;
- ni[x].ni_evil_incarnation = 0;
-
- if (mask)
- set_bit(mask, (ni[x].ni_status.ps_nodeid-1),
- sizeof(memb_mask_t));
-
- continue;
- }
-
- /*
- Case 5: Check for a node becoming master. Not really a
- transition.
- */
- if (ni[x].ni_state == S_RUN &&
- ni[x].ni_status.ps_state == S_MASTER) {
- logt_print(LOG_INFO, "Node %d is the master\n",
- ni[x].ni_status.ps_nodeid);
- ni[x].ni_state = S_MASTER;
- if (mask)
- set_bit(mask, (ni[x].ni_status.ps_nodeid-1),
- sizeof(memb_mask_t));
- continue;
- }
-
- /*
- Case 6: Check for a node which has changed its
- incarnation # quickly (e.g. killall -9 qdiskd;
- qdiskd). Not a transition.
- */
- if (state_run(ni[x].ni_state) &&
- ni[x].ni_incarnation != ni[x].ni_status.ps_incarnation) {
-
- logt_print(LOG_DEBUG, "Node %d incarnation # changed\n",
- ni[x].ni_status.ps_nodeid);
- ni[x].ni_incarnation =
- ni[x].ni_status.ps_incarnation;
- ni[x].ni_evil_incarnation = 0;
-
- continue;
- }
-
- /*
- All other cases: Believe the node's reported state
- */
- if (state_run(ni[x].ni_state)) {
- ni[x].ni_state = ni[x].ni_status.ps_state;
- if (mask)
- set_bit(mask, (ni[x].ni_status.ps_nodeid-1),
- sizeof(memb_mask_t));
- }
- }
-}
-
-
-/**
- Checks for presence of an online master. If there is no
- Returns
- */
-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) {
- logt_print(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;
- struct timeval tv;
-
- logt_print(LOG_INFO, "Quorum Daemon Initializing\n");
-
- if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0) {
- logt_print(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) {
- logt_print(LOG_CRIT, "Failed to open %s: %s\n", ctx->qc_device,
- strerror(errno));
- return -1;
- }
-
- logt_print(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 {
- logt_print(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) {
- logt_print(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) {
- logt_print(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);
-
- tv.tv_sec = ctx->qc_interval;
- tv.tv_usec = 0;
- cman_wait(ctx->qc_cman_user, &tv);
- }
-
- if (!_running) {
- return 1;
- }
-
- get_my_score(&score, &maxscore);
- logt_print(LOG_INFO, "Initial score %d/%d\n", score, maxscore);
- if ((ctx->qc_flags & RF_STOP_CMAN) && (score < score_req))
- return -1;
- logt_print(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_cman_admin, 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 int
-register_device(qd_ctx *ctx)
-{
- return cman_register_quorum_device(
- ctx->qc_cman_admin,
- (ctx->qc_flags&RF_CMAN_LABEL) ?
- ctx->qc_cman_label : ctx->qc_device,
- (!(ctx->qc_flags & RF_MASTER_WINS) ||
- ctx->qc_status == S_MASTER) ?
- ctx->qc_votes : 0);
-}
-
-static int
-update_device(qd_ctx *ctx)
-{
- return cman_update_quorum_device(
- ctx->qc_cman_admin,
- (ctx->qc_flags&RF_CMAN_LABEL) ?
- ctx->qc_cman_label : ctx->qc_device,
- (!(ctx->qc_flags & RF_MASTER_WINS) ||
- ctx->qc_status == S_MASTER) ?
- ctx->qc_votes : 0);
-}
-
-static int
-adjust_votes(qd_ctx *ctx)
-{
- if (!(ctx->qc_flags & RF_MASTER_WINS))
- return 0;
-
- return register_device(ctx);
-}
-
-
-static void
-print_node_info(FILE *fp, node_info_t *ni)
-{
- uint64_t incarnation;
-
- fprintf(fp, "node_info_t [node %d] {\n", ni->ni_status.ps_nodeid);
-
- incarnation = be_swap64(ni->ni_incarnation);
- fprintf(fp, " ni_incarnation = 0x%08x%08x\n",
- ((int)(incarnation>>32))&0xffffffff,
- ((int)(incarnation)&0xffffffff));
-
- incarnation = be_swap64(ni->ni_evil_incarnation);
- fprintf(fp, " ni_evil_incarnation = 0x%08x%08x\n",
- ((int)(incarnation>>32))&0xffffffff,
- ((int)(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;
- long flags;
- int fd;
-
- 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;
- }
-
- /* Don't block while writing to this file
- * XXX Not set O_NONBLOCK twice on stdout?
- */
- fd = fileno(fp);
- flags = fcntl(fd, F_GETFD, 0);
- if (fcntl(fd, F_SETFD, flags | O_NONBLOCK) != 0) {
- if (need_close)
- fclose(fp);
- return;
- }
-
- now = time(NULL);
- fprintf(fp, "Time Stamp: %s", ctime(&now));
- fprintf(fp, "Node ID: %d\n", ctx->qc_my_id);
-
- fprintf(fp, "Score: %d/%d (Minimum required = %d)\n",
- score, score_max, score_req);
- fprintf(fp, "Current state: %s\n", state_str(ctx->qc_status));
-
- /*
- fprintf(fp, "Current disk state: %s\n",
- state_str(ctx->qc_disk_status));
- */
- fprintf(fp, "Initializing Set: {");
- for (x=0; x<max; x++) {
- if (ni[x].ni_status.ps_state == S_INIT && ni[x].ni_seen)
- fprintf(fp," %d", ni[x].ni_status.ps_nodeid);
- }
- fprintf(fp, " }\n");
-
- fprintf(fp, "Visible Set: {");
- for (x=0; x<max; x++) {
- if (ni[x].ni_state >= S_RUN || ni[x].ni_status.ps_nodeid ==
- ctx->qc_my_id)
- fprintf(fp," %d", ni[x].ni_status.ps_nodeid);
- }
- fprintf(fp, " }\n");
-
- if (ctx->qc_status == S_INIT)
- goto out;
-
- if (ctx->qc_master)
- fprintf(fp, "Master Node ID: %d\n", ctx->qc_master);
- else
- fprintf(fp, "Master Node ID: (none)\n");
-
- if (!ctx->qc_master)
- goto out;
-
- fprintf(fp, "Quorate Set: {");
- for (x=0; x<max; x++) {
- if (is_bit_set(ni[ctx->qc_master-1].ni_status.ps_master_mask,
- ni[x].ni_status.ps_nodeid-1,
- sizeof(memb_mask_t))) {
- fprintf(fp," %d", ni[x].ni_status.ps_nodeid);
- }
- }
-
- fprintf(fp, " }\n");
-
-out:
- if (ctx->qc_flags & RF_DEBUG) {
- for (x = 0; x < max; x++)
- print_node_info(fp, &ni[x]);
- }
-
- fprintf(fp, "\n");
- if (need_close)
- fclose(fp);
-}
-
-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;
- const 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) {
- logt_print(LOG_WARNING, "set_priority [%s] failed: %s\n", func,
- strerror(errno));
- }
-}
-
-
-static int
-cman_wait(cman_handle_t ch, struct timeval *_tv)
-{
- fd_set rfds;
- int fd = cman_get_fd(ch);
- struct timeval tv_local = {0, 0};
- struct timeval *tv = _tv;
-
- if (!_tv)
- tv = &tv_local;
-
- 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;
-}
-
-
-/*
- Listen for cman events
- */
-static void
-process_cman_event(cman_handle_t handle, void *private, int reason, int arg)
-{
- qd_priv_t *qp = (qd_priv_t *)private;
- qd_ctx *ctx = qp->ctx;
-
- switch(reason) {
- case CMAN_REASON_PORTOPENED:
- break;
- case CMAN_REASON_TRY_SHUTDOWN:
- _running = 0;
- _cman_shutdown = 1;
- break;
- case CMAN_REASON_CONFIG_UPDATE:
- get_config_data(ctx, NULL, 0, NULL);
- break;
- case CMAN_REASON_PORTCLOSED:
- break;
- case CMAN_REASON_STATECHANGE:
- /* Not used */
- break;
- }
-}
-
-
-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, rd_lastok, wr_lastok;
-
- ctx->qc_status = S_NONE;
-
- maxtime.tv_usec = 0;
- maxtime.tv_sec = ctx->qc_interval * ctx->qc_tko;
-
- interval.tv_usec = 0;
- interval.tv_sec = ctx->qc_interval;
-
- rd_lastok.tv_usec = 0;
- rd_lastok.tv_sec = 0;
-
- wr_lastok.tv_usec = 0;
- wr_lastok.tv_sec = 0;
-
- get_my_score(&score, &score_max);
- if (score_max < ctx->qc_scoremin) {
- logt_print(LOG_WARNING, "Minimum score (%d) is impossible to "
- "achieve (heuristic total = %d)\n",
- ctx->qc_scoremin, score_max);
- }
-
- _running = 1;
- while (_running) {
- if (_reconfig) {
- get_config_data(ctx, NULL, 0, NULL);
- _reconfig = 0;
- }
-
- /* XXX this was getuptime() in clumanager */
- get_time(&oldtime, (ctx->qc_flags&RF_UPTIME));
-
- /* Read everyone else's status */
- if ((errors = read_node_blocks(ctx, ni, max)) == 0 )
- get_time(&rd_lastok, ctx->qc_flags&RF_UPTIME);
-
- /* Check for node transitions */
- check_transitions(ctx, ni, max, mask);
-
- /* Check heuristics and remove ourself if necessary */
- get_my_score(&score, &score_max);
-
- /* If we recently upgraded, decrement our wait time */
- if (upgrade > 0)
- --upgrade;
-
- score_req = ctx->qc_scoremin;
- if (score_req <= 0)
- score_req = (score_max/2 + 1);
-
- if (score < score_req) {
- clear_bit(mask, (ctx->qc_my_id-1), sizeof(mask));
- if (ctx->qc_status > S_NONE) {
- logt_print(LOG_NOTICE,
- "Score insufficient for master "
- "operation (%d/%d; required=%d); "
- "downgrading\n",
- score, score_max, score_req);
- ctx->qc_status = S_NONE;
- adjust_votes(ctx);
- msg.m_msg = M_NONE;
- ++msg.m_seq;
- bid_pending = 0;
- if (cman_wait(ctx->qc_cman_user, NULL) < 0) {
- logt_print(LOG_ERR, "cman: %s\n",
- strerror(errno));
- } else {
- cman_poll_quorum_device(ctx->qc_cman_admin, 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) {
- logt_print(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) {
- logt_print(LOG_WARNING, "Master conflict: abdicating\n");
-
- /* Handle just like a recent upgrade */
- ctx->qc_status = S_RUN;
- adjust_votes(ctx);
- 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.
- */
-
- logt_print(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;
-
- logt_print(LOG_INFO,
- "Assuming master role\n");
- ctx->qc_status = S_MASTER;
- adjust_votes(ctx);
- 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. */
-
- logt_print(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_wait(ctx->qc_cman_user, NULL) < 0) {
- logt_print(LOG_ERR, "cman_dispatch: %s\n",
- strerror(errno));
- logt_print(LOG_ERR,
- "Halting qdisk operations\n");
- return -1;
- }
- check_cman(ctx, mask, master_mask);
- if (!errors)
- cman_poll_quorum_device(ctx->qc_cman_admin, 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_wait(ctx->qc_cman_user, NULL) < 0) {
- logt_print(LOG_ERR, "cman_dispatch: %s\n",
- strerror(errno));
- logt_print(LOG_ERR,
- "Halting qdisk operations\n");
- return -1;
- }
- if (!errors) {
- cman_poll_quorum_device(
- ctx->qc_cman_admin,
- 1);
- }
- }
- }
-
- /* Write out our status */
- if (qd_write_status(ctx, ctx->qc_my_id, ctx->qc_status,
- &msg, mask, master_mask) != 0) {
- logt_print(LOG_ERR, "Error writing to quorum disk\n");
- errors++; /* this value isn't really used
- at this point */
- } else {
- get_time(&wr_lastok, ctx->qc_flags&RF_UPTIME);
- }
-
- /* write out our local status */
- update_local_status(ctx, ni, max, score, score_req, score_max);
-
- /* Cycle. We could time the loop and sleep
- (interval-looptime), but this is fine for now.*/
- get_time(&newtime, ctx->qc_flags&RF_UPTIME);
-
- /*
- * Reboot if the last successful hearbeat was longer ago than interval*TKO_COUNT
- */
- _diff_tv(&diff, &wr_lastok, &newtime);
- if (_cmp_tv(&maxtime, &diff) == 1 &&
- ctx->qc_flags & RF_IOTIMEOUT) {
- logt_print(LOG_EMERG, "Failed to send a heartbeat "
- "within %d second%s (%d.%06d) - REBOOTING\n",
- (int)maxtime.tv_sec,
- maxtime.tv_sec==1?"":"s",
- (int)diff.tv_sec,
- (int)diff.tv_usec);
- if (!(ctx->qc_flags & RF_DEBUG))
- reboot(RB_AUTOBOOT);
- }
-
- /*
- * Reboot if the last successful hearbeat was longer ago than interval*TKO_COUNT
- */
- _diff_tv(&diff, &rd_lastok, &newtime);
- if (_cmp_tv(&maxtime, &diff) == 1 &&
- ctx->qc_flags & RF_IOTIMEOUT) {
- logt_print(LOG_EMERG,
- "Failed to read from qdisk within "
- "%d second%s (%d.%06d) - REBOOTING\n",
- (int)maxtime.tv_sec,
- maxtime.tv_sec==1?"":"s",
- (int)diff.tv_sec,
- (int)diff.tv_usec);
- if (!(ctx->qc_flags & RF_DEBUG))
- reboot(RB_AUTOBOOT);
- }
-
- /*
- * Reboot if we didn't send a heartbeat in interval*TKO_COUNT
- */
- _diff_tv(&diff, &oldtime, &newtime);
- if (_cmp_tv(&maxtime, &diff) == 1 &&
- ctx->qc_flags & RF_PARANOID) {
- logt_print(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 {
- logt_print(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) {
- logt_print(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) {
- cman_wait(ctx->qc_cman_user, &sleeptime);
- }
- }
-
- return !!errors;
-}
-
-
-/**
- Tell the other nodes to elect a new master != me.
- */
-static int
-quorum_reelect_master(qd_ctx *ctx, node_info_t *ni, int max)
-{
- if (qd_write_status(ctx, ctx->qc_my_id, S_EXIT,
- NULL, NULL, NULL) != 0) {
- logt_print(LOG_WARNING,
- "Error writing to quorum disk during reelect_master\n");
- }
-
- while (1) {
- int master, x;
- int found = 0;
- int low_id, count;
-
- read_node_blocks(ctx, ni, max);
-
- for (x = 0; x < max; x++) {
- if (ni[x].ni_state >= S_RUN) {
- found = 1;
- }
- }
-
- if (!found) {
- logt_print(LOG_DEBUG, "No other nodes are active. Exiting\n");
- break;
- }
-
- master = master_exists(ctx, ni, max, &low_id, &count);
- if (master) {
- logt_print(LOG_DEBUG, "New master elected: %d\n", master);
- break;
- }
- /*
- * give time for message to be read
- */
- sleep(1);
- }
-
- return 0;
-}
-
-/**
- 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) {
- logt_print(LOG_WARNING,
- "Error writing to quorum disk during logout\n");
- }
- return 0;
-}
-
-
-static void
-conf_logging(int debug, int logmode, int facility, int loglevel,
- int filelevel, char *fname)
-{
- static int _log_config = 0;
-
- if (debug)
- _debug |= DEBUG_CONF;
- else
- _debug &= ~DEBUG_CONF;
- if (_debug)
- loglevel = LOG_DEBUG;
- if (_foreground)
- logmode |= LOG_MODE_OUTPUT_STDERR;
-
- if (!_log_config) {
- logt_init(LOG_DAEMON_NAME, logmode, facility, loglevel,
- filelevel, fname);
- _log_config = 1;
- return;
-
- }
-
- logt_conf(LOG_DAEMON_NAME, logmode, facility, loglevel,
- filelevel, fname);
-}
-
-
-static int
-ccs_read_old_logging(int ccsfd, int *facility, int *priority)
-{
- char query[256];
- char *val;
- int x, ret = 0;
-
- /* Get log log_facility */
- snprintf(query, sizeof(query), "/cluster/quorumd/@log_facility");
- if (ccs_get(ccsfd, query, &val) == 0) {
- logt_print(LOG_WARNING,
- "Use of quorumd/@log_facility is deprecated!\n");
- for (x = 0; facilitynames[x].c_name; x++) {
- if (strcasecmp(val, facilitynames[x].c_name))
- continue;
- *facility = facilitynames[x].c_val;
- ret = 1;
- break;
- }
- free(val);
- }
-
- /* Get log level */
- snprintf(query, sizeof(query), "/cluster/quorumd/@log_level");
- if (ccs_get(ccsfd, query, &val) == 0) {
- logt_print(LOG_WARNING,
- "Use of quorumd/@log_level is deprecated!\n");
- *priority = atoi(val);
- free(val);
- if (*priority < 0)
- *priority = SYSLOGLEVEL;
- else
- ret = 1;
- }
-
- return ret;
-}
-
-
-/**
- Grab logsys configuration data from libccs
- */
-static int
-get_log_config_data(int ccsfd)
-{
- char fname[PATH_MAX];
- int debug = 0, logmode = LOG_MODE_OUTPUT_FILE | LOG_MODE_OUTPUT_SYSLOG;
- int facility = SYSLOGFACILITY;
- int loglevel = SYSLOGLEVEL, filelevel = SYSLOGLEVEL;
- int need_close = 0;
-
- logt_print(LOG_DEBUG, "Loading logging configuration\n");
-
- if (ccsfd < 0) {
- ccsfd = ccs_connect();
- if (ccsfd < 0) {
- logt_print(LOG_ERR, "Logging configuration "
- "unavailable; using defaults\n");
- return -1;
- }
- need_close = 1;
- }
-
- snprintf(fname, sizeof(fname)-1, LOGDIR "/qdiskd.log");
- if (ccs_read_old_logging(ccsfd, &facility, &loglevel))
- filelevel = loglevel;
-
- ccs_read_logging(ccsfd, (char *)"QDISKD", &debug, &logmode,
- &facility, &loglevel, &filelevel, (char *)fname);
- conf_logging(debug, logmode, facility, loglevel, filelevel, fname);
-
- if (need_close)
- ccs_disconnect(ccsfd);
-
- return 0;
-}
-
-
-/*
- * return number of nodes - 1 on success
- * -1 on generic error
- * -2 if one of the node votes is != 1
- */
-static int
-auto_qdisk_votes(int desc)
-{
- int ret = 1;
- char buf[PATH_MAX];
- char *v = NULL, *name = NULL;
-
- while (1) {
- int votes=0;
-
- name = NULL;
- snprintf(buf, sizeof(buf)-1,
- "/cluster/clusternodes/clusternode[%d]/@name", ret);
- if (ccs_get(desc, buf, &name) != 0)
- break;
-
- snprintf(buf, sizeof(buf)-1,
- "/cluster/clusternodes/clusternode[%d]/@votes", ret);
-
- if (ccs_get(desc, buf, &v) == 0) {
- votes = atoi(v);
- free(v);
- v = NULL;
- } else {
- votes = 1;
- }
-
- if (votes != 1) {
-
- logt_print(LOG_ERR, "%s's vote count is %d\n",
- name, votes);
- free(name);
-
- logt_print(LOG_ERR, "Set all node vote counts to 1 "
- "or specify qdiskd's votes\n");
- return -2;
- }
-
- free(name);
- ret++;
- }
-
- // adjust count (one from init and one from the node count)
- ret = ret - 2;
-
- if (ret <= 0)
- logt_print(LOG_ERR, "Unable to determine qdiskd votes "
- "automatically\n");
- else
- logt_print(LOG_DEBUG, "Setting autocalculated votes to %d\n", ret);
-
- return (ret);
-}
-
-
-static int
-get_dynamic_config_data(qd_ctx *ctx, int ccsfd)
-{
- char *val = NULL;
- char query[256];
- int old_votes = 0, found = 0;
-
- if (ccsfd < 0)
- return -1;
-
- logt_print(LOG_DEBUG, "Loading dynamic configuration\n");
-
- /* Check label / device presence. If it disappeared, we need to exit */
- if (ctx->qc_config) {
- val = NULL;
- snprintf(query, sizeof(query), "/cluster/quorumd/@device");
- found = ccs_get(ccsfd, query, &val);
- if (found != 0) {
- val = NULL;
- snprintf(query, sizeof(query), "/cluster/quorumd/@label");
- found = ccs_get(ccsfd, query, &val);
- free(val);
- }
-
- if (found != 0) {
- logt_print(LOG_NOTICE,
- "Quorum device removed from the configuration."
- " Shutting down.\n");
- ctx->qc_votes = 0;
- register_device(ctx);
- _running = 0;
- return -1;
- }
- }
-
- /* Get status file */
- snprintf(query, sizeof(query), "/cluster/quorumd/@status_file");
- if (ccs_get(ccsfd, query, &val) == 0) {
- ctx->qc_status_file = val;
- }
-
- /* 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:
- logt_print(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);
- }
- set_priority(ctx->qc_sched, ctx->qc_sched_prio);
-
- /* 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 flag to see if we're supposed to kill cman if qdisk is not
- * available.
- */
- /* default = off, so, 1 to turn on */
- snprintf(query, sizeof(query), "/cluster/quorumd/@stop_cman");
- if (ccs_get(ccsfd, query, &val) == 0) {
- if (!atoi(val))
- ctx->qc_flags &= ~RF_STOP_CMAN;
- else
- ctx->qc_flags |= RF_STOP_CMAN;
- free(val);
- }
-
- /* default = off, so, 1 to turn on */
- snprintf(query, sizeof(query), "/cluster/quorumd/@io_timeout");
- if (ccs_get(ccsfd, query, &val) == 0) {
- if (!atoi(val))
- ctx->qc_flags &= ~RF_IOTIMEOUT;
- else
- ctx->qc_flags |= RF_IOTIMEOUT;
- free(val);
- }
-
- /*
- * Get flag to see if we're supposed to reboot if we can't complete
- * a pass in failure time
- */
- /* default = off, so, 1 to turn on */
- snprintf(query, sizeof(query), "/cluster/quorumd/@paranoid");
- if (ccs_get(ccsfd, query, &val) == 0) {
- if (!atoi(val))
- ctx->qc_flags &= ~RF_PARANOID;
- else
- ctx->qc_flags |= RF_PARANOID;
- free(val);
- }
-
- /*
- * Get flag to see if we're supposed to reboot if we can't complete
- * a pass in failure time
- */
- /* default = off, so, 1 to turn on */
- snprintf(query, sizeof(query), "/cluster/quorumd/@allow_kill");
- if (ccs_get(ccsfd, query, &val) == 0) {
- if (!atoi(val))
- ctx->qc_flags &= ~RF_ALLOW_KILL;
- else
- ctx->qc_flags |= RF_ALLOW_KILL;
- free(val);
- }
-
- /*
- * How many consecutive error cycles do we allow before
- * giving up?
- *
- * Notice that max_error_cycles is disabled if io_timeout is
- * active.
- */
- /* 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_flags & RF_IOTIMEOUT))
- ctx->qc_max_error_cycles = 0;
- free(val);
- }
-
- /* Get votes */
- if (ctx->qc_config) {
- old_votes = ctx->qc_votes;
- ctx->qc_flags &= ~RF_AUTO_VOTES;
- }
-
- ctx->qc_auto_votes = auto_qdisk_votes(ccsfd);
-
- snprintf(query, sizeof(query), "/cluster/quorumd/@votes");
- if (ccs_get(ccsfd, query, &val) == 0) {
- ctx->qc_votes = atoi(val);
- free(val);
- if (ctx->qc_votes < 0)
- ctx->qc_votes = 0;
- } else {
- ctx->qc_votes = ctx->qc_auto_votes;
- if (ctx->qc_votes < 0) {
- if (ctx->qc_config) {
- logt_print(LOG_WARNING, "Unable to determine "
- "new vote value; retaining old "
- "value of %d\n", old_votes);
- ctx->qc_votes = old_votes;
- } else {
- /* During startup, this is fatal */
- return -1;
- }
- } else {
- ctx->qc_flags |= RF_AUTO_VOTES;
- }
- }
-
- if (ctx->qc_config && old_votes != ctx->qc_votes) {
- logt_print(LOG_DEBUG, "Changing vote count from %d to %d\n",
- old_votes, ctx->qc_votes);
-
- if (ctx->qc_flags & RF_AUTO_MASTER_WINS) {
- logt_print(LOG_DEBUG, "Vote count changed! "
- "Disabling master-wins\n");
- ctx->qc_flags &= ~(RF_MASTER_WINS|RF_AUTO_MASTER_WINS);
- }
-
- /*
- * Here, we are reconfiguring _only_ the votes. The
- * label / cman runflags do not change during reconfiguration
- *
- * This only works after we have already gotten static
- * configuration data during initial startup.
- */
- register_device(ctx);
- }
-
- return 0;
-}
-
-
-static int
-get_static_config_data(qd_ctx *ctx, int ccsfd)
-{
- char *val = NULL;
- char query[256];
- int qdisk_fo;
-
- if (ccsfd < 0)
- return -1;
-
- logt_print(LOG_DEBUG, "Loading static configuration\n");
-
- /* 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;
- }
-
- snprintf(query, sizeof(query), "/cluster/totem/@token");
- if (ccs_get(ccsfd, query, &val) == 0) {
- ctx->qc_token_timeout = atoi(val);
- free(val);
- if (ctx->qc_token_timeout < 10000) {
- logt_print(LOG_ERR, "Token timeout %d is too fast "
- "to use with qdiskd!\n",
- ctx->qc_token_timeout);
- return -1;
- }
- } else {
- ctx->qc_token_timeout = DEFAULT_TOKEN_TIMEOUT;
- }
-
- /* Get tko */
- snprintf(query, sizeof(query), "/cluster/quorumd/@tko");
- if (ccs_get(ccsfd, query, &val) == 0) {
- ctx->qc_tko = atoi(val);
- free(val);
- } else {
- ctx->qc_tko = ((ctx->qc_token_timeout / 1000) -
- ctx->qc_interval) / 2;
- logt_print(LOG_DEBUG, "Auto-configured TKO as %d based on "
- "token=%d interval=%d\n", ctx->qc_tko,
- ctx->qc_token_timeout, ctx->qc_interval);
- }
-
- if (ctx->qc_tko < 4) {
- logt_print(LOG_WARNING, "Quorum disk TKO (%d) is too low!\n",
- ctx->qc_tko);
- }
-
- /* 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;
-
- logt_print(LOG_DEBUG, "Timings: %d tko, %d interval\n",
- ctx->qc_tko, ctx->qc_interval);
- logt_print(LOG_DEBUG, "Timings: %d tko_up, %d master_wait, "
- "%d upgrade_wait\n",
- ctx->qc_tko_up, ctx->qc_master_wait, ctx->qc_upgrade_wait);
-
- qdisk_fo = ctx->qc_interval * (ctx->qc_master_wait +
- ctx->qc_upgrade_wait +
- ctx->qc_tko) * 1000;
- if (qdisk_fo >= ctx->qc_token_timeout) {
- logt_print(LOG_ERR, "Quorum disk timings are too slow for "
- "configured token timeout\n");
- logt_print(LOG_ERR, " * Totem Token timeout: %dms\n",
- ctx->qc_token_timeout);
- logt_print(LOG_ERR, " * Min. Master recovery time: %dms\n",
- qdisk_fo);
- logt_print(LOG_ERR,
- "Please set token timeout to at least %dms\n",
- qdisk_fo + (ctx->qc_interval * 1000));
- return -1;
- }
-
- /* 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;
- /* courtesy info message */
- if (ctx->qc_device)
- logt_print(LOG_INFO, "Quorum Label (%s) will be used to "
- "locate quorum partition, overriding Quorum Device\n",
- ctx->qc_label);
- }
-
- if (!ctx->qc_device && !ctx->qc_label) {
- logt_print(LOG_ERR, "No device or label specified; cannot "
- "run QDisk services.\n");
- return -1;
- }
-
- /* 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 master-wins flag for when we transition -> offline */
- /* default = off, so, 1 to turn on */
- snprintf(query, sizeof(query), "/cluster/quorumd/@master_wins");
- if (ccs_get(ccsfd, query, &val) == 0) {
- if (atoi(val))
- ctx->qc_flags |= RF_MASTER_WINS;
- 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 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);
- }
-
- return 0;
-}
-
-
-/**
- Grab all our configuration data from libccs
- */
-static int
-get_config_data(qd_ctx *ctx, struct h_data *h, int maxh, int *cfh)
-{
- int ccsfd = -1, ret = -1;
-
- ccsfd = ccs_connect();
- if (ccsfd < 0) {
- logt_print(LOG_CRIT, "Configuration unavailable; "
- "cannot start\n");
- return -1;
- }
-
- get_log_config_data(ccsfd);
-
- /* Initialize defaults if we are not reconfiguring */
- if (ctx->qc_config == 0) {
- ctx->qc_interval = 1;
- ctx->qc_tko = 10;
- ctx->qc_scoremin = 0;
- ctx->qc_flags = RF_REBOOT | RF_ALLOW_KILL | RF_UPTIME;
- /* | RF_STOP_CMAN;*/
-
- ctx->qc_sched = SCHED_RR;
- ctx->qc_sched_prio = 1;
- ctx->qc_max_error_cycles = 0;
- }
-
- if (get_dynamic_config_data(ctx, ccsfd) < 0) {
- goto out;
- }
-
- if (ctx->qc_config) {
- ret = 0;
- goto out;
- }
-
- ctx->qc_config = 1;
-
- if (get_static_config_data(ctx, ccsfd) < 0) {
- goto out;
- }
-
- /* Heuristics need to report in 1 cycle before we need to
- * report in so we can get their score.
- */
- *cfh = configure_heuristics(ccsfd, h, maxh,
- ctx->qc_interval * (ctx->qc_tko - 1));
-
- if (ctx->qc_flags & RF_MASTER_WINS) {
- if (*cfh) {
- logt_print(LOG_WARNING, "Master-wins mode disabled "
- "(not compatible with heuristics)\n");
- ctx->qc_flags &= ~RF_MASTER_WINS;
- }
- if (ctx->qc_auto_votes != 1) {
- logt_print(LOG_WARNING, "Master-wins mode disabled "
- "(not compatible with more than 2 nodes)\n");
- ctx->qc_flags &= ~RF_MASTER_WINS;
- }
- } else {
- if (ctx->qc_flags & RF_AUTO_VOTES &&
- !*cfh &&
- ctx->qc_auto_votes == 1) {
- /* Two node cluster, no heuristics, 1 vote for
- * quorum disk daemon. Safe to enable master-wins.
- * In fact, qdiskd without master-wins in this config
- * is a waste of resources.
- */
- ctx->qc_flags |= RF_MASTER_WINS | RF_AUTO_MASTER_WINS;
- logt_print(LOG_INFO, "Enabling master-wins mode for "
- "simple two-node cluster\n");
- }
- }
-
- ret = 0;
-
- logt_print(LOG_DEBUG, "Quorum Daemon: %d heuristics, "
- "%d interval, %d tko, %d votes\n",
- *cfh, ctx->qc_interval, ctx->qc_tko, ctx->qc_votes);
- logt_print(LOG_DEBUG, "Run Flags: %08x\n", ctx->qc_flags);
-out:
- ccs_disconnect(ccsfd);
-
- return ret;
-}
-
-
-static void
-check_stop_cman(qd_ctx *ctx)
-{
- if (!(ctx->qc_flags & RF_STOP_CMAN))
- return;
-
- logt_print(LOG_WARNING, "Telling CMAN to leave the cluster; "
- "qdisk is not available\n");
- if (cman_shutdown(ctx->qc_cman_admin, 0) < 0) {
- logt_print(LOG_CRIT,
- "Could not leave the cluster - rebooting\n");
- sleep(5);
- if (ctx->qc_flags & RF_DEBUG) {
- logt_print(LOG_CRIT, "Debug mode specified! "
- "Reboot averted.\n");
- return;
- }
- reboot(RB_AUTOBOOT);
- }
-}
-
-
-#define logt_print_once(level, fmt, args...) \
-do { static int _logged=0; if (!_logged) { _logged=1; logt_print(level, fmt, ##args); } } while(0)
-
-
-static void
-qdisk_whine(cman_handle_t h, void *privdata, char *buf, int len,
- uint8_t port, int nodeid)
-{
- int32_t dstate;
- qd_priv_t *qp = (qd_priv_t *)privdata;
- node_info_t *ni = qp->ni;
-
- if (len != sizeof(dstate)) {
- return;
- }
-
- dstate = *((int32_t*)buf);
-
- if (nodeid == (qp->ctx->qc_my_id))
- return;
-
- swab32(dstate);
-
- if (dstate) {
- logt_print(LOG_NOTICE, "qdiskd on node %d reports hung %s()\n", nodeid,
- state_to_string(dstate));
- ni[nodeid-1].ni_misses = 0;
- }
-}
-
-
-int
-main(int argc, char **argv)
-{
- cman_node_t me;
- int cfh = 0, rv, nfd = -1, ret = -1, active;
- qd_ctx ctx;
- cman_handle_t ch_admin = NULL;
- cman_handle_t ch_user = NULL;
- node_info_t ni[MAX_NODES_DISK];
- struct h_data h[10];
- char device[128];
- pid_t pid;
- quorum_header_t qh;
- qd_priv_t qp;
-
- 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 = DEBUG_CMDLINE;
- 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_DEBUG"))
- _debug = 1;
-
- if (!_foreground && daemon_init(argv[0]) < 0) {
- fprintf(stderr, "Could not fork: %s\n", strerror(errno));
- goto out;
- }
-
- conf_logging(0, LOG_MODE_OUTPUT_SYSLOG, SYSLOGFACILITY,
- SYSLOGLEVEL, 0, NULL);
-
- while (_running && (ch_admin = cman_admin_init(NULL)) == NULL) {
- logt_print_once(LOG_INFO, "Waiting for CMAN to start\n");
- sleep(1);
- }
-
- while (_running && (active = cman_is_active(ch_admin)) <= 0) {
- logt_print_once(LOG_INFO,
- "Waiting for CMAN to become active\n");
- if (active < 0) {
- logt_print(LOG_CRIT, "cman_is_active: %s\n",
- strerror(errno));
- goto out;
- }
- sleep(1);
- }
-
- if (!_running)
- goto out;
-
- /* For cman notifications we need two sockets - one for events,
- one for config change callbacks */
- qp.ctx = &ctx;
- qp.ni = &ni[0];
- qp.ni_len = MAX_NODES_DISK;
-
- ch_user = cman_init(&qp);
- if (cman_start_notification(ch_user, process_cman_event) != 0) {
- logt_print(LOG_CRIT, "Could not register with CMAN: %s\n",
- strerror(errno));
- goto out;
- }
-
- if (cman_start_recv_data(ch_user, qdisk_whine, CLUSTER_PORT_QDISKD) != 0) {
- logt_print(LOG_CRIT, "Could not register with CMAN: %s\n",
- strerror(errno));
- goto out;
- }
-
- memset(&me, 0, sizeof(me));
- if (cman_get_node(ch_admin, CMAN_NODEID_US, &me) < 0) {
- logt_print(LOG_CRIT, "Could not determine local node ID: %s\n",
- strerror(errno));
- goto out;
- }
-
- qd_init(&ctx, ch_admin, ch_user, me.cn_nodeid);
-
- signal(SIGINT, int_handler);
- signal(SIGTERM, int_handler);
- signal(SIGHUP, hup_handler);
- signal(SIGUSR1, usr1_handler);
-
- /* RF_DEBUG can only be set from the command line */
- if (_debug)
- ctx.qc_flags |= RF_DEBUG;
-
- if (get_config_data(&ctx, h, 10, &cfh) < 0) {
- logt_print(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) {
- logt_print(LOG_CRIT, "Unable to match label"
- " '%s' to any device\n",
- ctx.qc_label);
- check_stop_cman(&ctx);
- goto out;
- } else if (ret > 0) {
- logt_print(LOG_WARNING, "%d matches found for "
- "label '%s'; please use 'device=' "
- "instead!\n", ret, ctx.qc_label);
- }
-
- if (ctx.qc_device)
- free(ctx.qc_device);
- ctx.qc_device = strdup(device);
-
- logt_print(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) {
- logt_print(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) {
- logt_print(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;
- }
- }
-
- ret = quorum_init(&ctx, ni, MAX_NODES_DISK, h, cfh);
- if (ret < 0) {
- logt_print(LOG_CRIT, "Initialization failed\n");
- check_stop_cman(&ctx);
- goto out;
- } else if (ret > 0) {
- /* ret > 0 means we received a shutdown during initialization */
- /* Write our 'clean down' state to disk and get out of here */
- logt_print(LOG_INFO, "Shutdown request received during initialization\n");
- quorum_logout(&ctx);
- goto out;
- }
-
- ret = 0;
-
- if (!_running)
- goto out;
-
- /* This registers the quorum device */
- ret = register_device(&ctx);
- if (ret) {
- if (errno == EBUSY) {
- logt_print(LOG_NOTICE, "quorum device is already registered, updating\n");
- ret = update_device(&ctx);
- if (ret) {
- logt_print(LOG_ERR, "Unable to update quorum device info!\n");
- goto out;
- }
- } else {
- logt_print(LOG_ERR, "Unable to register quorum device!\n");
- goto out;
- }
- }
-
- io_nanny_start(ch_user, ctx.qc_tko * ctx.qc_interval);
-
- if (quorum_loop(&ctx, ni, MAX_NODES_DISK) == 0) {
- /*
- * if we are master and we are in master-win mode,
- * request other qdiskd to elect a new one
- */
- if ((ctx.qc_status == S_MASTER) &&
- ((ctx.qc_flags & RF_MASTER_WINS) ||
- (ctx.qc_flags & RF_AUTO_MASTER_WINS))) {
- quorum_reelect_master(&ctx, ni, MAX_NODES_DISK);
- }
- /* Only clean up if we're exiting w/o error) */
- logt_print(LOG_NOTICE, "Unregistering quorum device.\n");
- cman_unregister_quorum_device(ctx.qc_cman_admin);
- quorum_logout(&ctx);
- }
-
- io_nanny_stop();
-
-out:
- /* free cman handle to avoid leak in cman */
- cman_finish(ch_admin);
- if (_cman_shutdown) {
- cman_replyto_shutdown(ch_user, 1);
- cman_finish(ch_user);
- }
- qd_destroy(&ctx);
- logt_exit();
- daemon_cleanup();
- return ret;
-}
-
diff --git a/cman/qdisk/mkqdisk.c b/cman/qdisk/mkqdisk.c
deleted file mode 100644
index 6d64ee5..0000000
--- a/cman/qdisk/mkqdisk.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- @file Quorum disk utility
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <disk.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <platform.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <liblogthread.h>
-
-#define PROGRAM_NAME "mkqdisk"
-
-int
-main(int argc, char **argv)
-{
- char device[128];
- char *newdev = NULL, *newlabel = NULL;
- int rv, flg = 0, verbose_level = 1;
-
- printf(PROGRAM_NAME " 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;
- if (verbose_level > LOG_DEBUG)
- verbose_level = LOG_DEBUG;
- break;
- }
- }
-
- logt_init(PROGRAM_NAME, LOG_MODE_OUTPUT_STDERR,
- verbose_level, verbose_level, verbose_level, NULL);
-
- /* 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 */
- flg = rv;
- break;
- case 'f':
- flg = rv;
- newlabel = optarg;
- break;
- case 'c':
- newdev = optarg;
- break;
- case 'l':
- newlabel = optarg;
- break;
- case 'h':
- printf("usage: mkqdisk -L | -f <label> | -c "
- "<device> -l <label> [-d]\n");
- return 0;
- default:
- break;
- }
- }
-
- /* list */
- if (flg == 'L') {
- return find_partitions(NULL, NULL, 0, verbose_level);
- } else if (flg == 'f') {
- return find_partitions( newlabel, device,
- sizeof(device), verbose_level);
- }
-
- if (!newdev && !newlabel) {
- printf("usage: mkqdisk -L | -f <label> | -c "
- "<device> -l <label>\n");
- return 1;
- }
-
- if (!newdev || !newlabel) {
- printf("Both a device and a label are required\n");
- return 1;
- }
-
- printf("Writing new quorum disk label '%s' to %s.\n",
- newlabel, newdev);
- printf("WARNING: About to destroy all data on %s; proceed [N/y] ? ",
- newdev);
- if (getc(stdin) != 'y') {
- printf("Good thinking.\n");
- return 0;
- }
-
- return qdisk_init(newdev, newlabel);
-}
diff --git a/cman/qdisk/platform.h b/cman/qdisk/platform.h
deleted file mode 100644
index b1dfc64..0000000
--- a/cman/qdisk/platform.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/** @file
- * Defines for byte-swapping
- */
-#ifndef __PLATFORM_H
-#define __PLATFORM_H
-
-#include <endian.h>
-#include <sys/param.h>
-#include <byteswap.h>
-#include <bits/wordsize.h>
-
-/* No swapping on little-endian machines */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define le_swap16(x) (x)
-#define le_swap32(x) (x)
-#define le_swap64(x) (x)
-#else
-#define le_swap16(x) bswap_16(x)
-#define le_swap32(x) bswap_32(x)
-#define le_swap64(x) bswap_64(x)
-#endif
-
-/* No swapping on big-endian machines */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define be_swap16(x) bswap_16(x)
-#define be_swap32(x) bswap_32(x)
-#define be_swap64(x) bswap_64(x)
-#else
-#define be_swap16(x) (x)
-#define be_swap32(x) (x)
-#define be_swap64(x) (x)
-#endif
-
-
-#define swab16(x) x=be_swap16(x)
-#define swab32(x) x=be_swap32(x)
-#define swab64(x) x=be_swap64(x)
-
-
-#endif /* __PLATFORM_H */
diff --git a/cman/qdisk/proc.c b/cman/qdisk/proc.c
deleted file mode 100644
index 688a4d1..0000000
--- a/cman/qdisk/proc.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/**
- @file Quorum disk /proc/partition scanning functions
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <disk.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <platform.h>
-#include <stdlib.h>
-#include <string.h>
-#include <liblogthread.h>
-#include "scandisk.h"
-
-const char *state_str(disk_node_state_t s);
-
-struct device_args {
- char *label;
- struct devnode *devnode;
- int sector_size;
- int flags;
- int count;
- int pad;
-};
-
-int
-check_device(char *device, char *label, quorum_header_t *qh,
- int flags)
-{
- int ret = -1;
- quorum_header_t qh_local;
- target_info_t disk;
-
- if (!qh)
- qh = &qh_local;
-
- ret = qdisk_validate(device);
- if (ret < 0) {
- logt_print(LOG_DEBUG, "qdisk_validate: %s\n", strerror(errno));
- return -1;
- }
-
- ret = qdisk_open(device, &disk);
- if (ret < 0) {
- logt_print(LOG_ERR, "qdisk_open: %s\n", strerror(errno));
- return -1;
- }
-
- ret = -1;
- if (qdisk_read(&disk, OFFSET_HEADER, qh, sizeof(*qh)) == sizeof(*qh)) {
- swab_quorum_header_t(qh);
- if (qh->qh_magic == HEADER_MAGIC_NUMBER) {
- if (!label || !strcmp(qh->qh_cluster, label)) {
- ret = 0;
- }
- }
- }
-
- qh->qh_kernsz = disk.d_blksz;
-
- /* only flag now is 'strict device check'; i.e.,
- "block size recorded must match kernel's reported size" */
- if (flags && qh->qh_version == VERSION_MAGIC_V2 &&
- disk.d_blksz != qh->qh_blksz) {
- ret = -1;
- }
-
- qdisk_close(&disk);
-
- return ret;
-}
-
-
-static void
-filter_devs(struct devnode *node, void *v_args)
-{
- struct device_args *args = (struct device_args *)v_args;
- quorum_header_t qh;
- quorum_header_t *ret_qh = NULL;
- int ret;
-
- if (!node->sysfsattrs.sysfs)
- return;
- if (!node->devpath)
- return;
- if (node->sysfsattrs.holders)
- return;
- /* Qdiskd doesn't work on soft-raid */
- if (node->md > 0)
- return;
-
- ret = check_device(node->devpath->path, args->label, &qh, args->flags);
- if (ret == 0) {
- ret_qh = malloc(sizeof(qh));
- if (!ret_qh)
- return;
- memcpy(ret_qh, &qh, sizeof(qh));
-
- node->filter = (void *)ret_qh;
- if (!args->count) {
- args->devnode = node;
- }
- ++args->count;
- }
-}
-
-
-const char *
-state_str(disk_node_state_t s)
-{
- switch (s) {
- case S_NONE:
- return "None";
- case S_EVICT:
- return "Evicted";
- case S_INIT:
- return "Initializing";
- case S_RUN:
- return "Running";
- case S_MASTER:
- return "Master";
- default:
- return "ILLEGAL";
- }
-}
-
-
-static void
-print_status_block(status_block_t *sb)
-{
- time_t timestamp = (time_t)sb->ps_timestamp;
- uint64_t incarnation = be_swap64(sb->ps_incarnation);
-
- if (sb->ps_state == S_NONE)
- return;
- logt_print(LOG_INFO, "Status block for node %d\n", sb->ps_nodeid);
- logt_print(LOG_INFO, "\tLast updated by node %d\n", sb->ps_updatenode);
- logt_print(LOG_INFO, "\tLast updated on %s", ctime((time_t *)×tamp));
- logt_print(LOG_INFO, "\tState: %s\n", state_str(sb->ps_state));
- logt_print(LOG_INFO, "\tFlags: %04x\n", (be_swap16(sb->ps_flags)));
- logt_print(LOG_INFO, "\tScore: %d/%d\n", sb->ps_score, sb->ps_scoremax);
- logt_print(LOG_INFO, "\tAverage Cycle speed: %d.%06d seconds\n",
- sb->ps_ca_sec, sb->ps_ca_usec);
- logt_print(LOG_INFO, "\tLast Cycle speed: %d.%06d seconds\n",
- sb->ps_lc_sec, sb->ps_lc_usec);
- logt_print(LOG_INFO, "\tIncarnation: %08x%08x\n",
- (int)(incarnation>>32&0xffffffff),
- (int)(incarnation&0xffffffff));
-
-}
-
-
-static void
-read_info(char *dev)
-{
- target_info_t ti;
- int x;
- status_block_t sb;
-
- if (qdisk_open(dev, &ti) < 0) {
- logt_print(LOG_ERR, "Could not read from %s: %s\n",
- dev, strerror(errno));
- return;
- }
-
- for (x = 0; x < MAX_NODES_DISK; x++) {
-
- if (qdisk_read(&ti,
- qdisk_nodeid_offset(x+1, ti.d_blksz),
- &sb, sizeof(sb)) < 0) {
- logt_print(LOG_ERR, "Error reading node ID block %d\n",
- x+1);
- continue;
- }
- swab_status_block_t(&sb);
- print_status_block(&sb);
- }
-
- qdisk_close(&ti);
-}
-
-
-static void
-print_qdisk_info(struct devnode *dn)
-{
- quorum_header_t *qh = (quorum_header_t *)dn->filter;
- struct devpath *dp;
- time_t timestamp = (time_t)qh->qh_timestamp;
-
- for (dp = dn->devpath; dp; dp = dp->next)
- printf("%s:\n", dp->path);
- printf("\tMagic: %08x\n", qh->qh_magic);
- printf("\tLabel: %s\n", qh->qh_cluster);
- printf("\tCreated: %s", ctime(×tamp));
- printf("\tHost: %s\n", qh->qh_updatehost);
- printf("\tKernel Sector Size: %d\n", qh->qh_kernsz);
- if (qh->qh_version == VERSION_MAGIC_V2) {
- printf("\tRecorded Sector Size: %d\n\n", (int)qh->qh_blksz);
- }
-}
-
-int
-find_partitions(const char *label, char *devname, size_t devlen, int print)
-{
- struct devlisthead *dh = NULL;
- struct devnode *dn = NULL;
- struct device_args dargs;
-
- memset(&dargs, 0, sizeof(dargs));
- dargs.label = (char *)label;
- dargs.flags = 1; /* strict device check */
- dargs.devnode = NULL; /* First matching device */
-
- dh = scan_for_dev(NULL, 5, filter_devs, (void *)(&dargs));
- if (!dh)
- goto not_found;
- if (!dargs.devnode)
- goto not_found;
-
- if (dargs.count > 0 && print) {
- for (dn = dh->devnode; dn; dn = dn->next) {
- if (dn->filter == NULL) {
- continue;
- }
-
- print_qdisk_info(dn);
- if (print >= 2) {
- /* Print node stuff */
- read_info(dn->devpath->path);
- }
- }
- }
-
- if (dargs.count >= 1 && label) {
- snprintf(devname, devlen, "%s", dargs.devnode->devpath->path);
- }
-
- for (dn = dh->devnode; dn; dn = dn->next)
- if (dn->filter)
- free(dn->filter);
- free_dev_list(dh);
-
- if (print)
- /* No errors if we're just printing stuff */
- return 0;
-
- if (dargs.count == 1 || !label)
- return 0;
-
- /* more than one match */
- return dargs.count;
-
- not_found:
- if (dh) {
- for (dn = dh->devnode; dn; dn = dn->next)
- if (dn->filter)
- free(dn->filter);
- free_dev_list(dh);
- }
- errno = ENOENT;
- return -1;
-}
diff --git a/cman/qdisk/scandisk.c b/cman/qdisk/scandisk.c
deleted file mode 100644
index 20a77f2..0000000
--- a/cman/qdisk/scandisk.c
+++ /dev/null
@@ -1,764 +0,0 @@
-#include <stdio.h>
-#include <time.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/param.h>
-#include <dirent.h>
-#include <sys/sysmacros.h>
-#include <sys/stat.h>
-
-#include "scandisk.h"
-
-/** search in cache helpers **/
-
-/*
- * match is 0 for exact match
- * 1 to see if the string is contained and return the first match
- */
-
-static struct devnode *find_dev_by_path(struct devnode *startnode, char *path,
- int match)
-{
- struct devnode *nextnode;
- struct devpath *nextpath;
-
- while (startnode) {
- nextnode = startnode->next;
- nextpath = startnode->devpath;
- while (nextpath) {
- if (match) {
- if (strstr(nextpath->path, path))
- return startnode;
- } else {
- if (!strcmp(nextpath->path, path))
- return startnode;
- }
- nextpath = nextpath->next;
- }
- startnode = nextnode;
- }
-
- return 0;
-}
-
-static struct devnode *find_dev_by_majmin(struct devnode *startnode, int maj,
- int min)
-{
- struct devnode *nextnode;
-
- while (startnode) {
- nextnode = startnode->next;
- if ((startnode->maj == maj) && (startnode->min == min))
- return startnode;
- startnode = nextnode;
- }
-
- return 0;
-}
-
-/** free the cache.. this one is easy ;) **/
-
-/* free all the path associated to one node */
-static void flush_dev_list(struct devpath *startpath)
-{
- struct devpath *nextpath;
-
- while (startpath) {
- nextpath = startpath->next;
- free(startpath);
- startpath = nextpath;
- }
-
- return;
-}
-
-/* free all nodes associated with one devlist */
-static void flush_dev_cache(struct devlisthead *devlisthead)
-{
- struct devnode *nextnode, *startnode = devlisthead->devnode;
-
- while (startnode) {
- nextnode = startnode->next;
- flush_dev_list(startnode->devpath);
- free(startnode);
- startnode = nextnode;
- }
-
- return;
-}
-
-/** list object allocation helpers **/
-
-/* our only certain keys in the list are maj and min
- * this function append a devnode obj to devlisthead
- * and set maj and min
- */
-
-static struct devnode *alloc_list_obj(struct devlisthead *devlisthead, int maj,
- int min)
-{
- struct devnode *nextnode;
-
- nextnode = malloc(sizeof(struct devnode));
- if (!nextnode)
- return 0;
-
- memset(nextnode, 0, sizeof(struct devnode));
-
- if (!devlisthead->devnode)
- devlisthead->devnode = nextnode;
- else
- devlisthead->tail->next = nextnode;
-
- devlisthead->tail = nextnode;
-
- nextnode->maj = maj;
- nextnode->min = min;
-
- return nextnode;
-}
-
-/* really annoying but we have no way to know upfront how
- * many paths are linked to a certain maj/min combo.
- * Once we find a device, we know maj/min and this new path.
- * add_path_obj will add the given path to the devnode
- */
-static int add_path_obj(struct devnode *startnode, const char *path)
-{
- struct devpath *nextpath, *startpath;
-
- nextpath = malloc(sizeof(struct devpath));
- if (!nextpath)
- return 0;
-
- memset(nextpath, 0, sizeof(struct devpath));
-
- if (!startnode->devpath) {
- startnode->devpath = startpath = nextpath;
- } else {
- startpath = startnode->devpath;
- while (startpath->next)
- startpath = startpath->next;
-
- /* always append what we find */
- startpath->next = nextpath;
- startpath = nextpath;
- }
-
- strncpy(startpath->path, path, MAXPATHLEN - 1);
-
- return 1;
-}
-
-/* lsdev needs to add blocks in 2 conditions: if we have a real block device
- * or if have a symlink to a block device.
- * this function simply avoid duplicate code around.
- */
-static int add_lsdev_block(struct devlisthead *devlisthead, struct stat *sb,
- const char *path)
-{
- int maj, min;
- struct devnode *startnode;
-
- maj = major(sb->st_rdev);
- min = minor(sb->st_rdev);
-
- startnode = find_dev_by_majmin(devlisthead->devnode, maj, min);
- if (!startnode) {
- startnode = alloc_list_obj(devlisthead, maj, min);
- if (!startnode)
- return 0;
- }
-
- if (!add_path_obj(startnode, path))
- return 0;
-
- return 1;
-}
-
-/* check if it is a device or a symlink to a device */
-static int dev_is_block(struct stat *sb, char *path)
-{
- if (S_ISBLK(sb->st_mode))
- return 1;
-
- if (S_ISLNK(sb->st_mode))
- if (!stat(path, sb))
- if (S_ISBLK(sb->st_mode))
- return 1;
-
- return 0;
-}
-
-/* lsdev does nothing more than ls -lR /dev
- * dives into dirs (skips hidden directories)
- * add block devices
- * parse symlinks
- *
- * ret:
- * 1 on success
- * -1 for generic errors
- * -2 -ENOMEM
- */
-static int lsdev(struct devlisthead *devlisthead, const char *path)
-{
- int i, n, err = 0;
- struct dirent **namelist;
- struct stat sb;
- char newpath[MAXPATHLEN];
-
- i = scandir(path, &namelist, 0, alphasort);
- if (i < 0)
- return -1;
-
- for (n = 0; n < i; n++) {
- if (namelist[n]->d_name[0] != '.') {
- snprintf(newpath, sizeof(newpath), "%s/%s", path,
- namelist[n]->d_name);
-
- if (!lstat(newpath, &sb)) {
- if (S_ISDIR(sb.st_mode))
- err = lsdev(devlisthead, newpath);
- if (err < 0)
- return err;
-
- if (dev_is_block(&sb, newpath))
- if (!add_lsdev_block
- (devlisthead, &sb, newpath) < 0)
- return -2;
- }
- }
- free(namelist[n]);
- }
- free(namelist);
- return 1;
-}
-
-/*
- * scan /proc/partitions and adds info into the list.
- * It's able to add nodes if those are not found in sysfs.
- *
- * ret:
- * 0 if we can't scan
- * -2 -ENOMEM
- * 1 if everything is ok
- */
-
-static int scanprocpart(struct devlisthead *devlisthead)
-{
- char line[4096];
- FILE *fp;
- int minor, major;
- unsigned long long blkcnt;
- char device[128];
- struct devnode *startnode;
- fp = fopen("/proc/partitions", "r");
- if (!fp)
- return 0;
- while (fgets(line, sizeof(line), fp)
- != NULL) {
-
- if (strlen(line) > 128 + (22))
- continue;
- sscanf(line, "%4d %4d %10llu %s",
- &major, &minor, &blkcnt, device);
-
- /* careful here.. if there is no device, we are scanning the
- * first two lines that are not useful to us
- */
- if (!strlen(device))
- continue;
- startnode =
- find_dev_by_majmin(devlisthead->devnode, major, minor);
- if (!startnode) {
- startnode = alloc_list_obj(devlisthead, major, minor);
- if (!startnode)
- return -2;
- }
-
- startnode->procpart = 1;
- strcpy(startnode->procname, device);
- }
-
- fclose(fp);
- return 1;
-}
-
-/* scan /proc/mdstat and adds info to the list. At this point
- * all the devices _must_ be already in the list. We don't add anymore
- * since raids can only be assembled out of existing devices
- *
- * ret:
- * 1 if we could scan
- * 0 otherwise
- */
-static int scanmdstat(struct devlisthead *devlisthead)
-{
- char line[4096];
- FILE *fp;
- char device[16];
- char separator[4];
- char status[16];
- char personality[16];
- char firstdevice[16];
- char devices[4096];
- char *tmp, *next;
- struct devnode *startnode = NULL;
-
- fp = fopen("/proc/mdstat", "r");
- if (!fp)
- return 0;
-
- while (fgets(line, sizeof(line), fp) != NULL) {
-
- /* i like things to be absolutely clean */
- memset(device, 0, sizeof(device));
- memset(separator, 0, sizeof(separator));
- memset(status, 0, sizeof(status));
- memset(personality, 0, sizeof(personality));
- memset(firstdevice, 0, sizeof(firstdevice));
- memset(devices, 0, sizeof(devices));
-
- if (strlen(line) > sizeof(line))
- continue;
-
- /* we only parse stuff that starts with ^md
- * that's supposed to point to raid */
- if (!(line[0] == 'm' && line[1] == 'd'))
- continue;
-
- sscanf(line, "%s %s %s %s %s",
- device, separator, status, personality, firstdevice);
-
- /* scan only raids that are active */
- if (strcmp(status, "active"))
- continue;
-
- /* try to find *mdX and set the device as real raid.
- * if we don't find the device we don't try to set the slaves */
- startnode = find_dev_by_path(devlisthead->devnode, device, 1);
- if (!startnode)
- continue;
-
- startnode->md = 1;
-
- /* trunkate the string from sdaX[Y] to sdaX and
- * copy the whole device string over */
- memset(strstr(firstdevice, "["), 0, 1);
- strcpy(devices, strstr(line, firstdevice));
-
- /* if we don't find any slave (for whatever reason)
- * keep going */
- if (!strlen(devices))
- continue;
-
- tmp = devices;
- while ((tmp) && ((next = strstr(tmp, " ")) || strlen(tmp))) {
-
- memset(strstr(tmp, "["), 0, 1);
-
- startnode =
- find_dev_by_path(devlisthead->devnode, tmp, 1);
- if (startnode)
- startnode->md = 2;
-
- tmp = next;
-
- if (tmp)
- tmp++;
-
- }
- }
-
- fclose(fp);
- return 1;
-}
-
-/* scanmapper parses /proc/devices to identify what maj are associated
- * with device-mapper
- *
- * ret:
- * can't fail for now
- */
-static int scanmapper(struct devlisthead *devlisthead)
-{
- struct devnode *startnode;
- FILE *fp;
- char line[4096];
- char major[4];
- char device[64];
- int maj, start = 0;
-
- fp = fopen("/proc/devices", "r");
- if (!fp)
- return 0;
-
- while (fgets(line, sizeof(line), fp) != NULL) {
- memset(major, 0, sizeof(major));
- memset(device, 0, sizeof(device));
-
- if (strlen(line) > sizeof(line))
- continue;
-
- if (!strncmp(line, "Block devices:", 13)) {
- start = 1;
- continue;
- }
-
- if (!start)
- continue;
-
- sscanf(line, "%s %s", major, device);
-
- if (!strncmp(device, "device-mapper", 13)) {
- maj = atoi(major);
- startnode = devlisthead->devnode;
-
- while (startnode) {
- if (startnode->maj == maj)
- startnode->mapper = 1;
-
- startnode = startnode->next;
- }
-
- }
-
- }
-
- fclose(fp);
- return 1;
-}
-
-/* scan through the list and execute the custom filter for each entry */
-static void run_filter(struct devlisthead *devlisthead,
- devfilter filter, void *filter_args)
-{
- struct devnode *startnode = devlisthead->devnode;
-
- while (startnode) {
- filter(startnode, filter_args);
- startnode = startnode->next;
- }
- return;
-}
-
-/** sysfs helper functions **/
-
-/* /sys/block/sda/dev or /sys/block/sda1/dev exists
- * the device is real and dev contains maj/min info.
- *
- * ret:
- * 1 on success and set maj/min
- * 0 if no file is found
- * -1 if we could not open the file
- */
-static int sysfs_is_dev(char *path, int *maj, int *min)
-{
- char newpath[MAXPATHLEN];
- struct stat sb;
- FILE *f;
- snprintf(newpath, sizeof(newpath), "%s/dev", path);
- if (!lstat(newpath, &sb)) {
- f = fopen(newpath, "r");
- if (f) {
- int err;
-
- err = fscanf(f, "%d:%d", maj, min);
- fclose(f);
- if ((err == EOF) || (err != 2))
- return -1;
-
- return 1;
- } else
- return -1;
- }
- return 0;
-}
-
-/* /sys/block/sda/removable tells us if a device can be ejected
- * from the system or not. This is useful for USB pendrive that are
- * both removable and disks.
- *
- * ret:
- * 1 if is removable
- * 0 if not
- * -1 if we couldn't find the file.
- */
-static int sysfs_is_removable(char *path)
-{
- char newpath[MAXPATHLEN];
- struct stat sb;
- int i = -1;
- FILE *f;
- snprintf(newpath, sizeof(newpath), "%s/removable", path);
- if (!lstat(newpath, &sb)) {
- f = fopen(newpath, "r");
- if (f) {
- int err;
-
- err = fscanf(f, "%d\n", &i);
- fclose(f);
- if ((err == EOF) || (err != 1))
- i = -1;
- }
- }
- return i;
-}
-
-/* we use this function to scan /sys/block/sda{,1}/{holders,slaves}
- * to know in what position of the foodchain this device is.
- * NOTE: a device can have both holders and slaves at the same time!
- * (for example an lvm volume on top of a raid device made of N real disks
- *
- * ret:
- * always return the amount of entries in the dir if successful
- * or any return value from scandir.
- */
-static int sysfs_has_subdirs_entries(char *path, const char *subdir)
-{
- char newpath[MAXPATHLEN];
- struct dirent **namelist;
- struct stat sb;
- int n, i, count = 0;
-
- snprintf(newpath, sizeof(newpath), "%s/%s", path, subdir);
- if (!lstat(newpath, &sb)) {
- if (S_ISDIR(sb.st_mode)) {
- i = scandir(newpath, &namelist, 0, alphasort);
- if (i < 0)
- return i;
- for (n = 0; n < i; n++) {
- if (namelist[n]->d_name[0] != '.')
- count++;
- free(namelist[n]);
- }
- free(namelist);
- }
- }
- return count;
-}
-
-/* this is the best approach so far to make sure a block device
- * is a disk and distinguish it from a cdrom or tape or etc.
- * What we know for sure is that a type 0 is a disk.
- * From an old piece code 0xe is an IDE disk and comes from media.
- * NOTE: we scan also for ../ that while it seems stupid, it will
- * allow to easily mark partitions as real disks.
- * (see for example /sys/block/sda/device/type and
- * /sys/block/sda1/../device/type)
- * TODO: there might be more cases to evaluate.
- *
- * ret:
- * -2 we were not able to open the file
- * -1 no path found
- * 0 we found the path but we have 0 clue on what it is
- * 1 is a disk
- */
-static int sysfs_is_disk(char *path)
-{
- char newpath[MAXPATHLEN];
- struct stat sb;
- int i = -1;
- FILE *f;
-
- snprintf(newpath, sizeof(newpath), "%s/device/type", path);
- if (!lstat(newpath, &sb))
- goto found;
-
- snprintf(newpath, sizeof(newpath), "%s/../device/type", path);
- if (!lstat(newpath, &sb))
- goto found;
-
- snprintf(newpath, sizeof(newpath), "%s/device/media", path);
- if (!lstat(newpath, &sb))
- goto found;
-
- snprintf(newpath, sizeof(newpath), "%s/../device/media", path);
- if (!lstat(newpath, &sb))
- goto found;
-
- snprintf(newpath, sizeof(newpath), "%s/device/devtype", path);
- if (!lstat(newpath, &sb))
- return 1;
-
- snprintf(newpath, sizeof(newpath), "%s/../device/devtype", path);
- if (!lstat(newpath, &sb))
- return 1;
-
- return -1;
-
- found:
- f = fopen(newpath, "r");
- if (f) {
- int err;
-
- err = fscanf(f, "%d\n", &i);
- fclose(f);
-
- if ((err == EOF) || (err != 1))
- return 0;
-
- switch (i) {
- case 0x0: /* scsi type_disk */
- case 0xe: /* found on ide disks from old kernels.. */
- i = 1;
- break;
- default:
- i = 0; /* by default we have no clue */
- break;
- }
- } else
- i = -2;
-
- return i;
-}
-
-/* recursive function that will scan and dive into /sys/block
- * looking for devices and scanning for attributes.
- *
- * ret:
- * 1 on success
- * -1 on generic error
- * -2 -ENOMEM
- */
-static int scansysfs(struct devlisthead *devlisthead, const char *path, int level, int parent_holder)
-{
- struct devnode *startnode;
- int i, n, maj, min, has_holder;
- struct dirent **namelist;
- struct stat sb;
- char newpath[MAXPATHLEN];
-
- i = scandir(path, &namelist, 0, alphasort);
- if (i < 0)
- return -1;
-
- for (n = 0; n < i; n++) {
- if (namelist[n]->d_name[0] != '.') {
- snprintf(newpath, sizeof(newpath),
- "%s/%s", path, namelist[n]->d_name);
-
- if (!lstat(newpath, &sb) && level)
- if (S_ISLNK(sb.st_mode))
- continue;
-
- has_holder = parent_holder;
-
- if (sysfs_is_dev(newpath, &maj, &min) > 0) {
- startnode =
- alloc_list_obj(devlisthead, maj,
- min);
- if (!startnode)
- return -2;
-
- startnode->sysfsattrs.sysfs = 1;
- startnode->sysfsattrs.removable =
- sysfs_is_removable(newpath);
-
- if (!parent_holder)
- has_holder =
- sysfs_has_subdirs_entries(newpath,
- "holders");
-
- startnode->sysfsattrs.holders = has_holder;
-
- startnode->sysfsattrs.slaves =
- sysfs_has_subdirs_entries(newpath,
- "slaves");
- startnode->sysfsattrs.disk =
- sysfs_is_disk(newpath);
- }
-
- if (!stat(newpath, &sb) && !level)
- if (S_ISDIR(sb.st_mode))
- if (scansysfs(devlisthead, newpath, 1, has_holder) < 0)
- return -1;
-
- if (!lstat(newpath, &sb))
- if (S_ISDIR(sb.st_mode))
- if (scansysfs(devlisthead, newpath, 1, has_holder) < 0)
- return -1;
-
- }
- free(namelist[n]);
- }
-
- free(namelist);
- return 1;
-}
-
-/*
- * devlisthead can be null if you are at init time. pass the old one if you are
- * updating or scanning..
- *
- * timeout is used only at init time to set the cache timeout value if default
- * value is not good enough. We might extend its meaning at somepoint.
- * Anything <= 0 means that the cache does not expire.
- */
-
-struct devlisthead *scan_for_dev(struct devlisthead *devlisthead,
- time_t timeout,
- devfilter filter, void *filter_args)
-{
- int res;
- time_t current;
-
- time(¤t);
-
- if (devlisthead) {
- if ((current - devlisthead->cache_timestamp) <
- devlisthead->cache_timeout) {
- return devlisthead;
- }
- } else {
- devlisthead = malloc(sizeof(struct devlisthead));
- if (!devlisthead)
- return NULL;
- memset(devlisthead, 0, sizeof(struct devlisthead));
- if (timeout)
- devlisthead->cache_timeout = timeout;
- else
- devlisthead->cache_timeout = DEVCACHETIMEOUT;
- }
-
- flush_dev_cache(devlisthead);
- devlisthead->cache_timestamp = current;
-
- /* it's important we check those 3 errors and abort in case
- * as it means that we are running out of mem,
- */
- devlisthead->sysfs = res = scansysfs(devlisthead, SYSBLOCKPATH, 0, 0);
- if (res < -1)
- goto emergencyout;
-
- devlisthead->procpart = res = scanprocpart(devlisthead);
- if (res < -1)
- goto emergencyout;
-
- devlisthead->lsdev = res = lsdev(devlisthead, DEVPATH);
- if (res < -1)
- goto emergencyout;
-
- /* from now on we don't alloc mem ourselves but only add info */
- devlisthead->mdstat = scanmdstat(devlisthead);
- devlisthead->mapper = scanmapper(devlisthead);
- if (filter)
- run_filter(devlisthead, filter, filter_args);
-
- return devlisthead;
-
- emergencyout:
- free_dev_list(devlisthead);
- return 0;
-}
-
-/* free everything we used so far */
-
-void free_dev_list(struct devlisthead *devlisthead)
-{
- if (devlisthead) {
- flush_dev_cache(devlisthead);
- free(devlisthead);
- }
- return;
-}
diff --git a/cman/qdisk/scandisk.h b/cman/qdisk/scandisk.h
deleted file mode 100644
index 031de26..0000000
--- a/cman/qdisk/scandisk.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef __SCANDISK_H__
-#define __SCANDISK_H__
-
-#ifndef DEVPATH
-#define DEVPATH "/dev"
-#endif
-
-#ifndef SYSFSPATH
-#define SYSFSPATH "/sys"
-#endif
-
-#ifndef SYSBLOCKPATH
-#define SYSBLOCKPATH SYSFSPATH "/block"
-#endif
-
-#ifndef DEVCACHETIMEOUT
-#define DEVCACHETIMEOUT 30 /* expressed in seconds */
-#endif
-
-/* each entry can be (generally):
- * > 0 on success or good hit
- * 0 on success with no hit
- * < 0 on error
- */
-
-struct sysfsattrs { /* usual 0 | 1 game */
- int sysfs; /* did we find an entry in sysfs at all? */
- int slaves; /* device has slaves */
- int holders; /* device has holders */
- int removable; /* device is removable */
- int disk; /* device is a disk */
-};
-
-/* this structure is required because we don't know upfront how many
- * entries for a certain maj/min will be found in /dev, and so we need
- * to alloc them dynamically.
- */
-struct devpath {
- struct devpath *next;
- char path[MAXPATHLEN];
-};
-
-/* this structure holds all the data for each maj/min found in the system
- * that is a block device
- */
-struct devnode {
- struct devnode *next;
- struct devpath *devpath; /* point to the first path entry */
- int maj; /* device major */
- int min; /* device minor */
- struct sysfsattrs sysfsattrs; /* like the others.. scanning /sys */
- int procpart; /* 0 if the device is not in proc/part or 1 on success. <0 on error */
- char procname[MAXPATHLEN]; /* non-NULL if we find a maj/min match */
- int md; /* 0 nothing to do with raid, 1 is raid,
- * 2 is raid slave - data from /proc/mdstat */
- int mapper; /* 0 nothing, 1 we believe it's a devmap dev */
- void *filter; /* your filter output.. whatever it is */
-};
-
-/* this is what you get after a scan... if you are lucky */
-/* each entry can be 0 if we can't scan or < 0 if there are errors */
-
-struct devlisthead {
- struct devnode *devnode; /* points to the first entry */
- struct devnode *tail; /* last entry (for fast append) */
- time_t cache_timestamp; /* this cache timestamp */
- int cache_timeout; /* for how long this cache is valid */
- int sysfs; /* set to 1 if we were able to scan
- * /sys */
- int procpart; /* set to 1 if we were able to scan
- * /proc/partitions */
- int lsdev; /* set to 1 if we were able to ls /dev */
- int mdstat; /* set to 1 if we were able to scan
- * /proc/mdstat */
- int mapper; /* set to 1 if we were able to run
- * something against mapper */
-};
-
-typedef void (*devfilter) (struct devnode * cur, void *arg);
-
-struct devlisthead *scan_for_dev(struct devlisthead *devlisthead,
- time_t timeout,
- devfilter filter, void *filter_args);
-void free_dev_list(struct devlisthead *devlisthead);
-
-#endif /* __SCANDISK_H__ */
diff --git a/cman/qdisk/score.c b/cman/qdisk/score.c
deleted file mode 100644
index 3ca531f..0000000
--- a/cman/qdisk/score.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/**
- @file Quorum daemon scoring functions + thread.
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <string.h>
-#include <ccs.h>
-#include <liblogthread.h>
-#include <sched.h>
-#include <sys/mman.h>
-#include "disk.h"
-#include "score.h"
-
-static pthread_mutex_t sc_lock = PTHREAD_MUTEX_INITIALIZER;
-static int _score = 0, _maxscore = 0, _score_thread_running = 0;
-static pthread_t score_thread = (pthread_t)0;
-extern void set_priority(int, int);
-
-struct h_arg {
- struct h_data *h;
- int sched_queue;
- int sched_prio;
- int count;
-};
-
-/*
- XXX Messy, but works for now...
- */
-static void
-nullify(void)
-{
- int fd[3];
-
- close(0);
- close(1);
- close(2);
-
- fd[0] = open("/dev/null", O_RDONLY);
- if (fd[0] != 0)
- dup2(fd[0], 0);
- fd[1] = open("/dev/null", O_WRONLY);
- if (fd[1] != 1)
- dup2(fd[1], 1);
- fd[2] = open("/dev/null", O_WRONLY);
- if (fd[2] != 2)
- dup2(fd[2], 2);
-}
-
-
-/**
- Set all signal handlers to default for exec of a script.
- ONLY do this after a fork().
- */
-static void
-restore_signals(void)
-{
- sigset_t set;
- int x;
-
- for (x = 1; x < _NSIG; x++)
- signal(x, SIG_DFL);
-
- sigfillset(&set);
- sigprocmask(SIG_UNBLOCK, &set, NULL);
-}
-
-
-/**
- Spin off a user-defined heuristic
- */
-static int
-fork_heuristic(struct h_data *h, struct timespec *now)
-{
- int pid;
- char *argv[4];
-
- if (h->childpid) {
- errno = EINPROGRESS;
- return -1;
- }
-
- if (now->tv_sec < h->nextrun.tv_sec ||
- ((now->tv_sec == h->nextrun.tv_sec) &&
- (now->tv_nsec < h->nextrun.tv_nsec)))
- return 0;
-
- h->nextrun.tv_sec = now->tv_sec + h->interval;
- h->nextrun.tv_nsec = now->tv_nsec;
-
- h->failtime.tv_sec = now->tv_sec + h->maxtime;
- h->failtime.tv_nsec = now->tv_nsec;
-
- pid = fork();
- if (pid < 0)
- return -1;
-
- if (pid) {
- h->childpid = pid;
- return 0;
- }
-
- /*
- * always use SCHED_OTHER for the child processes
- * nice -1 is fine; but we don't know what the child process
- * might do, so leaving it (potentially) in SCHED_RR or SCHED_FIFO
- * is out of the question
- *
- * XXX if you set SCHED_OTHER in the conf file and nice 20, the below
- * will make the heuristics a higher prio than qdiskd. This should be
- * fine in practice, because running qdiskd at nice 20 will cause all
- * sorts of problems on a busy system.
- */
- set_priority(SCHED_OTHER, -1);
- munlockall();
- restore_signals();
-
- argv[0] = strdup("/bin/sh");
- argv[1] = strdup("-c");
- argv[2] = h->program;
- argv[3] = NULL;
-
- nullify();
-
- execv("/bin/sh", argv);
-
- free(argv[0]);
- free(argv[1]);
-
- logt_print(LOG_ERR, "Execv failed\n");
- return 0;
-}
-
-
-/**
- Total our current score
- */
-static void
-total_score(struct h_data *h, int max, int *score, int *maxscore)
-{
- int x;
-
- *score = 0;
- *maxscore = 0;
-
- /* Allow operation w/o any heuristics */
- if (!max) {
- *score = *maxscore = 1;
- return;
- }
-
- for (x = 0; x < max; x++) {
- *maxscore += h[x].score;
- if (h[x].available)
- *score += h[x].score;
- }
-}
-
-
-/**
- Check for response from a user-defined heuristic / script
- */
-static int
-check_heuristic(struct h_data *h, int block, struct timespec *now)
-{
- int ret;
- int status;
-
- if (h->childpid == 0)
- /* No child to check */
- return 0;
-
- ret = waitpid(h->childpid, &status, block?0:WNOHANG);
- if (!block && ret == 0) {
- /* No children exited */
-
- /* no timeout */
- if (!h->maxtime)
- return 0;
-
- /* If we overran our timeout, the heuristic is dead */
- if (now->tv_sec > h->failtime.tv_sec ||
- (now->tv_sec == h->failtime.tv_sec &&
- now->tv_nsec > h->failtime.tv_nsec)) {
- h->misses = h->tko;
- h->failed = ETIMEDOUT;
- if (h->available) {
- logt_print(LOG_INFO, "Heuristic: '%s' DOWN - "
- "Exceeded timeout of %d seconds\n",
- h->program, h->maxtime);
- h->available = 0;
- }
- }
-
- return 0;
- }
-
- h->childpid = 0;
- if (ret < 0 && errno == ECHILD)
- /* wrong child? */
- goto miss;
-
- /* Timed out previously; this run must be ignored. */
- if (h->failed) {
- h->failed = 0;
- goto miss;
- }
- if (!WIFEXITED(status)) {
- ret = 0;
- goto miss;
- }
- if (WEXITSTATUS(status) != 0) {
- ret = 0;
- goto miss;
- }
-
- /* Returned 0 and was not killed */
- if (!h->available) {
- h->available = 1;
- logt_print(LOG_INFO, "Heuristic: '%s' UP\n", h->program);
- }
- h->misses = 0;
- return 0;
-
-miss:
- if (h->available) {
- h->misses++;
- if (h->misses >= h->tko) {
- logt_print(LOG_INFO,
- "Heuristic: '%s' DOWN (%d/%d)\n",
- h->program, h->misses, h->tko);
- h->available = 0;
- } else {
- logt_print(LOG_DEBUG,
- "Heuristic: '%s' missed (%d/%d)\n",
- h->program, h->misses, h->tko);
- }
- }
-
- return ret;
-}
-
-
-/**
- Kick off all available heuristics
- */
-static int
-fork_heuristics(struct h_data *h, int max)
-{
- struct timespec now;
- int x;
-
- clock_gettime(CLOCK_MONOTONIC, &now);
- for (x = 0; x < max; x++)
- fork_heuristic(&h[x], &now);
- return 0;
-}
-
-
-/**
- Check all available heuristics
- */
-static int
-check_heuristics(struct h_data *h, int max, int block)
-{
- struct timespec now;
- int x;
-
- clock_gettime(CLOCK_MONOTONIC, &now);
- for (x = 0; x < max; x++)
- check_heuristic(&h[x], block, &now);
- return 0;
-}
-
-
-/*
- * absmax should be qdiskd (interval * (tko-1))
- */
-static void
-auto_heuristic_timing(int *interval, int *tko, int absmax)
-{
- if (!interval || ! tko)
- return;
-
- if (absmax < 3)
- return;
-
- if (absmax <= 4) {
- *interval = 1;
- } else if (absmax <= 22) {
- *interval = 2;
- } else if (absmax <= 39) {
- *interval = 3;
- } else if (absmax <= 50) {
- *interval = 4;
- } else {
- *interval = 5;
- }
-
- *tko = absmax / (*interval);
-}
-
-
-/**
- Read configuration data from CCS into the array provided
- */
-int
-configure_heuristics(int ccsfd, struct h_data *h, int max, int maxtime)
-{
- int x = 0;
- char *val;
- char query[128];
-
- if (!h || !max)
- return -1;
-
- do {
- h[x].program = NULL;
- h[x].available = 0;
- h[x].misses = 0;
- auto_heuristic_timing(&h[x].interval, &h[x].tko, maxtime);
- h[x].maxtime = maxtime;
- h[x].score = 1;
- h[x].childpid = 0;
- h[x].nextrun.tv_sec = 0;
- h[x].nextrun.tv_nsec = 0;
- h[x].failtime.tv_sec = 0;
- h[x].failtime.tv_nsec = 0;
-
- /* Get program */
- snprintf(query, sizeof(query),
- "/cluster/quorumd/heuristic[%d]/@program", x+1);
- if (ccs_get(ccsfd, query, &val) != 0)
- /* No more */
- break;
- h[x].program = val;
-
- /* Get score */
- snprintf(query, sizeof(query),
- "/cluster/quorumd/heuristic[%d]/@score", x+1);
- if (ccs_get(ccsfd, query, &val) == 0) {
- h[x].score = atoi(val);
- free(val);
- if (h[x].score <= 0)
- h[x].score = 1;
- }
-
- /* Get query interval */
- snprintf(query, sizeof(query),
- "/cluster/quorumd/heuristic[%d]/@interval", x+1);
- if (ccs_get(ccsfd, query, &val) == 0) {
- h[x].interval = atoi(val);
- free(val);
- if (h[x].interval <= 0)
- h[x].interval = 2;
- }
-
- /* Get tko for this heuristic */
- snprintf(query, sizeof(query),
- "/cluster/quorumd/heuristic[%d]/@tko", x+1);
- if (ccs_get(ccsfd, query, &val) == 0) {
- h[x].tko= atoi(val);
- free(val);
- if (h[x].tko <= 0)
- h[x].tko = 1;
- }
-
- logt_print(LOG_DEBUG,
- "Heuristic: '%s' score=%d interval=%d tko=%d\n",
- h[x].program, h[x].score, h[x].interval, h[x].tko);
-
- } while (++x < max);
-
- logt_print(LOG_DEBUG, "%d heuristics loaded\n", x);
-
- return x;
-}
-
-
-/**
- Return the current score + maxscore to the caller
- */
-int
-get_my_score(int *score, int *maxscore)
-{
- pthread_mutex_lock(&sc_lock);
- *score = _score;
- *maxscore = _maxscore;
- pthread_mutex_unlock(&sc_lock);
-
- return 0;
-}
-
-
-/**
- Call this if no heuristics are set to run in master-wins mode
- */
-int
-fudge_scoring(void)
-{
- pthread_mutex_lock(&sc_lock);
- _score = _maxscore = 1;
- pthread_mutex_unlock(&sc_lock);
-
- return 0;
-}
-
-
-/**
- Loop for the scoring thread.
- */
-static void *
-score_thread_main(void *arg)
-{
- struct h_arg *args = (struct h_arg *)arg;
- int score, maxscore;
-
- set_priority(args->sched_queue, args->sched_prio);
-
- while (_score_thread_running) {
- fork_heuristics(args->h, args->count);
- check_heuristics(args->h, args->count, 0);
- total_score(args->h, args->count, &score, &maxscore);
-
- pthread_mutex_lock(&sc_lock);
- _score = score;
- _maxscore = maxscore;
- pthread_mutex_unlock(&sc_lock);
-
- if (_score_thread_running)
- sleep(1);
- }
-
- free(args->h);
- free(args);
- logt_print(LOG_INFO, "Score thread going away\n");
- return (NULL);
-}
-
-
-/**
- Start the score thread. h is copied into an argument which is
- passed in as the arg parameter in the score thread, so it is safe
- to pass in h if it was allocated on the stack.
- */
-int
-start_score_thread(qd_ctx *ctx, struct h_data *h, int count)
-{
- pthread_attr_t attrs;
- struct h_arg *args;
-
- if (!h || !count)
- return -1;
-
- args = malloc(sizeof(struct h_arg));
- if (!args)
- return -1;
-
- args->h = malloc(sizeof(struct h_data) * count);
- if (!args->h) {
- free(args);
- return -1;
- }
-
- memcpy(args->h, h, (sizeof(struct h_data) * count));
- args->count = count;
- args->sched_queue = ctx->qc_sched;
- args->sched_prio = ctx->qc_sched_prio;
-
- _score_thread_running = 1;
-
- pthread_attr_init(&attrs);
- pthread_attr_setinheritsched(&attrs, PTHREAD_INHERIT_SCHED);
- pthread_create(&score_thread, &attrs, score_thread_main, args);
- pthread_attr_destroy(&attrs);
-
- if (score_thread)
- return 0;
- _score_thread_running = 0;
- return -1;
-}
diff --git a/cman/qdisk/score.h b/cman/qdisk/score.h
deleted file mode 100644
index beff31b..0000000
--- a/cman/qdisk/score.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- @file Quorum daemon scoring functions + thread header file
- */
-#ifndef _SCORE_H
-#define _SCORE_H
-
-#include <time.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-struct h_data {
- char * program;
- struct timespec nextrun;
- struct timespec failtime;
- int score;
- int available;
- int tko;
- int interval;
- int maxtime;
- int misses;
- int failed;
- pid_t childpid;
-};
-
-/*
- Grab score data from CCSD
- */
-int configure_heuristics(int ccsfd, struct h_data *hp, int max, int maxtime);
-
-/*
- Start the thread which runs the scoring applets
- */
-int start_score_thread(qd_ctx *ctx, struct h_data *h, int count);
-
-/*
- Get our score + maxscore
- */
-int get_my_score(int *score, int *maxscore);
-
-/*
- Set score + maxscore to 1. Call if no heuristics are present
- to enable master-wins mode
- */
-int fudge_scoring(void);
-
-
-#endif
diff --git a/cman/scripts/Makefile b/cman/scripts/Makefile
deleted file mode 100644
index f80f7e4..0000000
--- a/cman/scripts/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-SHAREDIRTEX=checkquorum
-SHAREDIRT=checkquorum.wdmd
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-all:
-
-clean: generalclean
diff --git a/cman/scripts/checkquorum b/cman/scripts/checkquorum
deleted file mode 100755
index 61934cd..0000000
--- a/cman/scripts/checkquorum
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/perl -w
-# Quorum detection watchdog script
-#
-# This script will return -2 if the node had quorum at one point
-# and then subsequently lost it
-#
-# Copyright 2011 Red Hat, Inc.
-
-# Amount of time in seconds to wait after quorum is lost to fail script
-$wait_time = 60;
-
-# Hard Reboot the system (doesn't cleanly shut down the system)
-$hardreboot = 0;
-
-# Location of temporary file to capture timeouts
-$timerfile = "/var/run/cluster/checkquorum-timer";
-
-# Enable debug messages (0 to disable, 1 to enable)
-$debugval = 0;
-
-# If command is called attempting to 'repair' we automatically fail
-if (($#ARGV != -1) && ($ARGV[0] eq "repair")) {
- debug ("Failing on repair\n");
- exit 1;
-}
-
-if (!quorum()) {
- if (has_quorum_already_been_formed()) {
- debug("Quorum has already existed, node can be rebooted!\n");
- if (-e $timerfile) {
- $tf = open (FILE, "$timerfile");
- $time = <FILE>;
- close (FILE);
- $timediff = time() - $time;
- if ($timediff >= $wait_time) {
- reboot()
- } else {
- $remaining = $wait_time - $timediff;
- debug("Time has not exceeded wait time ($remaining seconds remaining).\n");
- }
- } else {
- debug("Creating timer file...\n");
- $tf = open (FILE, ">$timerfile");
- print FILE time();
- close (FILE);
- }
- } else {
- debug("This is a new startup no reboot will occur.\n");
- `rm -f $timerfile`;
- }
-} else {
- debug("Quorum exists, no reboot should occur.\n");
- `rm -f $timerfile`;
-}
-
-sub has_quorum_already_been_formed {
- $oe = `corosync-objctl 2>&1 | grep -E "runtime.totem.pg.mrp.srp.operational_entered|Could not initialize objdb library|Cannot connect to quorum service" `;
- if ($oe =~ /^Could not/ || $oe =~ /^Cannot/) {
- debug("corosync is not running\n");
- exit 0;
- }
- $oe =~ s/.*=//;
- if ($oe > 1) {
- return 1;
- } else {
- return 0;
- }
-}
-
-sub quorum {
- $cq = `corosync-quorumtool -s 2>&1 | grep -E "Quorate:|Cannot connect to quorum service"`;
- if ($cq =~ /Cannot connect to quorum service/) {
- debug("corosync is not running\n");
- exit 0;
- }
- $cq =~ s/Quorate: *//;
- chomp ($cq);
- return 1 if ($cq eq "Yes");
- return 0;
-}
-
-sub reboot {
- debug("Reboot commencing...\n");
- `rm -f $timerfile`;
- if ($hardreboot == 1) {
- `echo 1 > /proc/sys/kernel/sysrq`;
- `echo b > /proc/sysrq-trigger`;
- }
- exit -2;
-}
-
-sub debug {
- $out = pop(@_);
- if ($debugval) {
- print $out;
- }
-}
diff --git a/cman/scripts/checkquorum.wdmd b/cman/scripts/checkquorum.wdmd
deleted file mode 100644
index 1d81ff6..0000000
--- a/cman/scripts/checkquorum.wdmd
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/bin/bash
-# Quorum detection watchdog script
-#
-# This script will return -2 if the node had quorum at one point
-# and then subsequently lost it
-#
-# Copyright 2012 Red Hat, Inc.
-
-# defaults
-
-# Amount of time in seconds to wait after quorum is lost to fail script
-waittime=60
-
-# action to take if quorum is missing for over > waittime
-# autodetect|hardreboot|crashdump|watchdog
-action=autodetect
-
-# Location of temporary file to capture timeouts
-timerfile="/var/run/cluster/checkquorum-timer"
-
-# rpm based distros
-[ -d /etc/sysconfig ] && \
- [ -f /etc/sysconfig/checkquorum ] && \
- . /etc/sysconfig/checkquorum
-
-# deb based distros
-[ ! -d /etc/sysconfig ] && \
- [ -f /etc/default/checkquorum ] && \
- . /etc/default/checkquorum
-
-has_quorum() {
- corosync-quorumtool -s 2>/dev/null | \
- grep ^Quorate: | \
- grep -q Yes$
-}
-
-had_quorum() {
- output="$(corosync-objctl 2>/dev/null | \
- grep runtime.totem.pg.mrp.srp.operational_entered | cut -d "=" -f 2)"
- [ -n "$output" ] && {
- [ "$output" -ge 1 ] && return 0
- return 1
- }
-}
-
-take_action() {
- case "$action" in
- watchdog)
- [ -n "$wdmd_action" ] && return 1
- ;;
- hardreboot)
- echo 1 > /proc/sys/kernel/sysrq
- echo b > /proc/sysrq-trigger
- ;;
- crashdump)
- echo 1 > /proc/sys/kernel/sysrq
- echo c > /proc/sysrq-trigger
- ;;
- autodetect)
- service kdump status > /dev/null 2>&1
- usekexec="$?"
- [ -n "$wdmd_action" ] && [ "$usekexec" != "0" ] && return 1
- echo 1 > /proc/sys/kernel/sysrq
- [ "$usekexec" = "0" ] && echo c > /proc/sysrq-trigger
- echo b > /proc/sysrq-trigger
- esac
-}
-
-# watchdog uses $1 = test or = repair
-# with no arguments we are called by wdmd
-[ -z "$1" ] && wdmd_action=yes
-
-# we don't support watchdog repair action
-[ "$1" = "repair" ] && exit 1
-
-service corosync status > /dev/null 2>&1
-ret=$?
-
-case "$ret" in
- 3) # corosync is not running (clean)
- rm -f "$timerfile"
- exit 0
- ;;
- 1) # corosync crashed or did exit abonormally (dirty - take action)
- logger -t checkquorum.wdmd "corosync crashed or exited abonarmally. Node will soon reboot"
- take_action
- ;;
- 0) # corosync is running (clean)
- # check quorum here
- has_quorum && {
- echo -e "oldtime=$(date +%s)" > "$timerfile"
- exit 0
- }
- . "$timerfile"
- newtime="$(date +%s)"
- delta=$((newtime - oldtime))
- logger -t checkquorum.wdmd "Node has lost quorum. Node will soon reboot"
- had_quorum && [ "$delta" -gt "$waittime" ] && {
- take_action
- }
- ;;
-esac
-
-exit $?
diff --git a/cman/tests/Makefile b/cman/tests/Makefile
deleted file mode 100644
index eb800c1..0000000
--- a/cman/tests/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-TARGETS= client libtest sysman sysmand
-
-all: depends ${TARGETS}
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-
-CFLAGS += -I${cmanincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${cmanlibdir} -lcman
-LDFLAGS += -L${libdir}
-
-depends:
- $(MAKE) -C ../lib all
-
-%: %.o
- $(CC) -o $@ $^ $(LDFLAGS)
-
-install:
-
-clean: generalclean
diff --git a/cman/tests/client.c b/cman/tests/client.c
deleted file mode 100644
index ff74816..0000000
--- a/cman/tests/client.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* test client */
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <sys/utsname.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "libcman.h"
-
-static cman_handle_t handle;
-static void get_members(void);
-
-static void event_callback(cman_handle_t handle, void *private, int reason, int arg)
-{
- get_members();
-}
-
-
-static void data_callback(cman_handle_t handle, void *private,
- char *buf, int len, uint8_t port, int nodeid)
-{
- printf("Received from node %d port %d: '%s'\n", nodeid, port, buf);
-}
-
-
-int main(int argc, char *argv[])
-{
-
- unsigned char port = 100;
- char message[256];
- struct utsname ubuf;
-
- if (argc >= 2)
- port = atoi(argv[1]);
-
- if (argc >= 3)
- strcpy(message, argv[2]);
-
- printf("Cluster port number is %d\n", port);
- uname(&ubuf);
- sprintf(message, "Hello from %s", ubuf.nodename);
-
- handle = cman_init(NULL);
- if (!handle)
- {
- perror("Can't connect to cman");
- return -1;
- }
-
-
- if (cman_start_recv_data(handle, data_callback, port))
- {
- perror("Can't bind cluster socket");
- return -1;
- }
- cman_start_notification(handle, event_callback);
-
- while (1)
- {
-
- if (cman_send_data(handle, message, strlen(message)+1,0, port, 0) < 0)
- {
- perror("write");
- cman_finish(handle);
- exit(-1);
- }
-
- while (1)
- {
- if (cman_dispatch(handle, CMAN_DISPATCH_ALL|CMAN_DISPATCH_BLOCKING) == -1)
- break;
- }
- }
- fprintf(stderr, "EOF: finished\n");
-}
-
-
-void get_members(void)
-{
- cman_node_t *nodes;
- int i;
- int num_nodes = cman_get_node_count(handle);
-
- if (num_nodes == -1)
- {
- perror("get nodes");
- }
- else
- {
- printf("There are %d nodes: \n", num_nodes);
-
- nodes = malloc(num_nodes * sizeof(cman_node_t));
- if ( (cman_get_nodes(handle, num_nodes, &num_nodes, nodes)))
- {
- for (i=0; i<num_nodes; i++)
- {
- printf("%s %d\n", nodes[i].cn_name, nodes[i].cn_nodeid);
- }
- }
- else
- {
- perror("get node details");
- }
- }
-}
diff --git a/cman/tests/libtest.c b/cman/tests/libtest.c
deleted file mode 100644
index 85c1ea8..0000000
--- a/cman/tests/libtest.c
+++ /dev/null
@@ -1,132 +0,0 @@
-#include <netinet/in.h>
-#include <inttypes.h>
-#include "libcman.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-
-static void cman_callback(cman_handle_t handle, void *private, int reason, int arg)
-{
- printf("callback called reason = %d, arg=%d\n", reason, arg);
-}
-
-static void confchg_callback(cman_handle_t handle, void *private,
- unsigned int *member_list, int member_list_entries,
- unsigned int *left_list, int left_list_entries,
- unsigned int *joined_list, int joined_list_entries)
-{
- int i;
- printf("Confchg callback\n");
- printf("member_list: %d entries:\n", member_list_entries);
- for (i=0; i<member_list_entries; i++)
- printf(" %d\n", member_list[i]);
- printf("left_list: %d entries:\n", left_list_entries);
- for (i=0; i<left_list_entries; i++)
- printf(" %d\n", left_list[i]);
- printf("joined_list: %d entries:\n", joined_list_entries);
- for (i=0; i<joined_list_entries; i++)
- printf(" %d\n", joined_list[i]);
-}
-
-static void print_node(cman_node_t *node)
-{
- printf(" node id %d\n", node->cn_nodeid);
- printf(" node member %d\n", node->cn_member);
- printf(" node name %s\n", node->cn_name);
- printf(" node incarn %d\n", node->cn_incarnation);
- printf("\n");
-}
-
-int main()
-{
- cman_handle_t h;
- int num;
- int retnodes;
- cman_node_t *nodes;
- cman_version_t ver;
- cman_cluster_t clinfo;
-
- h = cman_init(0);
- if (!h)
- {
- perror("cman_init failed");
- exit(1);
- }
-
- num = cman_get_node_count(h);
- if (num > 0)
- printf("cluster has %d nodes\n", num);
- else
- perror("node count");
-
- printf("cman is active: %d\n", cman_is_active(h));
- printf("cman is quorate: %d\n", cman_is_quorate(h));
- printf("cman is listening: %d\n", cman_is_listening(h, CMAN_NODEID_US, 1)); /* membership! */
- cman_get_version(h, &ver);
- printf("cman version %d.%d.%d (config %d)\n",
- ver.cv_minor,
- ver.cv_major,
- ver.cv_patch,
- ver.cv_config);
-
- if (!cman_get_cluster(h, &clinfo))
- {
- printf("Cluster '%s', number %d\n", clinfo.ci_name, clinfo.ci_number);
- }
- else
- perror("cluster info failed");
-
- nodes = malloc(num * sizeof(cman_node_t));
- if (!nodes)
- {
- perror("malloc");
- exit(1);
- }
-
- if (!cman_get_nodes(h, num, &retnodes, nodes))
- {
- int i;
- printf("Getting all nodes:\n");
- for (i=0; i<retnodes; i++)
- print_node(&nodes[i]);
- }
- else
- {
- perror("get_nodes failed");
- }
-
- // Need to clear this.
- // Who wrote this rubbish? oh, I did.
- nodes[0].cn_name[0] = '\0';
- if (!cman_get_node(h, CMAN_NODEID_US, &nodes[0]))
- {
- printf("Getting our info:\n");
- print_node(&nodes[0]);
- }
- else
- {
- perror("get_node failed");
- }
-
- if (cman_start_notification(h, cman_callback))
- {
- perror("start_notification");
- }
-
- if (cman_start_confchg(h, confchg_callback))
- {
- perror("start_confchg");
- }
-
-
- while (1) {
- int ret = cman_dispatch(h, CMAN_DISPATCH_BLOCKING | CMAN_DISPATCH_ALL);
- if (ret == -1) {
- perror("cman_dispatch");
- break;
- }
- }
- cman_finish(h);
-
- return 0;
-}
diff --git a/cman/tests/qwait.c b/cman/tests/qwait.c
deleted file mode 100644
index 5d6a3f7..0000000
--- a/cman/tests/qwait.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <sys/utsname.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "cnxman-socket.h"
-
-static int cluster_sock;
-
-static void signal_handler(int sig)
-{
-
- return;
-}
-
-
-int main(int argc, char *argv[])
-{
- struct sigaction sa;
- sigset_t ss;
-
- cluster_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT);
- if (cluster_sock == -1)
- {
- perror("Can't open cluster socket");
- return -1;
- }
- sa.sa_handler = signal_handler;
- sa.sa_mask = ss;
- sa.sa_flags = 0;
- sigaction(SIGUSR1, &sa, NULL);
-
- if (ioctl(cluster_sock, SIOCCLUSTER_NOTIFY, SIGUSR1) == -1)
- {
- perror("Can't set up cluster notification");
- close(cluster_sock);
- return -1;
- }
-
- while (!ioctl(cluster_sock, SIOCCLUSTER_ISQUORATE, 0))
- {
- pause();
- }
-
- close(cluster_sock);
-
- return 0;
-}
diff --git a/cman/tests/sysman.c b/cman/tests/sysman.c
deleted file mode 100644
index 99ba562..0000000
--- a/cman/tests/sysman.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* "sysman" client */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <sys/utsname.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#define LOCAL_SOCKNAME "/var/run/sysman"
-static int open_local_sock(void);
-
-int main(int argc, char *argv[])
-{
- char message[PIPE_BUF];
- int local_sock;
- int len;
-
- if (argc < 2)
- {
- printf("usage: sysman \"command\"\n");
- return 0;
- }
-
- local_sock = open_local_sock();
- if (local_sock < 0)
- exit(2);
-
- /* Send the command */
- write(local_sock, argv[1], strlen(argv[1])+1);
-
- /* Print the replies */
- while ( (len = read(local_sock, message, sizeof(message))) )
- {
- write(STDOUT_FILENO, message, len);
- }
- printf("\n");
- return 0;
-}
-
-
-static int open_local_sock(void)
-{
- int local_socket;
- struct sockaddr_un sockaddr;
-
- // Open local socket
- local_socket = socket(PF_UNIX, SOCK_STREAM, 0);
- if (local_socket < 0)
- {
- perror("Can't create local socket");
- return -1;
- }
-
- strcpy(sockaddr.sun_path, LOCAL_SOCKNAME);
- sockaddr.sun_family = AF_UNIX;
- if (connect(local_socket, (struct sockaddr *)&sockaddr, sizeof(sockaddr)))
- {
- fprintf(stderr, "sysmand is not running\n");
- close(local_socket);
- return -1;
- }
- return local_socket;
-}
-
diff --git a/cman/tests/sysmand.c b/cman/tests/sysmand.c
deleted file mode 100644
index 8391c06..0000000
--- a/cman/tests/sysmand.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/* "sysman" server
-
- Listens on a cluster port and executes commands.
-
- This is just a demonstration piece of code, not for production use
-
- *************************************
- *** IT IS A MASSIVE SECURITY HOLE ***
- *************************************
-
- Any command passed to it will be run as root!
-
-*/
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <sys/utsname.h>
-#include <sys/errno.h>
-#include <syslog.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <time.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "libcman.h"
-#define LOCAL_SOCKNAME "/var/run/sysman"
-#define CLUSTER_PORT_SYSMAN 12
-
-static cman_node_t *nodes = NULL;
-static int num_nodes;
-static cman_handle_t ch;
-static int expected_responses;
-
-/* Header for all commands sent to other sysmand servers */
-struct sysman_header
-{
- int fd; /* local FD to return output to. in network byte order */
- int ret; /* Return code of command */
- char cmd;
-#define SYSMAN_CMD_REQUEST 1
-#define SYSMAN_CMD_REPLY 2
-};
-
-/* One of these for each fd we are listening on
- some fields are specific to particular types.
-*/
-struct read_fd
-{
- int fd;
- enum {CLUSTER_SOCK, LOCAL_RENDEZVOUS, LOCAL_SOCK} type;
- int nodes_done;
- time_t start_time;
- struct read_fd *next;
-};
-/* Head of the fd list. Also contains
- the cluster_socket details */
-static struct read_fd read_fd_head;
-
-
-static void get_members(void);
-static int open_local_sock(void);
-static int exec_command(char *cmd, char *reply, int *len);
-static int name_from_nodeid(int nodeid, char *name);
-static void remove_sock(struct read_fd *deadfd);
-static struct read_fd *find_by_fd(int fd);
-static int nodes_listening(int);
-
-static void event_callback(cman_handle_t handle, void *private, int reason, int arg)
-{
- get_members();
-}
-
-static void data_callback(cman_handle_t handle, void *private,
- char *buf, int len, uint8_t port, int nodeid)
-{
- struct read_fd *replyfd = NULL;
- char reply[PIPE_BUF];
- char title[PIPE_BUF];
- char nodename[CMAN_MAX_NODENAME_LEN];
- struct sysman_header *header;
- int status;
- int title_len;
- struct sysman_header *inheader = (struct sysman_header *)buf;
-
- switch (inheader->cmd)
- {
- case SYSMAN_CMD_REQUEST:
-
- /* Execute command and capture stdout/stderr into 'reply'*/
- status = exec_command(buf+sizeof(struct sysman_header), reply+sizeof(struct sysman_header), &len);
-
- header = (struct sysman_header *)reply;
-
- /* Send reply */
- header->fd = inheader->fd; /* Already in the right format */
- header->cmd = SYSMAN_CMD_REPLY;
- header->ret = htonl(status);
-
- cman_send_data(ch, reply, len, 0, port, nodeid);
- break;
-
- case SYSMAN_CMD_REPLY:
- name_from_nodeid(nodeid, nodename);
- title_len = sprintf(title, "\nReply from %s:", nodename);
- if (inheader->ret != 0)
- title_len += sprintf(title+title_len, " (ret=%d)", ntohl(inheader->ret));
- strcat(title, "\n"); title_len++;
- write(ntohl(inheader->fd), title, title_len);
- write(ntohl(inheader->fd), buf+sizeof(struct sysman_header),
- len - sizeof(struct sysman_header));
-
- replyfd = find_by_fd(ntohl(inheader->fd));
- if (replyfd)
- {
- /* If we've done all nodes then close the client down */
- if (++replyfd->nodes_done == expected_responses)
- {
- close(replyfd->fd);
- remove_sock(replyfd);
- }
- }
- break;
-
- default:
- name_from_nodeid(nodeid, nodename);
- syslog(LOG_ERR, "Unknown sysman command received from %s: %d\n",
- nodename, inheader->cmd);
- break;
- }
-}
-
-int main(int argc, char *argv[])
-{
- unsigned char port = CLUSTER_PORT_SYSMAN;
- int local_sock;
- struct read_fd *newfd;
- struct utsname nodeinfo;
-
- ch = cman_init(NULL);
- if (!ch)
- {
- perror("Can't connect to cman");
- return -1;
- }
-
- uname(&nodeinfo);
-
- if (cman_start_recv_data(ch, data_callback, port))
- {
- perror("Can't bind cluster socket");
- return -1;
- }
-
- cman_start_notification(ch, event_callback);
-
- read_fd_head.fd = cman_get_fd(ch);
- read_fd_head.type = CLUSTER_SOCK;
-
- /* Preload cluster members list */
- get_members();
-
- /* Just a sensible default, we work out just how many
- responses we expect properly later */
- expected_responses = num_nodes;
-
- /* Open the Unix socket we listen for commands on */
- local_sock = open_local_sock();
- if (local_sock < 0)
- exit(2);
-
- newfd = malloc(sizeof(struct read_fd));
- if (!newfd)
- exit(2);
-
- newfd->fd = local_sock;
- newfd->type = LOCAL_RENDEZVOUS;
- newfd->next = NULL;
- read_fd_head.next = newfd;
-
- while (1)
- {
- fd_set in;
- struct read_fd *thisfd;
- struct timeval tv = {10,0};
-
- read_fd_head.fd = cman_get_fd(ch);
- FD_ZERO(&in);
- for (thisfd = &read_fd_head; thisfd != NULL; thisfd = thisfd->next)
- {
- FD_SET(thisfd->fd, &in);
- }
-
- if (select(FD_SETSIZE, &in, NULL, NULL, &tv) > 0)
- {
- struct read_fd *lastfd = NULL;
-
- for (thisfd = &read_fd_head; thisfd != NULL; thisfd = thisfd->next)
- {
- if (FD_ISSET(thisfd->fd, &in))
- {
- switch(thisfd->type)
- {
- /* Request or response from another cluster node */
- case CLUSTER_SOCK:
- if (cman_dispatch(ch, CMAN_DISPATCH_ONE) == -1)
- goto closedown;
- break;
-
- /* Someone connected to our local socket */
- case LOCAL_RENDEZVOUS:
- {
- struct sockaddr_un socka;
- struct read_fd *newfd;
- socklen_t sl = sizeof(socka);
- int client_fd = accept(local_sock, (struct sockaddr *)&socka, &sl);
-
- if (client_fd >= 0)
- {
- newfd = malloc(sizeof(struct read_fd));
- if (!newfd)
- {
- close(client_fd);
- break;
- }
- newfd->fd = client_fd;
- newfd->type = LOCAL_SOCK;
- newfd->next = thisfd->next;
- newfd->nodes_done = 0;
- newfd->start_time = time(NULL);
- thisfd->next = newfd;
- }
- }
- break;
-
- /* Data on a connected socket */
- case LOCAL_SOCK:
- {
- int len;
- char buffer[PIPE_BUF];
- len = read(thisfd->fd, buffer, sizeof(buffer));
-
- /* EOF on socket */
- if (len <= 0)
- {
- struct read_fd *free_fd;
-
- close(thisfd->fd);
- /* Remove it from the list safely */
- lastfd->next = thisfd->next;
- free_fd = thisfd;
- thisfd = lastfd;
- free(free_fd);
- }
- else
- {
- char cman_buffer[PIPE_BUF];
- struct sysman_header *header = (struct sysman_header *)cman_buffer;
-
- expected_responses = nodes_listening(thisfd->fd);
-
- header->fd = htonl(thisfd->fd);
- header->cmd = SYSMAN_CMD_REQUEST;
- memcpy(cman_buffer+sizeof(*header), buffer, len);
-
- if (!cman_send_data(ch, cman_buffer, sizeof(*header)+len, 0, port, 0))
- {
- perror("write");
- goto closedown;
- }
- }
- }
- break;
-
- } /* switch */
-
- }
- lastfd = thisfd;
- }
- }
- /* Check for timed-out connections */
- for (thisfd = &read_fd_head; thisfd != NULL; thisfd = thisfd->next)
- {
- if (thisfd->type == LOCAL_SOCK && (thisfd->start_time <= time(NULL)-10))
- {
- write(thisfd->fd,"Timed-out\n", 10);
- close(thisfd->fd);
- remove_sock(thisfd);
-
- /* Refresh members list in case a node has gone down
- or a remote sysmand has crashed */
- get_members();
- }
- }
- }
- closedown:
- cman_finish(ch);
- close(local_sock);
-
- return 0;
-}
-
-/* Get a list of members */
-static void get_members()
-{
- num_nodes = cman_get_node_count(ch);
- if (num_nodes == -1)
- {
- perror("get nodes");
- }
- else
- {
- if (nodes) free(nodes);
-
- nodes = malloc(num_nodes * sizeof(cman_node_t));
-
- if (cman_get_nodes(ch, num_nodes, &num_nodes, nodes))
- perror("Error getting node list");
- }
-}
-
-/* Convert a nodeid to a node name */
-static int name_from_nodeid(int nodeid, char *name)
-{
- int i;
-
- for (i=0; i<num_nodes; i++)
- {
- if (nodeid == nodes[i].cn_nodeid)
- {
- strcpy(name, nodes[i].cn_name);
- return 0;
- }
- }
- /* Who?? */
- strcpy(name, "Unknown");
- return -1;
-}
-
-/* Check which nodes are listening on the SYSMAN port */
-static int nodes_listening(int errfd)
-{
- int i;
- int num_listening = 0;
-
- for (i=0; i<num_nodes; i++)
- {
- int listening;
-
- listening = cman_is_listening(ch, nodes[i].cn_nodeid, CLUSTER_PORT_SYSMAN);
-
- if (listening > 0)
- {
- num_listening++;
- }
- else
- {
- if (listening == 0)
- {
- char errstring[1024];
- int len;
- len = snprintf(errstring, sizeof(errstring),
- "WARNING: node %s is not listening for SYSMAN requests\n",
- nodes[i].cn_name);
- write(errfd, errstring, len);
- }
- }
- }
- return num_listening;
-}
-
-static int open_local_sock()
-{
- int local_socket;
- struct sockaddr_un sockaddr;
-
- // Open local socket
- unlink(LOCAL_SOCKNAME);
- local_socket = socket(PF_UNIX, SOCK_STREAM, 0);
- if (local_socket < 0)
- {
- syslog(LOG_ERR, "Can't create local socket: %m");
- return -1;
- }
-
- strcpy(sockaddr.sun_path, LOCAL_SOCKNAME);
- sockaddr.sun_family = AF_UNIX;
- if (bind(local_socket, (struct sockaddr *)&sockaddr, sizeof(sockaddr)))
- {
- syslog(LOG_ERR, "can't bind local socket: %m");
- close(local_socket);
- return -1;
- }
- if (listen(local_socket, 1) != 0)
- {
- syslog(LOG_ERR, "listen local: %m");
- close(local_socket);
- return -1;
- }
- // Make sure only root can talk to us via the local socket.
- // Considering the rest of the security implications of
- // this code, this is simply pathetic!
- chmod(LOCAL_SOCKNAME, 0600);
-
- return local_socket;
-}
-
-static struct read_fd *find_by_fd(int fd)
-{
- struct read_fd *thisfd;
-
- for (thisfd = &read_fd_head; thisfd != NULL; thisfd = thisfd->next)
- if (fd == thisfd->fd) return thisfd;
-
- return NULL;
-}
-
-static void remove_sock(struct read_fd *deadfd)
-{
- struct read_fd *thisfd;
- struct read_fd *lastfd=NULL;
-
- for (thisfd = &read_fd_head; thisfd != NULL; thisfd = thisfd->next)
- {
- if (thisfd == deadfd)
- {
- lastfd->next = deadfd->next;
- free(deadfd);
- }
- lastfd = thisfd;
- }
-}
-
-static int exec_command(char *cmd, char *reply, int *len)
-{
- FILE *pipe;
- int readlen;
- int avail = PIPE_BUF-sizeof(struct sysman_header)-1;
- char realcmd[strlen(cmd)+25];
-
- /* Send stderr back to the caller, and make stdin /dev/null */
- snprintf(realcmd, sizeof(realcmd), "%s </dev/null 2>&1", cmd);
-
- *len = 0;
- pipe = popen(realcmd, "r");
-
- /* Fill the buffer as full as possible */
- do
- {
- readlen = fread(reply + *len, 1, avail, pipe);
- if (readlen > 0)
- {
- *len += readlen;
- avail -= readlen;
- }
- }
- while (avail>0 && readlen > 0);
-
- reply[*len] ='\0';
-
- /* Return completion status of command */
- return pclose(pipe);
-}
diff --git a/cman/tests/user_service.c b/cman/tests/user_service.c
deleted file mode 100644
index f47987b..0000000
--- a/cman/tests/user_service.c
+++ /dev/null
@@ -1,285 +0,0 @@
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <signal.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include "cnxman-socket.h"
-
-static pthread_t recv_thread;
-static int cl_sock;
-static int quit = 0;
-static int leave_finished = 0;
-static pid_t our_pid;
-
-
-/* SIGUSR1 will cause this program to look for a new service event from SM
- using the GETEVENT ioctl.
-
- SIGTERM will cause this program to leave the service group cleanly; it will
- do a LEAVE ioctl, get a stop event and then exit.
-
- SIGKILL will cause the program to exit without first leaving the service
- group. In that case the kernel will clean up and leave the service group
- (as a part of cl_release on the cluster socket). */
-
-
-static void sigusr1_handler(int sig)
-{
-}
-
-static void sigterm_handler(int sig)
-{
- quit = 1;
-}
-
-/* This thread receives messages on the cluster socket and prints them. */
-
-static void *recv_thread_fn(void *arg)
-{
- struct iovec iov[2];
- struct msghdr msg;
- struct sockaddr_cl saddr;
- char buf[256];
- int len;
- int nodeid;
-
- for (;;) {
- memset(buf, 0, 256);
-
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_iovlen = 1;
- msg.msg_iov = iov;
- msg.msg_name = &saddr;
- msg.msg_flags = 0;
- msg.msg_namelen = sizeof(saddr);
- iov[0].iov_len = sizeof(buf);
- iov[0].iov_base = buf;
-
- len = recvmsg(cl_sock, &msg, MSG_OOB);
-
- if (len < 0 && errno == EAGAIN)
- continue;
-
- if (!len || len < 0)
- continue;
-
- nodeid = saddr.scl_nodeid;
-
- if (buf[0] == CLUSTER_OOB_MSG_PORTCLOSED)
- printf("message: oob port-closed from nodeid %d\n",
- nodeid);
-
- else if (buf[0] == CLUSTER_OOB_MSG_SERVICEEVENT)
- printf("message: oob service-event\n");
-
- else if (!strcmp(buf, "hello"))
- printf("message: \"%s\" from nodeid %d\n", buf, nodeid);
-
- else
- printf("message: unknown len %d byte0 %x nodeid %d\n",
- len, buf[0], nodeid);
- }
-}
-
-static void send_group_message(void)
-{
- struct iovec iov[2];
- struct msghdr msg;
- char buf[256];
- int len;
-
- strcpy(buf, "hello");
-
- iov[0].iov_len = strlen(buf);
- iov[0].iov_base = buf;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_iovlen = 1;
- msg.msg_iov = iov;
- msg.msg_name = NULL;
- msg.msg_flags = O_NONBLOCK;
- msg.msg_namelen = 0;
-
- len = sendmsg(cl_sock, &msg, 0);
-}
-
-static void print_ev(struct cl_service_event *ev)
-{
- switch (ev->type) {
- case SERVICE_EVENT_STOP:
- printf("stop:\n");
- break;
- case SERVICE_EVENT_START:
- printf("start:\n");
- break;
- case SERVICE_EVENT_FINISH:
- printf("finish:\n");
- break;
- case SERVICE_EVENT_LEAVEDONE:
- printf("leavedone:\n");
- break;
- }
- printf(" event_id = %u\n", ev->event_id);
- printf(" last_stop = %u\n", ev->last_stop);
- printf(" last_start = %u\n", ev->last_start);
- printf(" last_finish = %u\n", ev->last_finish);
- printf(" node_count = %u\n", ev->node_count);
-}
-
-static void print_members(int count, struct cl_cluster_node *nodes)
-{
- int i;
-
- printf("members:\n");
- for (i = 0; i < count; i++) {
- printf(" nodeid = %u \"%s\"\n", nodes->node_id, nodes->name);
- nodes++;
- }
-}
-
-static int process_event(struct cl_service_event *ev)
-{
- struct cl_cluster_node *nodes;
- int error = 0;
-
- print_ev(ev);
-
- if (ev->type == SERVICE_EVENT_START) {
-
- nodes = malloc(ev->node_count * sizeof(struct cl_cluster_node));
- if (!nodes) {
- perror("process_event: malloc failed");
- return -ENOMEM;
- }
-
- memset(nodes, 0, ev->node_count*sizeof(struct cl_cluster_node));
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_GETMEMBERS, nodes);
- if (error < 0)
- perror("process_event: service get members failed");
-
- print_members(ev->node_count, nodes);
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_STARTDONE,
- ev->event_id);
- if (error < 0)
- perror("process_event: start done error");
-
- /* send_group_message(); */
-
- free(nodes);
- }
-
- if (ev->type == SERVICE_EVENT_LEAVEDONE)
- leave_finished = 1;
-
- return error;
-}
-
-int main(int argc, char **argv)
-{
- struct cl_service_event event;
- struct sockaddr_cl saddr;
- char *name;
- int error;
-
- our_pid = getpid();
-
- if (argc > 1)
- name = argv[1];
- else
- name = "example";
-
-
- cl_sock = socket(AF_CLUSTER, SOCK_DGRAM, CLPROTO_CLIENT);
- if (cl_sock < 0) {
- perror("main: can't create cluster socket");
- return -1;
- }
-
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_REGISTER, name);
- if (error < 0) {
- perror("main: service register failed");
- return -1;
- }
-
-
- /* binding to an address is only needed if we want to send/recv
- messages to other nodes on the cluster socket. */
-
-#if 0
- saddr.scl_family = AF_CLUSTER;
- saddr.scl_port = 13; /* CLUSTER_PORT_USER_SERVICE */
-
- error = bind(cl_sock, (struct sockaddr *) &saddr,
- sizeof(struct sockaddr_cl));
- if (error < 0) {
- perror("main: can't bind to cluster socket");
- return -1;
- }
- pthread_create(&recv_thread, NULL, recv_thread_fn, 0);
-#endif
-
- signal(SIGUSR1, sigusr1_handler);
- signal(SIGTERM, sigterm_handler);
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_SETSIGNAL, SIGUSR1);
- if (error < 0) {
- perror("main: service set signal failed");
- return -1;
- }
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_JOIN, NULL);
- if (error < 0) {
- perror("main: service join failed");
- return -1;
- }
-
-
- for (;;) {
- memset(&event, 0, sizeof(struct cl_service_event));
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_GETEVENT, &event);
- if (error < 0) {
- perror("main: service get event failed");
- return -1;
- }
-
- if (!error)
- pause();
- else
- process_event(&event);
-
-
- if (quit) {
- quit = 0;
- leave_finished = 0;
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_LEAVE, NULL);
- if (error < 0) {
- perror("main: service leave failed");
- return -1;
- }
- }
-
- if (leave_finished)
- break;
- }
-
- error = ioctl(cl_sock, SIOCCLUSTER_SERVICE_UNREGISTER, NULL);
- if (error < 0)
- perror("main: unregister failed");
-
- return 0;
-}
diff --git a/common/Makefile b/common/Makefile
deleted file mode 100644
index 31fdfdb..0000000
--- a/common/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS=liblogthread
diff --git a/common/liblogthread/Makefile b/common/liblogthread/Makefile
deleted file mode 100644
index be072bf..0000000
--- a/common/liblogthread/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-TARGET= liblogthread
-
-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${incdir}
-
-LDFLAGS += -lpthread
diff --git a/common/liblogthread/liblogthread.c b/common/liblogthread/liblogthread.c
deleted file mode 100644
index ba96a2a..0000000
--- a/common/liblogthread/liblogthread.c
+++ /dev/null
@@ -1,334 +0,0 @@
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <time.h>
-#include <syslog.h>
-#include <pthread.h>
-#include <sys/param.h>
-
-#include "liblogthread.h"
-
-#define DEFAULT_ENTRIES 4096
-#define ENTRY_STR_LEN 128
-
-struct entry {
- int level;
- char str[ENTRY_STR_LEN];
- time_t time;
-};
-
-static struct entry *ents;
-static unsigned int num_ents = DEFAULT_ENTRIES;
-static unsigned int head_ent, tail_ent; /* add at head, remove from tail */
-static unsigned int dropped;
-static unsigned int pending_ents;
-static unsigned int init;
-static unsigned int done;
-static pthread_t thread_handle;
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-
-static int logt_mode; /* LOG_MODE_ */
-static int logt_syslog_facility;
-static int logt_syslog_priority;
-static int logt_logfile_priority;
-static char logt_name[PATH_MAX];
-static char logt_logfile[PATH_MAX];
-static FILE *logt_logfile_fp;
-
-static char *_time(time_t *t)
-{
- static char buf[64];
-
- strftime(buf, sizeof(buf), "%b %d %T", localtime(t));
- return buf;
-}
-
-static void write_entry(int level, time_t *t, char *str)
-{
- if ((logt_mode & LOG_MODE_OUTPUT_FILE) &&
- (level <= logt_logfile_priority) && logt_logfile_fp) {
- fprintf(logt_logfile_fp, "%s %s %s", _time(t), logt_name, str);
- fflush(logt_logfile_fp);
- }
- if ((logt_mode & LOG_MODE_OUTPUT_SYSLOG) &&
- (level <= logt_syslog_priority))
- syslog(level, "%s", str);
-}
-
-static void write_dropped(int level, time_t *t, int num)
-{
- char str[ENTRY_STR_LEN];
- sprintf(str, "dropped %d entries", num);
- write_entry(level, t, str);
-}
-
-static void *thread_fn(void *arg)
-{
- char str[ENTRY_STR_LEN];
- struct entry *e;
- time_t logtime;
- int level, prev_dropped = 0;
-
- while (1) {
- pthread_mutex_lock(&mutex);
- while (head_ent == tail_ent) {
- if (done) {
- pthread_mutex_unlock(&mutex);
- goto out;
- }
- pthread_cond_wait(&cond, &mutex);
- }
-
- e = &ents[tail_ent++];
- tail_ent = tail_ent % num_ents;
- pending_ents--;
-
- memcpy(str, e->str, ENTRY_STR_LEN);
- level = e->level;
- logtime = e->time;
-
- prev_dropped = dropped;
- dropped = 0;
- pthread_mutex_unlock(&mutex);
-
- if (prev_dropped) {
- write_dropped(level, &logtime, prev_dropped);
- prev_dropped = 0;
- }
-
- write_entry(level, &logtime, str);
- }
- out:
- pthread_exit(NULL);
-}
-
-static void _logt_print(int level, char *buf)
-{
- struct entry *e;
-
- pthread_mutex_lock(&mutex);
-
- if (pending_ents == num_ents) {
- dropped++;
- goto out;
- }
-
- e = &ents[head_ent++];
- head_ent = head_ent % num_ents;
- pending_ents++;
-
- strncpy(e->str, buf, ENTRY_STR_LEN);
- e->level = level;
- e->time = time(NULL);
- out:
- pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
-}
-
-void logt_print(int level, const char *fmt, ...)
-{
- va_list ap;
- char buf[ENTRY_STR_LEN];
-
- if (!init)
- return;
-
- buf[sizeof(buf) - 1] = 0;
-
- va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
- va_end(ap);
-
- if (level > logt_syslog_priority && level > logt_logfile_priority)
- return;
-
- /* this stderr crap really doesn't belong in this lib, please
- feel free to not use it */
- if (logt_mode & LOG_MODE_OUTPUT_STDERR)
- fputs(buf, stderr);
-
- _logt_print(level, buf);
-}
-
-static void _conf(const char *name, int mode, int syslog_facility,
- int syslog_priority, int logfile_priority, const char *logfile)
-{
- int fd;
-
- pthread_mutex_lock(&mutex);
- logt_mode = mode;
- logt_syslog_facility = syslog_facility;
- logt_syslog_priority = syslog_priority;
- logt_logfile_priority = logfile_priority;
- if (name)
- strncpy(logt_name, name, PATH_MAX);
- if (logfile)
- strncpy(logt_logfile, logfile, PATH_MAX);
-
- if (logt_mode & LOG_MODE_OUTPUT_FILE && logt_logfile[0]) {
- if (logt_logfile_fp) {
- fclose(logt_logfile_fp);
- logt_logfile_fp = NULL;
- }
- logt_logfile_fp = fopen(logt_logfile, "a+");
- if (logt_logfile_fp != NULL) {
- fd = fileno(logt_logfile_fp);
- fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
- }
- } else {
- if (logt_logfile_fp) {
- fclose(logt_logfile_fp);
- logt_logfile_fp = NULL;
- }
- }
-
- if (logt_mode & LOG_MODE_OUTPUT_SYSLOG) {
- closelog();
- openlog(logt_name, LOG_CONS | LOG_PID, logt_syslog_facility);
- }
- pthread_mutex_unlock(&mutex);
-}
-
-void logt_conf(const char *name, int mode, int syslog_facility, int syslog_priority,
- int logfile_priority, const char *logfile)
-{
- if (!init)
- return;
-
- _conf(name, mode, syslog_facility, syslog_priority, logfile_priority,
- logfile);
-}
-
-int logt_init(const char *name, int mode, int syslog_facility, int syslog_priority,
- int logfile_priority, const char *logfile)
-{
- int rv;
-
- if (init)
- return -1;
-
- _conf(name, mode, syslog_facility, syslog_priority, logfile_priority,
- logfile);
-
- ents = malloc(num_ents * sizeof(struct entry));
- if (!ents)
- return -1;
- memset(ents, 0, num_ents * sizeof(struct entry));
-
- rv = pthread_create(&thread_handle, NULL, thread_fn, NULL);
- if (rv) {
- free(ents);
- return -1;
- }
- done = 0;
- init = 1;
- return 0;
-}
-
-
-/*
- * Reinitialize logt w/ previous values (e.g. use after
- * a call to fork())
- *
- * Only works after you call logt_init and logt_exit
- */
-int logt_reinit(void)
-{
- char name_tmp[PATH_MAX];
- char file_tmp[PATH_MAX];
-
- if (!done || init)
- return -1;
-
- /* Use copies on the stack for these */
- memset(name_tmp, 0, sizeof(name_tmp));
- memset(file_tmp, 0, sizeof(file_tmp));
-
- strncpy(name_tmp, logt_name, sizeof(name_tmp));
- if (!strlen(name_tmp))
- return -1;
- if (strlen(logt_logfile))
- strncpy(file_tmp, logt_logfile, sizeof(file_tmp));
-
- return logt_init(name_tmp, logt_mode, logt_syslog_facility,
- logt_syslog_priority, logt_logfile_priority,
- file_tmp);
-}
-
-
-void logt_exit(void)
-{
- pthread_mutex_lock(&mutex);
- done = 1;
- init = 0;
- pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
- pthread_join(thread_handle, NULL);
-
- pthread_mutex_lock(&mutex);
- /* close syslog + log file */
- closelog();
- if (logt_logfile_fp) {
- fclose(logt_logfile_fp);
- logt_logfile_fp = NULL;
- }
-
- /* clean up any pending log messages */
- dropped = 0;
- pending_ents = 0;
- head_ent = tail_ent = 0;
- free(ents);
- ents = NULL;
-
- pthread_mutex_unlock(&mutex);
-}
-
-#ifdef TEST
-int main(int argc, char **argv)
-{
- int pid;
-
- logt_init("test", LOG_MODE_OUTPUT_FILE|LOG_MODE_OUTPUT_SYSLOG,
- LOG_DAEMON, LOG_DEBUG, LOG_DEBUG, "/tmp/logthread");
- logt_print(LOG_DEBUG, "debugging message %d\n", argc);
- logt_print(LOG_ERR, "error message %d\n", argc);
- sleep(1);
- logt_print(LOG_DEBUG, "second debug message\n");
- logt_exit();
-
- logt_print(LOG_ERR, "If you see this, it's a bug\n");
-
- logt_init("test2", LOG_MODE_OUTPUT_FILE|LOG_MODE_OUTPUT_SYSLOG,
- LOG_DAEMON, LOG_DEBUG, LOG_DEBUG, "/tmp/logthread");
- logt_print(LOG_DEBUG, "after 2nd init %d\n", argc);
- logt_print(LOG_ERR, "error message %d\n", argc);
- logt_print(LOG_DEBUG, "third debug message\n");
- logt_exit();
-
- logt_print(LOG_ERR, "If you see this, it's a bug\n");
-
- logt_reinit();
- logt_print(LOG_DEBUG, "after reinit\n");
- logt_print(LOG_DEBUG, "<-- should say test2\n");
-
- logt_exit();
-
- if ((pid = fork()) < 0)
- return -1;
-
- if (pid)
- exit(0);
-
- /* child process */
- logt_reinit();
- logt_print(LOG_DEBUG, "HELLO from child process\n");
- logt_exit();
-
- return 0;
-}
-#endif
-
diff --git a/common/liblogthread/liblogthread.h b/common/liblogthread/liblogthread.h
deleted file mode 100644
index 3c17395..0000000
--- a/common/liblogthread/liblogthread.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef LOGTHREAD_DOT_H
-#define LOGTHREAD_DOT_H
-
-#include <syslog.h>
-
-#define LOG_MODE_OUTPUT_FILE 1
-#define LOG_MODE_OUTPUT_SYSLOG 2
-#define LOG_MODE_OUTPUT_STDERR 4
-
-int logt_init(const char *name, int mode, int syslog_facility, int syslog_priority,
- int logfile_priority, const char *logfile);
-void logt_conf(const char *name, int mode, int syslog_facility, int syslog_priority,
- int logfile_priority, const char *logfile);
-void logt_exit(void);
-int logt_reinit(void);
-void logt_print(int level, const char *fmt, ...)
- __attribute__((format(printf, 2, 3)));;
-
-#endif
diff --git a/common/liblogthread/liblogthread.pc.in b/common/liblogthread/liblogthread.pc.in
deleted file mode 100644
index 8ba8268..0000000
--- a/common/liblogthread/liblogthread.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: liblogthread
-Version: @VERSION@
-Description: Cluster threaded logging library
-Requires:
-Libs: -L${libdir} -llogthread
-Cflags: -I${includedir}
diff --git a/config/Makefile b/config/Makefile
deleted file mode 100644
index 50468ed..0000000
--- a/config/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS=libs plugins tools man
diff --git a/config/libs/Makefile b/config/libs/Makefile
deleted file mode 100644
index 8fd2879..0000000
--- a/config/libs/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS = libccsconfdb
diff --git a/config/libs/libccsconfdb/Makefile b/config/libs/libccsconfdb/Makefile
deleted file mode 100644
index 2b233f3..0000000
--- a/config/libs/libccsconfdb/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-TARGET= libccs
-
-INCDIRT=ccs.h
-
-OBJS= $(TARGET).o \
- xpathlite.o \
- fullxpath.o \
- extras.o
-
-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 += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64
-CFLAGS += -I${corosyncincdir} -I${logtincdir} `xml2-config --cflags`
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${corosynclibdir} -lconfdb
-LDFLAGS += `xml2-config --libs`
-LDFLAGS += -L${libdir}
diff --git a/config/libs/libccsconfdb/ccs.h b/config/libs/libccsconfdb/ccs.h
deleted file mode 100644
index 5c67735..0000000
--- a/config/libs/libccsconfdb/ccs.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __CCS_DOT_H__
-#define __CCS_DOT_H__
-
-int ccs_connect(void);
-int ccs_force_connect(const char *cluster_name, int blocking);
-int ccs_disconnect(int desc);
-int ccs_get(int desc, const char *query, char **rtn);
-int ccs_get_list(int desc, const char *query, char **rtn);
-int ccs_set(int desc, const char *path, char *val);
-int ccs_lookup_nodename(int desc, const char *nodename, char **rtn);
-void ccs_read_logging(int fd, const char *name, int *debug, int *mode,
- int *syslog_facility, int *syslog_priority,
- int *logfile_priority, char *logfile);
-extern int fullxpath;
-
-#endif /* __CCS_DOT_H__ */
diff --git a/config/libs/libccsconfdb/ccs_internal.h b/config/libs/libccsconfdb/ccs_internal.h
deleted file mode 100644
index 617f9e7..0000000
--- a/config/libs/libccsconfdb/ccs_internal.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __CCS_INTERNAL_DOT_H__
-#define __CCS_INTERNAL_DOT_H__
-
-/* NOTE: use __attribute__ to hide the internal API */
-
-/* from libccs.c */
-void reset_iterator(confdb_handle_t handle, hdb_handle_t connection_handle)
- __attribute__ ((visibility("hidden")));
-int get_previous_query(confdb_handle_t handle, hdb_handle_t connection_handle,
- char *previous_query, hdb_handle_t *query_handle)
- __attribute__ ((visibility("hidden")));
-int set_previous_query(confdb_handle_t handle, hdb_handle_t connection_handle,
- const char *previous_query, hdb_handle_t query_handle)
- __attribute__ ((visibility("hidden")));
-
-/* from xpathlite.c */
-char *_ccs_get_xpathlite(confdb_handle_t handle, hdb_handle_t connection_handle,
- const char *query, int list)
- __attribute__ ((visibility("hidden")));
-
-/* from fullxpath.c */
-char *_ccs_get_fullxpath(confdb_handle_t handle, hdb_handle_t connection_handle,
- const char *query, int list)
- __attribute__ ((visibility("hidden")));
-int xpathfull_init(confdb_handle_t handle)
- __attribute__ ((visibility("hidden")));
-void xpathfull_finish(void) __attribute__ ((visibility("hidden")));
-
-#endif /* __CCS_INTERNAL_DOT_H__ */
diff --git a/config/libs/libccsconfdb/extras.c b/config/libs/libccsconfdb/extras.c
deleted file mode 100644
index 7d187c9..0000000
--- a/config/libs/libccsconfdb/extras.c
+++ /dev/null
@@ -1,447 +0,0 @@
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <limits.h>
-
-#define SYSLOG_NAMES
-#include <syslog.h>
-#include <liblogthread.h>
-
-#include "ccs.h"
-
-/**
- * ccs_lookup_nodename
- * @cd: ccs descriptor
- * @nodename: node name string
- * @retval: pointer to location to assign the result, if found
- *
- * This function takes any valid representation (FQDN, non-qualified
- * hostname, IP address, IPv6 address) of a node's name and finds its
- * canonical name (per cluster.conf). This function will find the primary
- * node name if passed a node's "altname" or any valid representation
- * of it.
- *
- * Returns: 0 on success, < 0 on failure
- */
-int ccs_lookup_nodename(int cd, const char *nodename, char **retval)
-{
- char path[256];
- char host_only[128];
- char *str;
- char *p;
- int error;
- int ret;
- unsigned int i;
- size_t nodename_len;
- struct addrinfo hints;
-
- if (nodename == NULL)
- return (-1);
-
- nodename_len = strlen(nodename);
- ret = snprintf(path, sizeof(path),
- "/cluster/clusternodes/clusternode[@name=\"%s\"]/@name",
- nodename);
- if (ret < 0 || (size_t) ret >= sizeof(path)) {
- errno = E2BIG;
- return (-E2BIG);
- }
-
- str = NULL;
- error = ccs_get(cd, path, &str);
- if (!error) {
- *retval = str;
- return (0);
- }
-
- if (nodename_len >= sizeof(host_only)) {
- errno = E2BIG;
- return (-E2BIG);
- }
-
- /* Try just the hostname */
- strcpy(host_only, nodename);
- p = strchr(host_only, '.');
- if (p != NULL) {
- *p = '\0';
-
- ret = snprintf(path, sizeof(path),
- "/cluster/clusternodes/clusternode[@name=\"%s\"]/@name",
- host_only);
- if (ret < 0 || (size_t) ret >= sizeof(path))
- return (-E2BIG);
-
- str = NULL;
- error = ccs_get(cd, path, &str);
- if (!error) {
- *retval = str;
- return (0);
- }
- }
-
- memset(&hints, 0, sizeof(hints));
- if (strchr(nodename, ':') != NULL)
- hints.ai_family = AF_INET6;
- else if (isdigit(nodename[nodename_len - 1]))
- hints.ai_family = AF_INET;
- else
- hints.ai_family = AF_UNSPEC;
-
- /*
- ** Try to match against each clusternode in cluster.conf.
- */
- for (i = 1;; i++) {
- char canonical_name[128];
- unsigned int altcnt;
-
- ret = snprintf(path, sizeof(path),
- "/cluster/clusternodes/clusternode[%u]/@name",
- i);
- if (ret < 0 || (size_t) ret >= sizeof(path))
- continue;
-
- for (altcnt = 0;; altcnt++) {
- size_t len;
- struct addrinfo *ai = NULL;
- char cur_node[128];
-
- if (altcnt != 0) {
- ret = snprintf(path, sizeof(path),
- "/cluster/clusternodes/clusternode[%u]/altname[%u]/@name",
- i, altcnt);
- if (ret < 0 || (size_t) ret >= sizeof(path))
- continue;
- }
-
- str = NULL;
- error = ccs_get(cd, path, &str);
- if (error || !str) {
- if (altcnt == 0)
- goto out_fail;
- break;
- }
-
- if (altcnt == 0) {
- if (strlen(str) >= sizeof(canonical_name)) {
- free(str);
- errno = E2BIG;
- return (-E2BIG);
- }
- strcpy(canonical_name, str);
- }
-
- if (strlen(str) >= sizeof(cur_node)) {
- free(str);
- errno = E2BIG;
- return (-E2BIG);
- }
-
- strcpy(cur_node, str);
-
- p = strchr(cur_node, '.');
- if (p != NULL)
- len = p - cur_node;
- else
- len = strlen(cur_node);
-
- if (strlen(host_only) == len &&
- !strncasecmp(host_only, cur_node, len)) {
- free(str);
- *retval = strdup(canonical_name);
- if (*retval == NULL) {
- errno = ENOMEM;
- return (-ENOMEM);
- }
- return (0);
- }
-
- if (getaddrinfo(str, NULL, &hints, &ai) == 0) {
- struct addrinfo *cur;
-
- for (cur = ai; cur != NULL; cur = cur->ai_next) {
- char hostbuf[512];
- if (getnameinfo
- (cur->ai_addr, cur->ai_addrlen,
- hostbuf, sizeof(hostbuf), NULL, 0,
- hints.ai_family !=
- AF_UNSPEC ? NI_NUMERICHOST : 0)) {
- continue;
- }
-
- if (!strcasecmp(hostbuf, nodename)) {
- freeaddrinfo(ai);
- free(str);
- *retval =
- strdup(canonical_name);
- if (*retval == NULL) {
- errno = ENOMEM;
- return (-ENOMEM);
- }
- return (0);
- }
- }
- freeaddrinfo(ai);
- }
-
- free(str);
-
- /* Now try any altnames */
- }
- }
-
-out_fail:
- errno = EINVAL;
- *retval = NULL;
- return (-1);
-}
-
-static int facility_id_get(char *name)
-{
- unsigned int i;
-
- for (i = 0; facilitynames[i].c_name != NULL; i++) {
- if (strcasecmp(name, facilitynames[i].c_name) == 0) {
- return (facilitynames[i].c_val);
- }
- }
- return (-1);
-}
-
-static int priority_id_get(char *name)
-{
- unsigned int i;
-
- for (i = 0; prioritynames[i].c_name != NULL; i++) {
- if (strcasecmp(name, prioritynames[i].c_name) == 0) {
- return (prioritynames[i].c_val);
- }
- }
- return (-1);
-}
-
-/* requires string buffer to be PATH_MAX */
-static void read_string(int fd, const char *path, char *string)
-{
- char *str;
- int error;
-
- memset(string, 0, PATH_MAX);
-
- error = ccs_get(fd, path, &str);
- if (error || !str)
- return;
-
- strcpy(string, str);
-
- free(str);
-}
-
-static void read_yesno(int fd, const char *path, int *yes, int *no)
-{
- char *str;
- int error;
-
- *yes = 0;
- *no = 0;
-
- error = ccs_get(fd, path, &str);
- if (error || !str)
- return;
-
- if (!strcmp(str, "yes"))
- *yes = 1;
- else if (!strcmp(str, "no"))
- *no = 1;
-
- free(str);
-}
-
-static void read_onoff(int fd, const char *path, int *on, int *off)
-{
- char *str;
- int error;
-
- *on = 0;
- *off = 0;
-
- error = ccs_get(fd, path, &str);
- if (error || !str)
- return;
-
- if (!strcmp(str, "on"))
- *on = 1;
- else if (!strcmp(str, "off"))
- *off = 1;
-
- free(str);
-}
-
-/* requires path buffer to be PATH_MAX */
-static void create_daemon_path(const char *name, const char *field, char *path)
-{
- memset(path, 0, PATH_MAX);
- snprintf(path, PATH_MAX,
- "/cluster/logging/logging_daemon[@name=\"%s\"]/@%s",
- name, field);
-}
-
-/* Values should be initialized to default values before calling
- this function; they are not changed if cluster.conf has nothing
- to say about them. If *debug is already set , then *logfile_priority
- is set to LOG_DEBUG; all debug and logfile_priority values from
- cluster.conf are ignored. */
-
-void ccs_read_logging(int fd, const char *name, int *debug, int *mode,
- int *syslog_facility, int *syslog_priority,
- int *logfile_priority, char *logfile)
-{
- char string[PATH_MAX];
- char path[PATH_MAX];
- int val, y, n, on, off;
-
- /*
- * to_syslog
- */
- create_daemon_path(name, "to_syslog", path);
-
- read_yesno(fd, "/cluster/logging/@to_syslog", &y, &n);
- if (y)
- *mode |= LOG_MODE_OUTPUT_SYSLOG;
- if (n)
- *mode &= ~LOG_MODE_OUTPUT_SYSLOG;
-
- read_yesno(fd, path, &y, &n);
- if (y)
- *mode |= LOG_MODE_OUTPUT_SYSLOG;
- if (n)
- *mode &= ~LOG_MODE_OUTPUT_SYSLOG;
-
- /*
- * to_logfile
- */
- create_daemon_path(name, "to_logfile", path);
-
- read_yesno(fd, "/cluster/logging/@to_logfile", &y, &n);
- if (y)
- *mode |= LOG_MODE_OUTPUT_FILE;
- if (n)
- *mode &= ~LOG_MODE_OUTPUT_FILE;
-
- read_yesno(fd, path, &y, &n);
- if (y)
- *mode |= LOG_MODE_OUTPUT_FILE;
- if (n)
- *mode &= ~LOG_MODE_OUTPUT_FILE;
-
- /*
- * syslog_facility
- */
- create_daemon_path(name, "syslog_facility", path);
-
- read_string(fd, "/cluster/logging/@syslog_facility", string);
-
- if (string[0]) {
- val = facility_id_get(string);
- if (val >= 0)
- *syslog_facility = val;
- }
-
- read_string(fd, path, string);
-
- if (string[0]) {
- val = facility_id_get(string);
- if (val >= 0)
- *syslog_facility = val;
- }
-
- /*
- * syslog_priority
- */
- create_daemon_path(name, "syslog_priority", path);
-
- read_string(fd, "/cluster/logging/@syslog_priority", string);
-
- if (string[0]) {
- val = priority_id_get(string);
- if (val >= 0)
- *syslog_priority = val;
- }
-
- read_string(fd, path, string);
-
- if (string[0]) {
- val = priority_id_get(string);
- if (val >= 0)
- *syslog_priority = val;
- }
-
- /*
- * logfile
- */
- create_daemon_path(name, "logfile", path);
-
- read_string(fd, "/cluster/logging/@logfile", string);
-
- if (string[0])
- strcpy(logfile, string);
-
- read_string(fd, path, string);
-
- if (string[0])
- strcpy(logfile, string);
-
- /*
- * debug is only ever turned on, not off, so if it's already on
- * (from the daemon), then just skip the debug lookups.
- */
- if (*debug) {
- *logfile_priority = LOG_DEBUG;
- return;
- }
-
- /*
- * debug
- * debug=on is a shortcut for logfile_priority=LOG_DEBUG
- */
- create_daemon_path(name, "debug", path);
-
- read_onoff(fd, "/cluster/logging/@debug", &on, &off);
- if (on)
- *debug = 1;
-
- read_onoff(fd, path, &on, &off);
- if (on)
- *debug = 1;
- else if (off)
- *debug = 0;
-
- if (*debug) {
- *logfile_priority = LOG_DEBUG;
- return;
- }
-
- /*
- * logfile_priority
- */
- create_daemon_path(name, "logfile_priority", path);
-
- read_string(fd, "/cluster/logging/@logfile_priority", string);
-
- if (string[0]) {
- val = priority_id_get(string);
- if (val >= 0)
- *logfile_priority = val;
- }
-
- read_string(fd, path, string);
-
- if (string[0]) {
- val = priority_id_get(string);
- if (val >= 0)
- *logfile_priority = val;
- }
-}
-
diff --git a/config/libs/libccsconfdb/fullxpath.c b/config/libs/libccsconfdb/fullxpath.c
deleted file mode 100644
index 86d4f59..0000000
--- a/config/libs/libccsconfdb/fullxpath.c
+++ /dev/null
@@ -1,363 +0,0 @@
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <corosync/corotypes.h>
-#include <corosync/confdb.h>
-#include <libxml/parser.h>
-#include <libxml/xpath.h>
-
-#include "ccs.h"
-#include "ccs_internal.h"
-
-#ifndef XMLBUFSIZE
-#define XMLBUFSIZE 64000
-#endif
-
-int fullxpath = 0;
-
-static xmlDocPtr doc = NULL;
-static xmlXPathContextPtr ctx = NULL;
-
-static int add_to_buffer(char *data, char **buffer, int *bufsize)
-{
- int datalen = 0, bufferlen = 0;
- char *newbuf = NULL;
-
- datalen = strlen(data);
- bufferlen = strlen(*buffer);
-
- if (datalen) {
- if ((bufferlen + datalen) >= *bufsize) {
- newbuf = malloc((*bufsize * 2));
- if (!newbuf) {
- errno = ENOMEM;
- return -1;
- }
- *bufsize = *bufsize * 2;
- memset(newbuf, 0, *bufsize);
- memcpy(newbuf, *buffer, bufferlen);
- free(*buffer);
- *buffer = newbuf;
- }
- strncpy(*buffer + bufferlen, data, datalen);
- }
- return 0;
-}
-
-static int dump_objdb_buff(confdb_handle_t dump_handle, hdb_handle_t cluster_handle,
- hdb_handle_t parent_object_handle, char **buffer,
- int *bufsize)
-{
- hdb_handle_t object_handle;
- char temp[PATH_MAX];
- char object_name[PATH_MAX];
- char key_name[PATH_MAX];
- char *key_value = NULL;
- size_t key_value_len = 0, object_name_len = 0;
- confdb_value_types_t type;
- int res;
-
- res = confdb_key_iter_start(dump_handle, parent_object_handle);
- if (res != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- if (!*buffer || ((*buffer) && !strlen(*buffer))) {
- snprintf(temp, PATH_MAX - 1,
- "<?xml version=\"1.0\"?>\n<cluster");
- if (add_to_buffer(temp, buffer, bufsize))
- return -1;
- }
-
- while ((res =
- confdb_key_iter_typed2(dump_handle, parent_object_handle, key_name,
- (void **)&key_value,
- &key_value_len, &type)) == CS_OK) {
- int char_pos = 0;
- key_value[key_value_len] = '\0';
-
- snprintf(temp, PATH_MAX - 1, " %s=\"", key_name);
- if (add_to_buffer(temp, buffer, bufsize)) {
- free(key_value);
- return -1;
- }
-
- for (char_pos = 0; char_pos < key_value_len-1; char_pos++) {
- switch (key_value[char_pos]) {
-
- case '&':
- snprintf(temp, PATH_MAX - 1, "&");
- break;
- case '<':
- snprintf(temp, PATH_MAX - 1, "<");
- break;
- case '>':
- snprintf(temp, PATH_MAX - 1, ">");
- break;
- case '"':
- snprintf(temp, PATH_MAX - 1, """);
- break;
- case '\'':
- snprintf(temp, PATH_MAX - 1, "'");
- break;
- default:
- temp[0] = key_value[char_pos];
- temp[1] = '\0';
- break;
- }
- if (add_to_buffer(temp, buffer, bufsize)) {
- free(key_value);
- return -1;
- }
- }
- free(key_value);
- key_value = NULL;
-
- snprintf(temp, PATH_MAX - 1, "\"");
- if (add_to_buffer(temp, buffer, bufsize))
- return -1;
- }
-
- if (parent_object_handle > 0) {
- snprintf(temp, PATH_MAX - 1, ">\n");
- if (add_to_buffer(temp, buffer, bufsize))
- return -1;
- }
-
- res = confdb_object_iter_start(dump_handle, parent_object_handle);
- if (res != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- while ((res =
- confdb_object_iter(dump_handle, parent_object_handle,
- &object_handle, object_name,
- &object_name_len)) == CS_OK) {
- hdb_handle_t parent;
-
- res =
- confdb_object_parent_get(dump_handle, object_handle,
- &parent);
- if (res != CS_OK) {
- errno = EINVAL;
- return -1;
- }
-
- object_name[object_name_len] = '\0';
-
- snprintf(temp, PATH_MAX - 1, "<%s", object_name);
- if (add_to_buffer(temp, buffer, bufsize))
- return -1;
-
- res =
- dump_objdb_buff(dump_handle, cluster_handle, object_handle, buffer,
- bufsize);
- if (res) {
- errno = res;
- return res;
- }
-
- if (object_handle != parent_object_handle) {
- snprintf(temp, PATH_MAX - 1, "</%s>\n", object_name);
- if (add_to_buffer(temp, buffer, bufsize))
- return -1;
- } else {
- snprintf(temp, PATH_MAX - 1, ">\n");
- if (add_to_buffer(temp, buffer, bufsize))
- return -1;
- }
- }
-
- if (parent_object_handle == cluster_handle) {
- snprintf(temp, PATH_MAX - 1, "</cluster>\n");
- if (add_to_buffer(temp, buffer, bufsize))
- return -1;
- }
-
- return 0;
-}
-
-int xpathfull_init(confdb_handle_t handle)
-{
- int size = XMLBUFSIZE;
- char *buffer, *newbuf;
- hdb_handle_t cluster_handle;
-
- newbuf = buffer = malloc(XMLBUFSIZE);
- if (!buffer) {
- errno = ENOMEM;
- goto fail;
- }
-
- memset(buffer, 0, XMLBUFSIZE);
-
- if (confdb_object_find_start(handle, OBJECT_PARENT_HANDLE) != CS_OK)
- goto fail;
-
- if (confdb_object_find(handle, OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"), &cluster_handle) != CS_OK)
- goto fail;
-
- if (dump_objdb_buff(handle, cluster_handle, cluster_handle, &newbuf, &size))
- goto fail;
-
- if (newbuf != buffer) {
- buffer = newbuf;
- newbuf = NULL;
- }
-
- doc = xmlParseMemory(buffer, strlen(buffer));
- if (!doc)
- goto fail;
-
- free(buffer);
-
- ctx = xmlXPathNewContext(doc);
- if (!ctx) {
- xmlFreeDoc(doc);
- goto fail;
- }
-
- return 0;
-
-fail:
- return -1;
-}
-
-void xpathfull_finish()
-{
- if (ctx) {
- xmlXPathFreeContext(ctx);
- ctx = NULL;
- }
- if (doc) {
- xmlFreeDoc(doc);
- doc = NULL;
- }
- return;
-}
-
-/**
- * _ccs_get_fullxpath
- * @desc:
- * @query:
- * @rtn: value returned
- * @list: 1 to operate in list fashion
- *
- * This function will allocate space for the value that is the result
- * of the given query. It is the user's responsibility to ensure that
- * the data returned is freed.
- *
- * Returns: char * to result or NULL in case of failure.
- */
-char *_ccs_get_fullxpath(confdb_handle_t handle, hdb_handle_t connection_handle,
- const char *query, int list)
-{
- xmlXPathObjectPtr obj = NULL;
- char previous_query[PATH_MAX];
- hdb_handle_t list_handle = 0;
- unsigned int xmllistindex = 0;
- int prev = 0;
- char *rtn = NULL;
-
- errno = 0;
-
- if (strncmp(query, "/", 1)) {
- errno = EINVAL;
- goto fail;
- }
-
- memset(previous_query, 0, PATH_MAX);
-
- prev =
- get_previous_query(handle, connection_handle, previous_query,
- &list_handle);
-
- if (list && !prev && !strcmp(query, previous_query)) {
- if (confdb_key_increment
- (handle, connection_handle, "iterator_tracker",
- strlen("iterator_tracker"), &xmllistindex) != CS_OK) {
- xmllistindex = 0;
- } else {
- xmllistindex--;
- }
- } else {
- reset_iterator(handle, connection_handle);
- xmllistindex = 0;
- }
-
- obj = xmlXPathEvalExpression((xmlChar *) query, ctx);
-
- if (!obj) {
- errno = EINVAL;
- goto fail;
- }
-
- if (obj->nodesetval && (obj->nodesetval->nodeNr > 0)) {
- xmlNodePtr node;
- int size = 0, nnv = 0;
-
- if (xmllistindex >= obj->nodesetval->nodeNr) {
- reset_iterator(handle, connection_handle);
- errno = ENODATA;
- goto fail;
- }
-
- node = obj->nodesetval->nodeTab[xmllistindex];
-
- if (!node) {
- errno = ENODATA;
- goto fail;
- }
-
- if (((node->type == XML_ATTRIBUTE_NODE) && strstr(query, "@*"))
- || ((node->type == XML_ELEMENT_NODE)
- && strstr(query, "child::*"))) {
- if (node->children && node->children->content)
- size = strlen((char *)node->children->content) +
- strlen((char *)node->name) + 2;
- else
- size = strlen((char *)node->name) + 2;
-
- nnv = 1;
- } else {
- if (node->children && node->children->content)
- size =
- strlen((char *)node->children->content) + 1;
-
- else {
- errno = ENODATA;
- goto fail;
- }
- }
-
- rtn = malloc(size);
-
- if (!rtn) {
- errno = ENOMEM;
- goto fail;
- }
-
- if (nnv)
- sprintf(rtn, "%s=%s", node->name,
- node->children ? (char *)node->children->
- content : "");
- else
- sprintf(rtn, "%s",
- node->children ? node->children->
- content : node->name);
-
- if (list)
- set_previous_query(handle, connection_handle,
- (char *)query, OBJECT_PARENT_HANDLE);
-
- } else
- errno = EINVAL;
-
-fail:
- if (obj)
- xmlXPathFreeObject(obj);
-
- return rtn;
-}
diff --git a/config/libs/libccsconfdb/libccs.c b/config/libs/libccsconfdb/libccs.c
deleted file mode 100644
index 6a2b143..0000000
--- a/config/libs/libccsconfdb/libccs.c
+++ /dev/null
@@ -1,648 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <corosync/corotypes.h>
-#include <corosync/confdb.h>
-
-#include "ccs.h"
-#include "ccs_internal.h"
-
-/* Callbacks are not supported - we will use them to update fullxml doc/ctx */
-static confdb_callbacks_t callbacks = {
-};
-
-/* helper functions */
-
-static confdb_handle_t confdb_connect(void)
-{
- confdb_handle_t handle = 0;
-
- if (confdb_initialize(&handle, &callbacks) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- return handle;
-}
-
-static int confdb_disconnect(confdb_handle_t handle)
-{
- if (confdb_finalize(handle) != CS_OK) {
- errno = EINVAL;
- return -1;
- }
- return 0;
-}
-
-static hdb_handle_t find_libccs_handle(confdb_handle_t handle)
-{
- hdb_handle_t libccs_handle = 0;
-
- if (confdb_object_find_start(handle, OBJECT_PARENT_HANDLE) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- if (confdb_object_find
- (handle, OBJECT_PARENT_HANDLE, "libccs", strlen("libccs"),
- &libccs_handle) != CS_OK) {
- errno = ENOENT;
- return -1;
- }
-
- confdb_object_find_destroy(handle, OBJECT_PARENT_HANDLE);
-
- return libccs_handle;
-}
-
-static hdb_handle_t find_ccs_handle(confdb_handle_t handle, int ccs_handle)
-{
- int res, found = 0;
- hdb_handle_t libccs_handle = 0, connection_handle = 0;
- char data[128];
- size_t datalen = 0;
-
- libccs_handle = find_libccs_handle(handle);
- if (libccs_handle == -1)
- return -1;
-
- if (confdb_object_find_start(handle, libccs_handle) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- while (confdb_object_find
- (handle, libccs_handle, "connection", strlen("connection"),
- &connection_handle) == CS_OK) {
- memset(data, 0, sizeof(data));
- if (confdb_key_get
- (handle, connection_handle, "ccs_handle",
- strlen("ccs_handle"), data, &datalen) == CS_OK) {
- res = atoi(data);
- if (res == ccs_handle) {
- found = 1;
- break;
- }
- }
- }
-
- confdb_object_find_destroy(handle, libccs_handle);
-
- if (found) {
- return connection_handle;
- } else {
- errno = ENOENT;
- return -1;
- }
-}
-
-static int destroy_ccs_handle(confdb_handle_t handle,
- hdb_handle_t connection_handle)
-{
- if (confdb_object_destroy(handle, connection_handle) != CS_OK) {
- errno = EINVAL;
- return -1;
- }
-
- return 0;
-}
-
-static int get_running_config_version(confdb_handle_t handle, int *config_version)
-{
- hdb_handle_t cluster_handle;
- char data[128];
- size_t datalen = 0;
- int ret = -1;
-
- if (confdb_object_find_start(handle, OBJECT_PARENT_HANDLE) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- if (confdb_object_find
- (handle, OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"),
- &cluster_handle) == CS_OK) {
- memset(data, 0, sizeof(data));
- if (confdb_key_get
- (handle, cluster_handle, "config_version",
- strlen("config_version"), data, &datalen) == CS_OK) {
- *config_version = atoi(data);
- ret = 0;
- }
- }
-
- confdb_object_find_destroy(handle, OBJECT_PARENT_HANDLE);
-
- if (ret < 0)
- errno = ENODATA;
-
- return ret;
-}
-
-static int get_stored_config_version(confdb_handle_t handle,
- hdb_handle_t connection_handle, int *config_version)
-{
- char data[128];
- size_t datalen = 0;
- int ret = -1;
-
- if (confdb_key_get
- (handle, connection_handle, "config_version",
- strlen("config_version"), data, &datalen) == CS_OK) {
- *config_version = atoi(data);
- ret = 0;
- }
-
- if (ret < 0)
- errno = ENODATA;
-
- return ret;
-}
-
-static int set_stored_config_version(confdb_handle_t handle,
- hdb_handle_t connection_handle, int new_version)
-{
- char temp[PATH_MAX];
- size_t templen = 0;
- char data[128];
-
- memset(data, 0, sizeof(data));
- snprintf(data, sizeof(data), "%d", new_version);
-
- if (confdb_key_get
- (handle, connection_handle, "config_version",
- strlen("config_version"), temp, &templen) == CS_OK) {
- if (confdb_key_replace
- (handle, connection_handle, "config_version",
- strlen("config_version"), temp, templen, data,
- strlen(data) + 1) == CS_OK) {
- return 0;
- }
- }
-
- return -1;
-}
-
-static int config_reload(confdb_handle_t handle,
- hdb_handle_t connection_handle, int fullxpathint)
-{
- int running_version;
- int stored_version;
-
- if (get_running_config_version(handle, &running_version) < 0)
- return -1;
-
- if (get_stored_config_version(handle, connection_handle, &stored_version) < 0)
- return -1;
-
- if (running_version == stored_version)
- return 0;
-
- if (fullxpathint) {
- xpathfull_finish();
- if (xpathfull_init(handle))
- return -1;
- }
-
- reset_iterator(handle, connection_handle);
-
- if (set_previous_query(handle, connection_handle, "", 0))
- return -1;
-
- if (set_stored_config_version(handle, connection_handle, running_version))
- return -1;
-
- return 0;
-}
-
-static hdb_handle_t create_ccs_handle(confdb_handle_t handle, int ccs_handle,
- int xpath)
-{
- hdb_handle_t libccs_handle = 0, connection_handle = 0;
- char buf[128];
- int config_version = 0;
-
- libccs_handle = find_libccs_handle(handle);
- if (libccs_handle == -1)
- return -1;
-
- if (get_running_config_version(handle, &config_version) < 0)
- return -1;
-
- if (confdb_object_create
- (handle, libccs_handle, "connection", strlen("connection"),
- &connection_handle) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "%d", ccs_handle);
- if (confdb_key_create_typed
- (handle, connection_handle, "ccs_handle", buf,
- strlen(buf) + 1, CONFDB_VALUETYPE_STRING) != CS_OK) {
- destroy_ccs_handle(handle, connection_handle);
- errno = ENOMEM;
- return -1;
- }
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "%d", config_version);
- if (confdb_key_create_typed
- (handle, connection_handle, "config_version",
- buf, strlen(buf) + 1, CONFDB_VALUETYPE_STRING) != CS_OK) {
- destroy_ccs_handle(handle, connection_handle);
- errno = ENOMEM;
- return -1;
- }
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "%d", xpath);
- if (confdb_key_create_typed
- (handle, connection_handle, "fullxpath", buf,
- strlen(buf) + 1, CONFDB_VALUETYPE_STRING) != CS_OK) {
- destroy_ccs_handle(handle, connection_handle);
- errno = ENOMEM;
- return -1;
- }
-
- return connection_handle;
-}
-
-static hdb_handle_t get_ccs_handle(confdb_handle_t handle, int *ccs_handle,
- int xpath)
-{
- unsigned int next_handle;
- hdb_handle_t libccs_handle = 0;
- hdb_handle_t ret = 0;
-
- libccs_handle = find_libccs_handle(handle);
- if (libccs_handle == -1)
- return -1;
-
- if (confdb_key_increment
- (handle, libccs_handle, "next_handle", strlen("next_handle"),
- &next_handle) == CS_OK) {
- ret = create_ccs_handle(handle, (int)next_handle, xpath);
- if (ret == -1) {
- *ccs_handle = -1;
- return ret;
- }
-
- *ccs_handle = (int)next_handle;
- return ret;
- }
-
- *ccs_handle = -1;
- errno = ENOMEM;
- return -1;
-}
-
-int get_previous_query(confdb_handle_t handle, hdb_handle_t connection_handle,
- char *previous_query, hdb_handle_t *query_handle)
-{
- size_t datalen = 0;
-
- if (confdb_key_get
- (handle, connection_handle, "previous_query",
- strlen("previous_query"), previous_query, &datalen) == CS_OK) {
- if (confdb_key_get
- (handle, connection_handle, "query_handle",
- strlen("query_handle"), query_handle,
- &datalen) == CS_OK) {
- return 0;
- }
- }
- errno = ENOENT;
- return -1;
-}
-
-int set_previous_query(confdb_handle_t handle, hdb_handle_t connection_handle,
- const char *previous_query, hdb_handle_t query_handle)
-{
- char temp[PATH_MAX];
- size_t templen = 0;
- hdb_handle_t temphandle;
- unsigned int temptracker;
-
- if (confdb_key_get
- (handle, connection_handle, "previous_query",
- strlen("previous_query"), temp, &templen) == CS_OK) {
- if (strcmp(previous_query, temp)) {
- if (confdb_key_replace
- (handle, connection_handle, "previous_query",
- strlen("previous_query"), temp, templen,
- previous_query,
- strlen(previous_query) + 1) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
- } else {
- if (confdb_key_create_typed
- (handle, connection_handle, "previous_query",
- previous_query,
- strlen(previous_query) + 1, CONFDB_VALUETYPE_STRING) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
-
- if (confdb_key_get
- (handle, connection_handle, "query_handle", strlen("query_handle"),
- &temphandle, &templen) == CS_OK) {
- if (temphandle != query_handle) {
- if (confdb_key_replace
- (handle, connection_handle, "query_handle",
- strlen("query_handle"), &temphandle,
- sizeof(hdb_handle_t), &query_handle,
- sizeof(hdb_handle_t)) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
- } else {
- if (confdb_key_create_typed
- (handle, connection_handle, "query_handle",
- &query_handle,
- sizeof(hdb_handle_t), CONFDB_VALUETYPE_UINT64) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
-
- if (confdb_key_get
- (handle, connection_handle, "iterator_tracker",
- strlen("iterator_tracker"), &temptracker, &templen) != CS_OK) {
- temptracker = 1;
- if (confdb_key_create_typed
- (handle, connection_handle, "iterator_tracker",
- &temptracker, sizeof(unsigned int), CONFDB_VALUETYPE_UINT32) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
-
- return 0;
-}
-
-void reset_iterator(confdb_handle_t handle, hdb_handle_t connection_handle)
-{
- unsigned int value = 0;
-
- if (confdb_key_increment
- (handle, connection_handle, "iterator_tracker",
- strlen("iterator_tracker"), &value) != CS_OK)
- return;
-
- confdb_key_delete(handle, connection_handle, "iterator_tracker",
- strlen("iterator_tracker"), &value,
- sizeof(unsigned int));
-
- return;
-}
-
-static int check_cluster_name(int ccs_handle, const char *cluster_name)
-{
- confdb_handle_t handle = 0;
- hdb_handle_t cluster_handle;
- char data[128];
- int found = 0;
- size_t datalen = 0;
-
- handle = confdb_connect();
- if (handle < 0)
- return -1;
-
- if (confdb_object_find_start(handle, OBJECT_PARENT_HANDLE) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
-
- while (confdb_object_find
- (handle, OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"),
- &cluster_handle) == CS_OK) {
- memset(data, 0, sizeof(data));
- if (confdb_key_get
- (handle, cluster_handle, "name", strlen("name"), data,
- &datalen) == CS_OK) {
- if (!strncmp(data, cluster_name, datalen)) {
- found = 1;
- break;
- }
- }
- }
-
- confdb_object_find_destroy(handle, OBJECT_PARENT_HANDLE);
-
- confdb_disconnect(handle);
-
- if (found) {
- return ccs_handle;
- } else {
- errno = ENOENT;
- return -1;
- }
-}
-
-/**
- * _ccs_get
- * @desc:
- * @query:
- * @rtn: value returned
- * @list: 1 to operate in list fashion
- *
- * This function will allocate space for the value that is the result
- * of the given query. It is the user's responsibility to ensure that
- * the data returned is freed.
- *
- * Returns: 0 on success, < 0 on failure
- */
-static int _ccs_get(int desc, const char *query, char **rtn, int list)
-{
- confdb_handle_t handle = 0;
- hdb_handle_t connection_handle = 0;
- char data[128];
- size_t datalen = 0;
- int fullxpathint = 0;
-
- *rtn = NULL;
-
- handle = confdb_connect();
- if (handle < 0)
- return -1;
-
- connection_handle = find_ccs_handle(handle, desc);
- if (connection_handle == -1)
- goto fail;
-
- memset(data, 0, sizeof(data));
- if (confdb_key_get
- (handle, connection_handle, "fullxpath", strlen("fullxpath"), &data,
- &datalen) != CS_OK) {
- errno = EINVAL;
- goto fail;
- } else
- fullxpathint = atoi(data);
-
- if (config_reload(handle, connection_handle, fullxpathint) < 0)
- goto fail;
-
- if (!fullxpathint)
- *rtn =
- _ccs_get_xpathlite(handle, connection_handle, query, list);
- else
- *rtn =
- _ccs_get_fullxpath(handle, connection_handle, query, list);
-
-fail:
- confdb_disconnect(handle);
-
- if (!*rtn)
- return -1;
-
- return 0;
-}
-
-/**** PUBLIC API ****/
-
-/**
- * ccs_connect
- *
- * Returns: ccs_desc on success, < 0 on failure
- */
-int ccs_connect(void)
-{
- confdb_handle_t handle = 0;
- int ccs_handle = 0;
-
- handle = confdb_connect();
- if (handle == -1)
- return handle;
-
- get_ccs_handle(handle, &ccs_handle, fullxpath);
- if (ccs_handle < 0)
- goto fail;
-
- if (fullxpath) {
- if (xpathfull_init(handle)) {
- ccs_disconnect(ccs_handle);
- return -1;
- }
- }
-
-fail:
- confdb_disconnect(handle);
-
- return ccs_handle;
-}
-
-/**
- * ccs_force_connect
- *
- * @cluster_name: verify that we are trying to connect to the requested cluster (tbd)
- * @blocking: retry connection forever
- *
- * Returns: ccs_desc on success, < 0 on failure
- */
-int ccs_force_connect(const char *cluster_name, int blocking)
-{
- int res = -1;
-
- if (blocking) {
- while (res < 0) {
- res = ccs_connect();
- if (res < 0)
- sleep(1);
- }
- } else {
- res = ccs_connect();
- if (res < 0)
- return res;
- }
- if (cluster_name)
- return check_cluster_name(res, cluster_name);
- else
- return res;
-}
-
-/**
- * ccs_disconnect
- *
- * @desc: the descriptor returned by ccs_connect
- *
- * Returns: 0 on success, < 0 on error
- */
-int ccs_disconnect(int desc)
-{
- confdb_handle_t handle = 0;
- hdb_handle_t connection_handle = 0;
- int ret;
- char data[128];
- size_t datalen = 0;
- int fullxpathint = 0;
-
- handle = confdb_connect();
- if (handle <= 0)
- return handle;
-
- connection_handle = find_ccs_handle(handle, desc);
- if (connection_handle == -1) {
- ret = -1;
- goto fail;
- }
-
- memset(data, 0, sizeof(data));
- if (confdb_key_get
- (handle, connection_handle, "fullxpath", strlen("fullxpath"), &data,
- &datalen) != CS_OK) {
- errno = EINVAL;
- ret = -1;
- goto fail;
- } else
- fullxpathint = atoi(data);
-
- if (fullxpathint)
- xpathfull_finish();
-
- ret = destroy_ccs_handle(handle, connection_handle);
-
-fail:
- confdb_disconnect(handle);
- return ret;
-}
-
-/* see _ccs_get */
-int ccs_get(int desc, const char *query, char **rtn)
-{
- return _ccs_get(desc, query, rtn, 0);
-}
-
-/* see _ccs_get */
-int ccs_get_list(int desc, const char *query, char **rtn)
-{
- return _ccs_get(desc, query, rtn, 1);
-}
-
-/**
- * ccs_set: set an individual element's value in the config file.
- * @desc:
- * @path:
- * @val:
- *
- * This function is used to update individual elements in a config file.
- * It's effects are cluster wide. It only succeeds when the node is part
- * of a quorate cluster.
- *
- * Note currently implemented.
- *
- * Returns: 0 on success, < 0 on failure
- */
-int ccs_set(int desc, const char *path, char *val)
-{
- errno = ENOSYS;
- return -1;
-}
diff --git a/config/libs/libccsconfdb/libccs.pc.in b/config/libs/libccsconfdb/libccs.pc.in
deleted file mode 100644
index eddc87f..0000000
--- a/config/libs/libccsconfdb/libccs.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: libccs
-Version: @VERSION@
-Description: Cluster Config library
-Requires:
-Libs: -L${libdir} -lccs
-Cflags: -I${includedir}
diff --git a/config/libs/libccsconfdb/xpathlite.c b/config/libs/libccsconfdb/xpathlite.c
deleted file mode 100644
index 44bf346..0000000
--- a/config/libs/libccsconfdb/xpathlite.c
+++ /dev/null
@@ -1,444 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <corosync/corotypes.h>
-#include <corosync/confdb.h>
-
-#include "ccs.h"
-#include "ccs_internal.h"
-
-static int tokenizer(char *current_query)
-{
- int tokens = 0;
- char *curpos = current_query;
- char *next = NULL;
- char *end;
-
- end = current_query + strlen(current_query);
-
- while (curpos <= end) {
- tokens++;
-
- if (strncmp(curpos, "/", 1)) {
- errno = EINVAL;
- return -1;
- }
-
- memset(curpos, 0, 1);
- curpos = curpos + 1;
-
- next = strstr(curpos, "/");
- if (next == curpos) {
- errno = EINVAL;
- return -1;
- }
-
- if (!next)
- return tokens;
-
- if ((strstr(curpos, "[") > next) || !strstr(curpos, "["))
- curpos = next;
- else
- curpos = strstr(strstr(curpos, "]"), "/");
-
- }
- errno = EINVAL;
- return -1;
-}
-
-/*
- * return 0 on success
- * return -1 on errors
- */
-static int path_dive(confdb_handle_t handle, hdb_handle_t *query_handle,
- char *current_query, int tokens)
-{
- char *pos = NULL, *next = NULL;
- int i;
- hdb_handle_t new_obj_handle;
- confdb_value_types_t type;
-
- pos = current_query + 1;
-
- for (i = 1; i <= tokens; i++) {
- if (confdb_object_find_start(handle, *query_handle) !=
- CS_OK)
- goto fail;
-
- next = pos + strlen(pos) + 1;
-
- if (!strstr(pos, "[")) {
- /* straight path diving */
- if (confdb_object_find
- (handle, *query_handle, pos, strlen(pos),
- &new_obj_handle) != CS_OK)
- goto fail;
- else {
- confdb_object_find_destroy(handle,
- *query_handle);
- *query_handle = new_obj_handle;
- }
- } else {
- /*
- * /something[int]/ or /something[@foo="bar"]/
- * start and end will identify []
- * middle will point to the inside request
- */
-
- char *start = NULL, *middle = NULL, *end = NULL;
- char *key_value = NULL;
- size_t valuelen;
- char data[PATH_MAX];
- size_t datalen = 0;
-
- /*
- * those ones should be always good because
- * the tokenizer takes care of them
- */
-
- start = strstr(pos, "[");
- if (!start)
- goto fail;
-
- end = strstr(pos, "]");
- if (!end)
- goto fail;
-
- middle = start + 1;
- memset(start, 0, 1);
- memset(end, 0, 1);
-
- if (!strcmp(pos, "child::*")) {
- int val, j;
-
- val = atoi(middle);
-
- if (val < 1)
- goto fail;
-
- if (confdb_object_iter_start
- (handle, *query_handle) != CS_OK)
- goto fail;
-
- for (j = 1; j <= val; j++) {
- if (confdb_object_iter
- (handle, *query_handle,
- &new_obj_handle, data,
- &datalen) != CS_OK)
- goto fail;
- }
- confdb_object_iter_destroy(handle,
- *query_handle);
- confdb_object_find_destroy(handle,
- *query_handle);
- *query_handle = new_obj_handle;
-
- } else if (!strstr(middle, "@")) {
- /* lookup something with index num = int */
- int val, j;
-
- val = atoi(middle);
-
- if (val < 1)
- goto fail;
-
- for (j = 1; j <= val; j++) {
- if (confdb_object_find
- (handle, *query_handle, pos,
- strlen(pos),
- &new_obj_handle) != CS_OK)
- goto fail;
- }
- confdb_object_find_destroy(handle,
- *query_handle);
- *query_handle = new_obj_handle;
-
- } else {
- /* lookup something with obj foo = bar */
- char *equal = NULL, *value = NULL, *tmp = NULL;
- int goout = 0;
-
- equal = strstr(middle, "=");
- if (!equal)
- goto fail;
-
- memset(equal, 0, 1);
-
- value = strstr(equal + 1, "\"");
- if (!value)
- goto fail;
-
- value = value + 1;
-
- tmp = strstr(value, "\"");
- if (!tmp)
- goto fail;
-
- memset(tmp, 0, 1);
-
- middle = strstr(middle, "@") + 1;
- if (!middle)
- goto fail;
-
- // middle points to foo
- // value to bar
-
- memset(data, 0, PATH_MAX);
- while (!goout) {
- if (confdb_object_find
- (handle, *query_handle, pos,
- strlen(pos),
- &new_obj_handle) != CS_OK)
- goto fail;
- else {
- key_value = NULL;
- if (confdb_key_get_typed2
- (handle, new_obj_handle,
- middle,
- (void **) &key_value,
- &valuelen, &type) == CS_OK) {
- if (!strcmp
- (key_value, value))
- goout = 1;
- free(key_value);
- key_value = NULL;
- }
- }
- }
- free(key_value);
- key_value = NULL;
- confdb_object_find_destroy(handle,
- *query_handle);
- *query_handle = new_obj_handle;
- }
- }
-
- pos = next;
- }
-
- return 0;
-
-fail:
- errno = EINVAL;
- return -1;
-}
-
-static int get_data(confdb_handle_t handle, hdb_handle_t connection_handle,
- hdb_handle_t query_handle, hdb_handle_t *list_handle,
- char **rtn, char *curpos, int list, int is_oldlist)
-{
- int cmp;
- char data[PATH_MAX];
- char *resval;
- char *keyval;
- hdb_handle_t new_obj_handle;
- unsigned int value = 0;
- confdb_value_types_t type;
- size_t datalen = 0, keyvallen = PATH_MAX;
-
- memset(data, 0, PATH_MAX);
-
- // we need to handle child::*[int value] in non list mode.
- cmp = strcmp(curpos, "child::*");
- if (cmp >= 0) {
- char *start = NULL, *end = NULL;
-
- // a pure child::* request should come down as list
- if (!cmp && !list)
- goto fail;
-
- if (confdb_object_iter_start(handle, query_handle) != CS_OK)
- goto fail;
-
- if (!is_oldlist)
- *list_handle = query_handle;
-
- if (cmp) {
- start = strstr(curpos, "[");
- if (!start)
- goto fail;
-
- start = start + 1;
-
- end = strstr(start, "]");
- if (!end)
- goto fail;
-
- memset(end, 0, 1);
- value = atoi(start);
- if (value <= 0)
- goto fail;
- } else {
- if (confdb_key_increment
- (handle, connection_handle, "iterator_tracker",
- strlen("iterator_tracker"), &value) != CS_OK)
- value = 1;
- }
-
- while (value != 0) {
- memset(data, 0, PATH_MAX);
- if (confdb_object_iter
- (handle, query_handle, &new_obj_handle, data,
- &datalen) != CS_OK) {
- reset_iterator(handle, connection_handle);
- goto fail;
- }
-
- value--;
- }
-
- resval = malloc(datalen + 2);
- if (!resval)
- goto fail;
- snprintf(resval, datalen + 2, "%s=", data);
- *rtn = resval;
-
- } else if (!strncmp(curpos, "@*", strlen("@*"))) {
-
- // this query makes sense only if we are in list mode
- if (!list)
- goto fail;
-
- if (confdb_key_iter_start(handle, query_handle) != CS_OK)
- goto fail;
-
- *list_handle = query_handle;
-
- if (confdb_key_increment
- (handle, connection_handle, "iterator_tracker",
- strlen("iterator_tracker"), &value) != CS_OK)
- value = 1;
-
- while (value != 0) {
- memset(data, 0, PATH_MAX);
- keyval = NULL;
- if (confdb_key_iter_typed2
- (handle, query_handle, data, (void **)&keyval,
- &keyvallen, &type) != CS_OK) {
- reset_iterator(handle, connection_handle);
- goto fail;
- }
-
- value--;
- if (value != 0) {
- free(keyval);
- keyval = NULL;
- }
- }
- datalen = strlen(data);
- resval = malloc(datalen + keyvallen + 2);
- if (!resval)
- goto fail;
- snprintf(resval, datalen + keyvallen + 2, "%s=%s", data, keyval);
- *rtn = resval;
- free(keyval);
-
- } else { /* pure data request */
- char *query;
-
- // this query doesn't make sense in list mode
- if (list)
- goto fail;
-
- if (confdb_object_find_start(handle, query_handle) != CS_OK)
- goto fail;
-
- query = strstr(curpos, "@");
- if (!query)
- goto fail;
-
- query = query + 1;
-
- keyval = NULL;
- if (confdb_key_get_typed2
- (handle, query_handle, query, (void **)&keyval,
- &keyvallen, &type) != CS_OK)
- goto fail;
-
- *rtn = keyval;
- }
-
- return 0;
-
-fail:
- errno = EINVAL;
- return -1;
-}
-
-/**
- * _ccs_get_xpathlite
- * @handle:
- * @connection_handle:
- * @query:
- * @list: 1 to operate in list fashion
- *
- * This function will allocate space for the value that is the result
- * of the given query. It is the user's responsibility to ensure that
- * the data returned is freed.
- *
- * Returns: char * to result or NULL in case of failure.
- */
-char *_ccs_get_xpathlite(confdb_handle_t handle, hdb_handle_t connection_handle,
- const char *query, int list)
-{
- char current_query[PATH_MAX];
- char *datapos, *rtn = NULL;
- char previous_query[PATH_MAX];
- hdb_handle_t list_handle = 0;
- hdb_handle_t query_handle = 0;
- int prev = 0, is_oldlist = 0;
- int tokens, i;
-
- memset(current_query, 0, PATH_MAX);
- strncpy(current_query, query, PATH_MAX - 1);
-
- memset(previous_query, 0, PATH_MAX);
-
- datapos = current_query + 1;
-
- prev =
- get_previous_query(handle, connection_handle, previous_query,
- &list_handle);
-
- if (list && !prev && !strcmp(current_query, previous_query)) {
- query_handle = list_handle;
- is_oldlist = 1;
- } else {
- reset_iterator(handle, connection_handle);
- query_handle = OBJECT_PARENT_HANDLE;
- }
-
- if (confdb_object_find_start(handle, query_handle) != CS_OK) {
- errno = ENOENT;
- goto fail;
- }
-
- tokens = tokenizer(current_query);
- if (tokens < 1)
- goto fail;
-
- for (i = 1; i < tokens; i++)
- datapos = datapos + strlen(datapos) + 1;
-
- if (!is_oldlist)
- if (path_dive(handle, &query_handle, current_query, tokens - 1) < 0) /* path dive can mangle tokens */
- goto fail;
-
- if (get_data
- (handle, connection_handle, query_handle, &list_handle, &rtn,
- datapos, list, is_oldlist) < 0)
- goto fail;
-
- if (list)
- if (set_previous_query
- (handle, connection_handle, (char *)query, list_handle))
- goto fail;
-
- return rtn;
-
-fail:
- return NULL;
-}
diff --git a/config/man/Makefile b/config/man/Makefile
deleted file mode 100644
index 0c003af..0000000
--- a/config/man/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-MANTARGET= cluster.conf.5
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-all:
-
-clean:
diff --git a/config/man/cluster.conf.5 b/config/man/cluster.conf.5
deleted file mode 100644
index ad2cfee..0000000
--- a/config/man/cluster.conf.5
+++ /dev/null
@@ -1,237 +0,0 @@
-.TH CLUSTER.CONF 5 2010-01-12 cluster cluster
-
-.SH NAME
-cluster.conf \- configuration file for cman and related daemons
-
-.SH SYNOPSIS
-.B /etc/cluster/cluster.conf
-
-.SH DESCRIPTION
-When
-.BR cman_tool (8)
-starts the
-.BR corosync (8)
-daemon, the cluster.conf data is read into the corosync in-memory
-database (confdb). The configuration is used by corosync,
-cman and other related cluster daemons and programs. When cman
-configures corosync with cluster.conf, the
-.BR corosync.conf (5)
-file is not used.
-
-A basic cluster configuration is described below.
-Configuration options for other daemons/programs are described in
-their own man pages.
-.BR ccs_tool (8)
-can be used to do some basic cluster.conf editing.
-
-The cluster.rng schema is used to validate cluster.conf. Unrecognized
-items will produce a warning during cluster startup, and invalid xml
-structure will cause the cluster startup to fail. See
-.BR ccs_config_validate (8)
-and
-.BR ccs_config_dump (8).
-
-.SS Cluster
-The top level
-.B cluster
-section contains all other sections and has two required attributes:
-.TP 8
-.B name
-The name of the cluster can be up to 15 characters long (16 including
-terminating null). It is important that this name be unique among
-clusters on the same network.
-.TP 8
-.B config_version
-The config_version specifies the revision level of the file and should be
-increased each time the file is updated.
-.P
-.nf
-<cluster name="alpha" config_version="1">
-</cluster>
-.fi
-
-.SS Cluster Nodes
-The set of nodes that make up the cluster are defined in the
-.B clusternodes
-section which contains multiple
-.B clusternode
-sections. A clusternode has two required attributes:
-.TP 8
-.B name
-The node name should correspond to the hostname on the network interface
-to be used for cluster communication.
-.TP 8
-.B nodeid
-The node id must be greater than zero and unique.
-.P
-.nf
-<cluster name="alpha" config_version="1">
- <clusternodes>
- <clusternode name="node-01" nodeid="1">
- </clusternode>
-
- <clusternode name="node-02" nodeid="2">
- </clusternode>
-
- <clusternode name="node-03" nodeid="3">
- </clusternode>
- </clusternodes>
-</cluster>
-.fi
-
-.SS Logging
-Cluster daemons use a common
-.B logging
-section to configure their loggging behavior.
-.P
-.nf
-<cluster name="alpha" config_version="1">
- <logging/>
-</cluster>
-.fi
-.P
-
-Global settings apply to all:
-.P
-.nf
-<logging debug="on"/>
-.fi
-.P
-
-Per-daemon
-.B logging_daemon
-subsections override the global settings.
-Daemon names that can be configured include: corosync, qdiskd, groupd, fenced,
-dlm_controld, gfs_controld, rgmanager.
-.P
-.nf
-<logging>
- <logging_daemon name="qdiskd" debug="on"/>
- <logging_daemon name="fenced" debug="on"/>
-</logging>
-.fi
-.P
-
-Corosync daemon settings apply to all corosync subsystems by default, but
-subsystems can also be configured individually. These include CLM, CPG, MAIN,
-SERV, CMAN, TOTEM, QUORUM, CONFDB, CKPT, EVT.
-.P
-.nf
-<logging>
- <logging_daemon name="corosync" subsys="QUORUM" debug="on"/>
- <logging_daemon name="corosync" subsys="CONFDB" debug="on"/>
-</logging>
-.fi
-.P
-
-The attributes available at global, daemon and subsystem levels are:
-
-.TP 8
-.B to_syslog
-enable/disable messages to syslog (yes/no), default "yes"
-
-.TP 8
-.B to_logfile
-enable/disable messages to log file (yes/no), default "yes"
-
-.TP 8
-.B syslog_facility
-facility used for syslog messages, default "local4"
-
-.TP 8
-.B syslog_priority
-messages at this level and up will be sent to syslog, default "info"
-
-.TP 8
-.B logfile_priority
-messages at this level and up will be written to log file, default "info"
-
-.TP 8
-.B logfile "\ "
-the log file name, default /var/log/cluster/<daemon>.log
-
-.TP 8
-.B debug="on"
-a shortcut for logfile_priority="debug"
-
-.SH EXAMPLE
-An explicit configuration for the default settings would be:
-.P
-.nf
-<logging to_syslog="yes" to_logfile="yes" syslog_facility="local4"
- syslog_priority="info" logfile_priority="info">
- <logging_daemon name="qdiskd"
- logfile="/var/log/cluster/qdiskd.log"/>
- <logging_daemon name="fenced"
- logfile="/var/log/cluster/fenced.log"/>
- <logging_daemon name="dlm_controld"
- logfile="/var/log/cluster/dlm_controld.log"/>
- <logging_daemon name="gfs_controld"
- logfile="/var/log/cluster/gfs_controld.log"/>
- <logging_daemon name="rgmanager"
- logfile="/var/log/cluster/rgmanager.log"/>
- <logging_daemon name="corosync"
- logfile="/var/log/cluster/corosync.log"/>
-</logging>
-.fi
-.P
-
-To include debug messages (and above) from all daemons in their default
-log files, either of the following which are equivalent:
-.P
-.nf
-<logging debug="on"/>
-<logging logfile_priority="debug"/>
-.fi
-.P
-
-To exclude all log messages from syslog:
-.P
-.nf
-<logging to_syslog="no"/>
-.fi
-.P
-
-To disable logging to all log files:
-.P
-.nf
-<logging to_file="no"/>
-.fi
-.P
-
-To include debug messages (and above) from all daemons in syslog:
-.P
-.nf
-<logging syslog_priority="debug"/>
-.fi
-.P
-
-To limit syslog messages to error (and above), keeping info (and above) in
-log files (this logfile_priority setting is the default so could be omitted):
-.P
-.nf
-<logging syslog_priority="error" logfile_priority="info"/>
-.fi
-.P
-
-.SH FILES
-.TP
-.I /etc/cluster/cluster.conf
-standard location of cluster configuration file
-.TP
-.I /usr/share/cluster/cluster.rng
-standard location of cluster.conf schema
-
-.SH SEE ALSO
-.BR ccs_tool (8),
-.BR ccs_config_dump (8),
-.BR ccs_config_validate (8),
-.BR cman_tool (8),
-.BR cman (5),
-.BR qdisk (5),
-.BR fenced (8),
-.BR fence_node (8),
-.BR dlm_controld (8),
-.BR gfs_controld (8),
-.BR rgmanager (8)
-
diff --git a/config/plugins/Makefile b/config/plugins/Makefile
deleted file mode 100644
index d79ca04..0000000
--- a/config/plugins/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS = xml
diff --git a/config/plugins/ldap/99cluster.ldif b/config/plugins/ldap/99cluster.ldif
deleted file mode 100644
index 50ffa9d..0000000
--- a/config/plugins/ldap/99cluster.ldif
+++ /dev/null
@@ -1,1826 +0,0 @@
-# Auto-generated @ 2010-05-04 17:59:59
-dn: cn=schema
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.1 NAME 'rhcsConfig-version'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.5 NAME 'rhcsTwo-node'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.6 NAME 'rhcsExpected-votes'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.241 NAME 'rhcsUpgrading'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.242 NAME 'rhcsDisallowed'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.16 NAME 'rhcsQuorum-dev-poll'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.17 NAME 'rhcsShutdown-timeout'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.18 NAME 'rhcsCcsd-poll'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.19 NAME 'rhcsDebug-mask'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.13 NAME 'rhcsPort'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.3 NAME 'rhcsCluster-id'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.274 NAME 'rhcsHash-cluster-id'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.45 NAME 'rhcsNodename'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.228 NAME 'rhcsBroadcast'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.86 NAME 'rhcsKeyfile'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.229 NAME 'rhcsDisable-openais'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.20 NAME 'rhcsAddr'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.81 NAME 'rhcsConsensus'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.82 NAME 'rhcsJoin'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.8 NAME 'rhcsToken'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.278 NAME 'rhcsFail-recv-const'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.83 NAME 'rhcsToken-retransmits-before-loss-const'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.84 NAME 'rhcsRrp-mode'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.85 NAME 'rhcsSecauth'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.230 NAME 'rhcsRingnumber'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.231 NAME 'rhcsBindnetaddr'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.232 NAME 'rhcsMcastaddr'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.233 NAME 'rhcsMcastport'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.112 NAME 'rhcsInterval'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.113 NAME 'rhcsTko'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.4 NAME 'rhcsVotes'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.114 NAME 'rhcsMin-score'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.39 NAME 'rhcsDevice'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.115 NAME 'rhcsLabel'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.116 NAME 'rhcsStatus-file'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.117 NAME 'rhcsScheduler'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.118 NAME 'rhcsReboot'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.96 NAME 'rhcsPriority'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.119 NAME 'rhcsStop-cman'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.120 NAME 'rhcsParanoid'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.121 NAME 'rhcsAllow-kill'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.122 NAME 'rhcsMax-error-cycles'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.243 NAME 'rhcsIo-timeout'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.244 NAME 'rhcsMaster-wins'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.124 NAME 'rhcsScore'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.123 NAME 'rhcsProgram'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.107 NAME 'rhcsPost-join-delay'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.108 NAME 'rhcsPost-fail-delay'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.109 NAME 'rhcsOverride-path'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.110 NAME 'rhcsOverride-time'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.111 NAME 'rhcsClean-start'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.239 NAME 'rhcsSkip-undefined'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.62 NAME 'rhcsDebug'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.70 NAME 'rhcsUse-uuid'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.64 NAME 'rhcsMulticast-address'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.43 NAME 'rhcsAuth'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.67 NAME 'rhcsHash'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.72 NAME 'rhcsUri'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.68 NAME 'rhcsKey-file'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.73 NAME 'rhcsMulticast-interface'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.23 NAME 'rhcsLog-debug'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.24 NAME 'rhcsTimewarn'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.25 NAME 'rhcsProtocol'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.26 NAME 'rhcsEnable-fencing'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.27 NAME 'rhcsEnable-quorum'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.28 NAME 'rhcsEnable-deadlk'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.29 NAME 'rhcsEnable-plock'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.30 NAME 'rhcsPlock-debug'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.31 NAME 'rhcsPlock-rate-limit'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.32 NAME 'rhcsPlock-ownership'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.33 NAME 'rhcsDrop-resources-time'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.34 NAME 'rhcsDrop-resources-count'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.35 NAME 'rhcsDrop-resources-age'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.37 NAME 'rhcsNodir'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.21 NAME 'rhcsWeight'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.36 NAME 'rhcsEnable-withdraw'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.38 NAME 'rhcsGroupd-compat'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.74 NAME 'rhcsTo-syslog'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.75 NAME 'rhcsTo-logfile'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.76 NAME 'rhcsSyslog-facility'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.77 NAME 'rhcsSyslog-priority'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.79 NAME 'rhcsLogfile-priority'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.78 NAME 'rhcsLogfile'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.80 NAME 'rhcsSubsys'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.2 NAME 'rhcsNodeid'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.22 NAME 'rhcsMcast'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.12 NAME 'rhcsIpaddr'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.40 NAME 'rhcsLogin'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.41 NAME 'rhcsPasswd'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.42 NAME 'rhcsPasswd-script'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.44 NAME 'rhcsLanplus'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.267 NAME 'rhcsKey'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.268 NAME 'rhcsDevices'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.50 NAME 'rhcsAction'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.269 NAME 'rhcsAptpl'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.47 NAME 'rhcsServers'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.48 NAME 'rhcsCserver'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.49 NAME 'rhcsRpowerpath'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.51 NAME 'rhcsOption'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.63 NAME 'rhcsIp-family'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.252 NAME 'rhcsIpport'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.66 NAME 'rhcsRetrans'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.69 NAME 'rhcsDomain'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.71 NAME 'rhcsTimeout'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.270 NAME 'rhcsSerial-device'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.271 NAME 'rhcsSerial-params'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.272 NAME 'rhcsChannel-address'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.59 NAME 'rhcsExec'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.60 NAME 'rhcsVmware-type'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.52 NAME 'rhcsSecure'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.61 NAME 'rhcsVmware-datacenter'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.53 NAME 'rhcsVerbose'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.245 NAME 'rhcsVersion'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.246 NAME 'rhcsHelp'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.247 NAME 'rhcsSeparator'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.57 NAME 'rhcsPartition'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.58 NAME 'rhcsManaged'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.248 NAME 'rhcsHmc-version'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.249 NAME 'rhcsCmd-prompt'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.250 NAME 'rhcsInet4-only'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.251 NAME 'rhcsInet6-only'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.55 NAME 'rhcsIdentity-file'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.253 NAME 'rhcsSnmp-version'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.254 NAME 'rhcsCommunity'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.255 NAME 'rhcsSnmp-auth-prot'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.256 NAME 'rhcsSnmp-sec-level'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.257 NAME 'rhcsSnmp-priv-prot'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.258 NAME 'rhcsSnmp-priv-passwd'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.259 NAME 'rhcsSnmp-priv-passwd-script'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.260 NAME 'rhcsUdpport'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.261 NAME 'rhcsCipher'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.262 NAME 'rhcsMethod'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.263 NAME 'rhcsDrac-version'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.264 NAME 'rhcsModule-name'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.54 NAME 'rhcsSwitch'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.265 NAME 'rhcsIo-fencing'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.56 NAME 'rhcsSsl'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.266 NAME 'rhcsRibcl'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.9 NAME 'rhcsAgent'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.87 NAME 'rhcsLog-level'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.88 NAME 'rhcsStatus-child-max'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.89 NAME 'rhcsStatus-poll-interval'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.90 NAME 'rhcsTransition-throttling'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.91 NAME 'rhcsCentral-processing'
- EQUALITY integerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.92 NAME 'rhcsLog-facility'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.93 NAME 'rhcsOrdered'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.94 NAME 'rhcsRestricted'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.95 NAME 'rhcsNofailback'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.97 NAME 'rhcsFile'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.98 NAME 'rhcsClass'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.99 NAME 'rhcsService'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.100 NAME 'rhcsService-state'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.101 NAME 'rhcsService-owner'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.102 NAME 'rhcsNode'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.103 NAME 'rhcsNode-id'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.104 NAME 'rhcsNode-state'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.105 NAME 'rhcsNode-clean'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.106 NAME 'rhcsNode-local'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.273 NAME 'rhcsInterface'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.125 NAME 'rhcsRef'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.126 NAME 'rhcsAutostart'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.127 NAME 'rhcsHardrecovery'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.128 NAME 'rhcsExclusive'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.129 NAME 'rhcsNfslock'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.130 NAME 'rhcsNfs-client-cache'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.131 NAME 'rhcsRecovery'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.132 NAME 'rhcsDepend'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.133 NAME 'rhcsDepend-mode'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.134 NAME 'rhcsMax-restarts'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.135 NAME 'rhcsRestart-expire-time'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.136 NAME 'rhcs--independent-subtree'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.137 NAME 'rhcs--enforce-timeouts'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.275 NAME 'rhcs--max-failures'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.276 NAME 'rhcs--failure-expire-time'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.138 NAME 'rhcsAddress'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.139 NAME 'rhcsFamily'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.140 NAME 'rhcsMonitor-link'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.141 NAME 'rhcsSleeptime'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.142 NAME 'rhcsTarget'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.143 NAME 'rhcsPath'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.144 NAME 'rhcsSvcname'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.145 NAME 'rhcsFsid'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.146 NAME 'rhcsOptions'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.147 NAME 'rhcsAllow-recover'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.148 NAME 'rhcsService-name'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.149 NAME 'rhcsUse-cache'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.150 NAME 'rhcsMountpoint'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.151 NAME 'rhcsHost'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.152 NAME 'rhcsExport'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.153 NAME 'rhcsFstype'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.154 NAME 'rhcsNo-unmount'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.155 NAME 'rhcsForce-unmount'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.156 NAME 'rhcsSelf-fence'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.157 NAME 'rhcsWorkgroup'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.158 NAME 'rhcsServer-root'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.159 NAME 'rhcsConfig-file'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.160 NAME 'rhcsHttpd-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.161 NAME 'rhcsShutdown-wait'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.162 NAME 'rhcsUrl-list'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.163 NAME 'rhcsSlapd-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.164 NAME 'rhcsSmbd-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.165 NAME 'rhcsNmbd-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.166 NAME 'rhcsListen-address'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.167 NAME 'rhcsMysqld-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.168 NAME 'rhcsStartup-wait'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.169 NAME 'rhcsPostmaster-user'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.170 NAME 'rhcsPostmaster-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.171 NAME 'rhcsTomcat-user'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.172 NAME 'rhcsCatalina-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.173 NAME 'rhcsCatalina-base'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.174 NAME 'rhcsVg-name'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.175 NAME 'rhcsLv-name'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.177 NAME 'rhcsMigration-mapping'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.234 NAME 'rhcsUse-virsh'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.235 NAME 'rhcsXmlfile'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.184 NAME 'rhcsMigrate'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.185 NAME 'rhcsSnapshot'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.277 NAME 'rhcsStatus-program'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.236 NAME 'rhcsHypervisor'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.237 NAME 'rhcsHypervisor-uri'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.238 NAME 'rhcsMigration-uri'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.186 NAME 'rhcsInstanceName'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.187 NAME 'rhcsDIR-EXECUTABLE'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.188 NAME 'rhcsDIR-PROFILE'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.189 NAME 'rhcsSTART-PROFILE'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.190 NAME 'rhcsSTART-WAITTIME'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.191 NAME 'rhcsAUTOMATIC-RECOVER'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.192 NAME 'rhcsPRE-START-USEREXIT'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.193 NAME 'rhcsPOST-START-USEREXIT'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.194 NAME 'rhcsPRE-STOP-USEREXIT'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.195 NAME 'rhcsPOST-STOP-USEREXIT'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.196 NAME 'rhcsSID'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.197 NAME 'rhcsDBTYPE'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.198 NAME 'rhcsNETSERVICENAME'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.199 NAME 'rhcsDBJ2EE-ONLY'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.200 NAME 'rhcsJAVA-HOME'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.201 NAME 'rhcsSTRICT-MONITORING'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.202 NAME 'rhcsDIR-BOOTSTRAP'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.203 NAME 'rhcsDIR-SECSTORE'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.204 NAME 'rhcsDB-JARS'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.205 NAME 'rhcsNamed-sdb'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.206 NAME 'rhcsNamed-working-dir'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.207 NAME 'rhcsNamed-options'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.208 NAME 'rhcsSybase-home'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.209 NAME 'rhcsSybase-ase'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.210 NAME 'rhcsSybase-ocs'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.211 NAME 'rhcsServer-name'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.212 NAME 'rhcsLogin-file'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.213 NAME 'rhcsInterfaces-file'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.214 NAME 'rhcsSybase-user'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.215 NAME 'rhcsStart-timeout'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.216 NAME 'rhcsDeep-probe-timeout'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.240 NAME 'rhcsResource'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.227 NAME 'rhcsQuick-status'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.217 NAME 'rhcsForce-fsck'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.218 NAME 'rhcsListener-name'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.219 NAME 'rhcsUser'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.220 NAME 'rhcsHome'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.221 NAME 'rhcsType'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.222 NAME 'rhcsVhost'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.223 NAME 'rhcsDepth'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.1 NAME 'rhcsCluster' SUP top STRUCTURAL
- MUST ( rhcsConfig-version $ name )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.3 NAME 'rhcsCman' SUP top STRUCTURAL
- MUST ( cn )
- MAY ( rhcsDisable-openais $ rhcsKeyfile $ rhcsBroadcast $ rhcsNodename $ rhcsHash-cluster-id $ rhcsCluster-id $ rhcsPort $ rhcsDebug-mask $ rhcsCcsd-poll $ rhcsShutdown-timeout $ rhcsQuorum-dev-poll $ rhcsDisallowed $ rhcsUpgrading $ rhcsExpected-votes $ rhcsTwo-node )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.8 NAME 'rhcsMulticast' SUP top STRUCTURAL
- MUST ( rhcsAddr )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.4 NAME 'rhcsTotem' SUP top STRUCTURAL
- MUST ( cn )
- MAY ( rhcsKeyfile $ rhcsSecauth $ rhcsRrp-mode $ rhcsToken-retransmits-before-loss-const $ rhcsFail-recv-const $ rhcsToken $ rhcsJoin $ rhcsConsensus )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.56 NAME 'rhcsInterface' SUP top STRUCTURAL
- MAY ( rhcsBroadcast $ rhcsMcastport $ rhcsMcastaddr $ rhcsBindnetaddr $ rhcsRingnumber )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.29 NAME 'rhcsQuorumd' SUP top STRUCTURAL
- MUST ( cn )
- MAY ( rhcsMaster-wins $ rhcsIo-timeout $ rhcsMax-error-cycles $ rhcsAllow-kill $ rhcsParanoid $ rhcsStop-cman $ rhcsPriority $ rhcsReboot $ rhcsScheduler $ rhcsStatus-file $ rhcsLabel $ rhcsDevice $ rhcsMin-score $ rhcsVotes $ rhcsTko $ rhcsInterval )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.30 NAME 'rhcsHeuristic' SUP top STRUCTURAL
- MUST ( rhcsProgram )
- MAY ( rhcsTko $ rhcsInterval $ rhcsScore )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.28 NAME 'rhcsFence-daemon' SUP top STRUCTURAL
- MAY ( rhcsSkip-undefined $ rhcsClean-start $ rhcsOverride-time $ rhcsOverride-path $ rhcsPost-fail-delay $ rhcsPost-join-delay )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.18 NAME 'rhcsFence-xvmd' SUP top STRUCTURAL
- MAY ( rhcsMulticast-interface $ rhcsKey-file $ rhcsUri $ rhcsHash $ rhcsAuth $ rhcsMulticast-address $ rhcsUse-uuid $ rhcsPort $ rhcsDebug )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.12 NAME 'rhcsDlm' SUP top STRUCTURAL
- MUST ( cn )
- MAY ( rhcsDrop-resources-age $ rhcsDrop-resources-count $ rhcsDrop-resources-time $ rhcsPlock-ownership $ rhcsPlock-rate-limit $ rhcsPlock-debug $ rhcsEnable-plock $ rhcsEnable-deadlk $ rhcsEnable-quorum $ rhcsEnable-fencing $ rhcsProtocol $ rhcsTimewarn $ rhcsLog-debug )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.14 NAME 'rhcsLockspace' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsNodir )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.15 NAME 'rhcsMaster' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsWeight )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.13 NAME 'rhcsGfs-controld' SUP top STRUCTURAL
- MAY ( rhcsDrop-resources-age $ rhcsDrop-resources-count $ rhcsDrop-resources-time $ rhcsPlock-ownership $ rhcsPlock-rate-limit $ rhcsPlock-debug $ rhcsEnable-plock $ rhcsEnable-withdraw )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.16 NAME 'rhcsGroup' SUP top STRUCTURAL
- MAY ( rhcsGroupd-compat )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.19 NAME 'rhcsLogging' SUP top STRUCTURAL
- MUST ( cn )
- MAY ( rhcsDebug $ rhcsLogfile $ rhcsLogfile-priority $ rhcsSyslog-priority $ rhcsSyslog-facility $ rhcsTo-logfile $ rhcsTo-syslog )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.57 NAME 'rhcsLogging-daemon' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsDebug $ rhcsLogfile $ rhcsLogfile-priority $ rhcsSyslog-priority $ rhcsSyslog-facility $ rhcsTo-logfile $ rhcsTo-syslog $ rhcsSubsys )
- )
-### Placeholder for rhcsClusternodes
-### This object class currently has no attributes
-#objectClasses: (
-# 1.3.6.1.4.1.2312.8.1.2.9 NAME 'rhcsClusternodes' SUP top STRUCTURAL
-# MUST ( cn )
-# )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.10 NAME 'rhcsClusternode' SUP top STRUCTURAL
- MUST ( rhcsNodeid $ name )
- MAY ( rhcsWeight $ rhcsVotes )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.11 NAME 'rhcsAltname' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsMcast $ rhcsPort )
- )
-### Placeholder for rhcsFencedevices
-### This object class currently has no attributes
-#objectClasses: (
-# 1.3.6.1.4.1.2312.8.1.2.17 NAME 'rhcsFencedevices' SUP top STRUCTURAL
-# MUST ( cn )
-# )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.5 NAME 'rhcsFencedevice' SUP top STRUCTURAL
- MUST ( rhcsAgent $ name )
- MAY ( rhcsRibcl $ rhcsSsl $ rhcsIo-fencing $ rhcsSwitch $ rhcsModule-name $ rhcsDrac-version $ rhcsMethod $ rhcsCipher $ rhcsUdpport $ rhcsSnmp-priv-passwd-script $ rhcsSnmp-priv-passwd $ rhcsSnmp-priv-prot $ rhcsSnmp-sec-level $ rhcsSnmp-auth-prot $ rhcsCommunity $ rhcsSnmp-version $ rhcsIdentity-file $ rhcsInet6-only $ rhcsInet4-only $ rhcsCmd-prompt $ rhcsHmc-version $ rhcsManaged $ rhcsPartition $ rhcsSeparator $ rhcsHelp $ rhcsVersion $ rhcsVerbose $ rhcsVmware-datacenter $ rhcsSecure $ rhcsVmware-type $ rhcsExec $ rhcsChannel-address $ rhcsSerial-params $ rhcsSerial-device $ rhcsTimeout $ rhcsUse-uuid $ rhcsDomain $ rhcsKey-file $ rhcsHash $ rhcsRetrans $ rhcsIpport $ rhcsMulticast-address $ rhcsIp-family $ rhcsDebug $ rhcsOption $ rhcsRpowerpath $ rhcsCserver $ rhcsServers $ rhcsAptpl $ rhcsLogfile $ rhcsAction $ rhcsDevices $ rhcsKey $ rhcsNodename $ rhcsLanplus $ rhcsAuth $ rhcsPasswd-script $ rhcsPasswd $ rhcsLogin $ rhcsIpaddr $ rhcsPort $ rhcsDevice )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.21 NAME 'rhcsRm' SUP top STRUCTURAL
- MUST ( cn )
- MAY ( rhcsLog-facility $ rhcsCentral-processing $ rhcsTransition-throttling $ rhcsStatus-poll-interval $ rhcsStatus-child-max $ rhcsLog-level )
- )
-### Placeholder for rhcsFailoverdomains
-### This object class currently has no attributes
-#objectClasses: (
-# 1.3.6.1.4.1.2312.8.1.2.22 NAME 'rhcsFailoverdomains' SUP top STRUCTURAL
-# MUST ( cn )
-# )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.23 NAME 'rhcsFailoverdomain' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsNofailback $ rhcsRestricted $ rhcsOrdered )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.24 NAME 'rhcsFailoverdomainnode' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsPriority )
- )
-### Placeholder for rhcsEvents
-### This object class currently has no attributes
-#objectClasses: (
-# 1.3.6.1.4.1.2312.8.1.2.25 NAME 'rhcsEvents' SUP top STRUCTURAL
-# MUST ( cn )
-# )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.26 NAME 'rhcsEvent' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsNode-local $ rhcsNode-clean $ rhcsNode-state $ rhcsNode-id $ rhcsNode $ rhcsService-owner $ rhcsService-state $ rhcsService $ rhcsClass $ rhcsPriority $ rhcsFile )
- )
-### Placeholder for rhcsResources
-### This object class currently has no attributes
-#objectClasses: (
-# 1.3.6.1.4.1.2312.8.1.2.27 NAME 'rhcsResources' SUP top STRUCTURAL
-# )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.59 NAME 'rhcsClvmd' SUP top STRUCTURAL
- MAY ( rhcsInterface )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.31 NAME 'rhcsService' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsPriority $ rhcsRestart-expire-time $ rhcsMax-restarts $ rhcsDepend-mode $ rhcsDepend $ rhcsRecovery $ rhcsNfs-client-cache $ rhcsNfslock $ rhcsExclusive $ rhcsHardrecovery $ rhcsAutostart $ rhcsDomain $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.32 NAME 'rhcsIp' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsSleeptime $ rhcsNfslock $ rhcsMonitor-link $ rhcsFamily $ rhcsAddress $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.33 NAME 'rhcsNfsclient' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsUse-cache $ rhcsService-name $ rhcsAllow-recover $ rhcsOptions $ rhcsFsid $ rhcsSvcname $ rhcsPath $ rhcsTarget $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.34 NAME 'rhcsNfsexport' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsFsid $ rhcsPath $ rhcsDevice $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.35 NAME 'rhcsScript' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsFile $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.36 NAME 'rhcsNetfs' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsOptions $ rhcsForce-unmount $ rhcsNo-unmount $ rhcsFstype $ rhcsExport $ rhcsHost $ rhcsMountpoint $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.37 NAME 'rhcsClusterfs' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsNfslock $ rhcsFsid $ rhcsSelf-fence $ rhcsOptions $ rhcsForce-unmount $ rhcsFstype $ rhcsDevice $ rhcsMountpoint $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.38 NAME 'rhcsSmb' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsWorkgroup $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.39 NAME 'rhcsApache' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsShutdown-wait $ rhcsHttpd-options $ rhcsConfig-file $ rhcsServer-root $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.40 NAME 'rhcsOpenldap' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsShutdown-wait $ rhcsSlapd-options $ rhcsUrl-list $ rhcsConfig-file $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.41 NAME 'rhcsSamba' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsShutdown-wait $ rhcsNmbd-options $ rhcsSmbd-options $ rhcsConfig-file $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.42 NAME 'rhcsMysql' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsShutdown-wait $ rhcsStartup-wait $ rhcsMysqld-options $ rhcsListen-address $ rhcsConfig-file $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.43 NAME 'rhcsPostgres-8' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsShutdown-wait $ rhcsPostmaster-options $ rhcsPostmaster-user $ rhcsConfig-file $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.44 NAME 'rhcsTomcat-5' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsShutdown-wait $ rhcsCatalina-base $ rhcsCatalina-options $ rhcsTomcat-user $ rhcsConfig-file $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.45 NAME 'rhcsLvm' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsNfslock $ rhcsSelf-fence $ rhcsLv-name $ rhcsVg-name $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.46 NAME 'rhcsVm' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsMigration-uri $ rhcsHypervisor-uri $ rhcsHypervisor $ rhcsStatus-program $ rhcsRestart-expire-time $ rhcsMax-restarts $ rhcsDepend-mode $ rhcsDepend $ rhcsSnapshot $ rhcsPath $ rhcsMigrate $ rhcsXmlfile $ rhcsUse-virsh $ rhcsMigration-mapping $ rhcsRecovery $ rhcsExclusive $ rhcsHardrecovery $ rhcsAutostart $ rhcsDomain $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.47 NAME 'rhcsSAPInstance' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsPOST-STOP-USEREXIT $ rhcsPRE-STOP-USEREXIT $ rhcsPOST-START-USEREXIT $ rhcsPRE-START-USEREXIT $ rhcsAUTOMATIC-RECOVER $ rhcsSTART-WAITTIME $ rhcsSTART-PROFILE $ rhcsDIR-PROFILE $ rhcsDIR-EXECUTABLE $ rhcsInstanceName $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.48 NAME 'rhcsSAPDatabase' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsPOST-STOP-USEREXIT $ rhcsPRE-STOP-USEREXIT $ rhcsPOST-START-USEREXIT $ rhcsPRE-START-USEREXIT $ rhcsDB-JARS $ rhcsDIR-SECSTORE $ rhcsDIR-BOOTSTRAP $ rhcsAUTOMATIC-RECOVER $ rhcsSTRICT-MONITORING $ rhcsJAVA-HOME $ rhcsDBJ2EE-ONLY $ rhcsNETSERVICENAME $ rhcsDBTYPE $ rhcsDIR-EXECUTABLE $ rhcsSID $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.49 NAME 'rhcsNamed' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsService-name $ rhcsShutdown-wait $ rhcsNamed-options $ rhcsNamed-working-dir $ rhcsNamed-sdb $ rhcsConfig-file $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.50 NAME 'rhcsASEHAagent' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsDeep-probe-timeout $ rhcsStart-timeout $ rhcsShutdown-timeout $ rhcsSybase-user $ rhcsInterfaces-file $ rhcsLogin-file $ rhcsServer-name $ rhcsSybase-ocs $ rhcsSybase-ase $ rhcsSybase-home $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.58 NAME 'rhcsDrbd' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsResource $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.51 NAME 'rhcsFs' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsOptions $ rhcsForce-fsck $ rhcsFsid $ rhcsNfslock $ rhcsSelf-fence $ rhcsQuick-status $ rhcsForce-unmount $ rhcsFstype $ rhcsDevice $ rhcsMountpoint $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.52 NAME 'rhcsOracledb' SUP top STRUCTURAL
- MAY ( rhcs--failure-expire-time $ rhcs--max-failures $ rhcs--enforce-timeouts $ rhcs--independent-subtree $ rhcsVhost $ rhcsType $ rhcsHome $ rhcsUser $ rhcsListener-name $ name $ rhcsRef )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.53 NAME 'rhcsAction' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsTimeout $ rhcsInterval $ rhcsDepth )
- )
-### Placeholder for rhcsFence
-### This object class currently has no attributes
-#objectClasses: (
-# 1.3.6.1.4.1.2312.8.1.2.54 NAME 'rhcsFence' SUP top STRUCTURAL
-# MUST ( cn )
-# )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.7 NAME 'rhcsMethod' SUP top STRUCTURAL
- MUST ( name )
- )
-### Placeholder for rhcsUnfence
-### This object class currently has no attributes
-#objectClasses: (
-# 1.3.6.1.4.1.2312.8.1.2.55 NAME 'rhcsUnfence' SUP top STRUCTURAL
-# )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.6 NAME 'rhcsDevice' SUP top STRUCTURAL
- MUST ( name )
- MAY ( rhcsRibcl $ rhcsSsl $ rhcsIo-fencing $ rhcsSwitch $ rhcsModule-name $ rhcsDrac-version $ rhcsMethod $ rhcsCipher $ rhcsUdpport $ rhcsSnmp-priv-passwd-script $ rhcsSnmp-priv-passwd $ rhcsSnmp-priv-prot $ rhcsSnmp-sec-level $ rhcsSnmp-auth-prot $ rhcsCommunity $ rhcsSnmp-version $ rhcsIdentity-file $ rhcsInet6-only $ rhcsInet4-only $ rhcsCmd-prompt $ rhcsHmc-version $ rhcsManaged $ rhcsPartition $ rhcsSeparator $ rhcsHelp $ rhcsVersion $ rhcsVerbose $ rhcsVmware-datacenter $ rhcsSecure $ rhcsVmware-type $ rhcsExec $ rhcsChannel-address $ rhcsSerial-params $ rhcsSerial-device $ rhcsTimeout $ rhcsUse-uuid $ rhcsDomain $ rhcsKey-file $ rhcsHash $ rhcsRetrans $ rhcsIpport $ rhcsMulticast-address $ rhcsIp-family $ rhcsDebug $ rhcsOption $ rhcsRpowerpath $ rhcsCserver $ rhcsServers $ rhcsAptpl $ rhcsLogfile $ rhcsAction $ rhcsDevices $ rhcsKey $ rhcsNodename $ rhcsLanplus $ rhcsAuth $ rhcsPasswd-script $ rhcsPasswd $ rhcsLogin $ rhcsIpaddr $ rhcsPort $ rhcsDevice )
- )
diff --git a/config/plugins/ldap/Makefile b/config/plugins/ldap/Makefile
deleted file mode 100644
index 33e907d..0000000
--- a/config/plugins/ldap/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-TARGET= config_ldap.lcrso
-
-LCRSOT=$(TARGET)
-
-DOCS = 99cluster.ldif \
- example.ldif
-
-all: ${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
-
-CFLAGS += -fPIC
-CFLAGS += -I${ldapincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${ldaplibdir} -lldap
-LDFLAGS += -L${libdir}
-
-OBJS= configldap.o
-
-${TARGET}: ${OBJS}
- $(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
-
-clean: generalclean
-
--include $(OBJS:.o=.d)
diff --git a/config/plugins/ldap/configldap.c b/config/plugins/ldap/configldap.c
deleted file mode 100644
index fb25af4..0000000
--- a/config/plugins/ldap/configldap.c
+++ /dev/null
@@ -1,292 +0,0 @@
-#include <sys/types.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <arpa/inet.h>
-
-// CC: temp until I tame SASL ... is this necessary?
-#define LDAP_DEPRECATED 1
-#include <ldap.h>
-
-/* corosync headers */
-#include <corosync/lcr/lcr_comp.h>
-#include <corosync/engine/objdb.h>
-#include <corosync/engine/config.h>
-
-/* These are defaults. they can be overridden with environment variables
- * COROSYNC_LDAP_URL & COROSYNC_LDAP_BASEDN
- */
-#define DEFAULT_LDAP_URL "ldap:///"
-#define DEFAULT_LDAP_BASEDN "dc=chrissie,dc=net"
-
-static int ldap_readconfig(struct objdb_iface_ver0 *objdb, const char **error_string);
-static int ldap_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, const char **error_string);
-static int init_config(struct objdb_iface_ver0 *objdb);
-static char error_reason[1024];
-static const char *ldap_url = DEFAULT_LDAP_URL;
-static const char *ldap_basedn = DEFAULT_LDAP_BASEDN;
-
-/*
- * Exports the interface for the service
- */
-
-static struct config_iface_ver0 ldapconfig_iface_ver0 = {
- .config_readconfig = ldap_readconfig,
- .config_reloadconfig = ldap_reloadconfig
-};
-
-static struct lcr_iface ifaces_ver0[2] = {
- {
- .name = "ldapconfig",
- .version = 0,
- .versions_replace = 0,
- .versions_replace_count = 0,
- .dependencies = 0,
- .dependency_count = 0,
- .constructor = NULL,
- .destructor = NULL,
- .interfaces = NULL,
- }
-};
-
-static struct lcr_comp ldap_comp_ver0 = {
- .iface_count = 1,
- .ifaces = ifaces_ver0,
-};
-
-
-
-__attribute__ ((constructor)) static void ldap_comp_register(void) {
- lcr_interfaces_set(&ifaces_ver0[0], &ldapconfig_iface_ver0);
- lcr_component_register(&ldap_comp_ver0);
-};
-
-static int ldap_readconfig(struct objdb_iface_ver0 *objdb, const char **error_string)
-{
- int ret;
-
- /* Read config tree from LDAP */
- if (!(ret = init_config(objdb)))
- sprintf(error_reason, "%s", "Successfully read config from LDAP\n");
-
- *error_string = error_reason;
-
- return ret;
-}
-
-static int ldap_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, const char **error_string)
-{
- return ldap_readconfig(objdb, error_string);
-}
-
-/*
- * Convert hyphens to underscores in all attribute names
- */
-static void convert_underscores(char *s, int len)
-{
- int j;
-
- for (j=0; j < len; j++) {
- if (s[j] == '-')
- s[j] = '_';
- }
-}
-
-static void convert_dn_underscores(LDAPDN dn)
-{
- int i=0;
-
- while (dn[i]) {
- convert_underscores(dn[i][0][0].la_attr.bv_val, dn[i][0][0].la_attr.bv_len);
- i++;
- }
-}
-
-/*
- * Return the parent object of a DN.
- * Actually, this returns the LAST parent with that name. which should (!) be correct.
- */
-static hdb_handle_t find_parent(struct objdb_iface_ver0 *objdb, LDAPDN dn, int startdn, const char *parent)
-{
- int i=startdn;
- int gotstart=0;
- int start=0, end=startdn;
- hdb_handle_t parent_handle = OBJECT_PARENT_HANDLE;
- hdb_handle_t object_handle=0;
- hdb_handle_t find_handle;
-
- /*
- * Find the start and end positions first.
- * start is where the 'parent' entry is.
- * end is the end of the list
- */
- do {
- if (!gotstart && dn[i][0][0].la_value.bv_len == 7 &&
- !strncmp(parent, dn[i][0][0].la_value.bv_val, 7)) {
- gotstart = 1;
- start = i;
- }
- i++;
- } while (dn[i]);
- if (start <= 0)
- return parent_handle;
-
- for (i=start; i>=end; i--) {
- objdb->object_find_create(parent_handle,
- dn[i][0][0].la_value.bv_val, dn[i][0][0].la_value.bv_len,
- &find_handle);
- while (!objdb->object_find_next(find_handle, &object_handle)) {
- parent_handle = object_handle;
- }
- objdb->object_find_destroy(find_handle);
- }
- return object_handle;
-}
-
-
-
-static int read_config_for(LDAP *ld, struct objdb_iface_ver0 *objdb, hdb_handle_t parent,
- const char *object, const char *sub_dn)
-{
- char search_dn[4096];
- int rc;
- int first_entry = 1;
- char *dn;
- LDAPMessage *result, *e;
- hdb_handle_t parent_handle = OBJECT_PARENT_HANDLE;
- hdb_handle_t object_handle;
-
- sprintf(search_dn, "%s,%s", sub_dn, ldap_basedn);
-
- /* Search the whole tree from the base DN provided */
- rc = ldap_search_ext_s(ld, search_dn, LDAP_SCOPE_SUBTREE, "(objectClass=*)", NULL, 0,
- NULL, NULL, NULL, 0, &result);
- if (rc != LDAP_SUCCESS) {
- sprintf(error_reason, "ldap_search_ext_s: %s\n", ldap_err2string(rc));
- if (rc == LDAP_NO_SUCH_OBJECT)
- return 0;
- else
- return -1;
- }
- for (e = ldap_first_entry(ld, result); e != NULL;
- e = ldap_next_entry(ld, e)) {
- if ((dn = ldap_get_dn(ld, e)) != NULL) {
- char *attr;
- BerElement *attr_ber;
- LDAPDN parsed_dn;
-
- /* Make it parsable so we can discern the hierarchy */
- if (ldap_str2dn(dn, &parsed_dn, LDAP_DN_PEDANTIC)) {
- sprintf(error_reason, "ldap_str2dn failed: %s\n", ldap_err2string(rc));
- return -1;
- }
-
- /*
- * LDAP doesn't allow underscores in dn names so we replace hypens with
- * underscores so we can have thing like config_version, appear as
- * config-version in ldap
- */
- convert_dn_underscores(parsed_dn);
-
- /* Create a new object if the top-level is NOT name= OR we are the first "cluster" entry */
- if (strncmp(parsed_dn[0][0][0].la_attr.bv_val, "name", 4) || first_entry) {
- parent_handle = find_parent(objdb, parsed_dn, 0, object);
-
- objdb->object_create(parent_handle, &object_handle, parsed_dn[0][0][0].la_value.bv_val,
- parsed_dn[0][0][0].la_value.bv_len);
- first_entry = 0;
- }
- else {
- /* Remove redundant empty parent. */
- objdb->object_destroy(object_handle);
-
- parent_handle = find_parent(objdb, parsed_dn, 2, object);
- /* Create a new object with the same name as the current one */
- objdb->object_create(parent_handle, &object_handle, parsed_dn[1][0][0].la_value.bv_val,
- parsed_dn[1][0][0].la_value.bv_len);
- }
-
- /* Finished with the text representation */
- ldap_memfree(dn);
-
- /* Store the attributes as keys */
- attr = ldap_first_attribute(ld, e, &attr_ber);
- while (attr) {
- int i;
- struct berval **val_ber;
-
- val_ber = ldap_get_values_len(ld, e, attr);
- i=0;
- while (val_ber[i]) {
- /*
- * If the attribute starts "rhcs" then remove that bit
- * and make the first letter lower case so it matches the
- * cluster.conf entry.
- * so, after the above underscore change too:
- * eg 'rhcsConfig-version' becomes 'config_version'. magic!
- */
- if (strncmp(attr, "rhcs", 4) == 0) {
- memmove(attr, attr+4, strlen(attr+4)+1);
- attr[0] |= 0x60;
- }
- convert_underscores(attr, strlen(attr));
-
- /*
- * Add a key - but ignore "objectClass" & "cn" attributes
- * as they don't provide anything we can use
- */
- if (strcmp("objectClass", attr) &&
- strcmp("cn", attr)) {
- objdb->object_key_create_typed(object_handle, attr,
- val_ber[i]->bv_val,
- val_ber[i]->bv_len+1,
- OBJDB_VALUETYPE_STRING);
- }
- i++;
- }
- ldap_memfree(attr);
- attr = ldap_next_attribute(ld, e, attr_ber);
- ldap_value_free_len(val_ber);
- }
- ldap_memfree(attr);
- ber_free(attr_ber, 0);
- }
- }
- ldap_msgfree(result);
-
- return 0;
-}
-
-/* The real work starts here */
-static int init_config(struct objdb_iface_ver0 *objdb)
-{
- LDAP *ld;
- int version, rc;
-
- if (getenv("COROSYNC_LDAP_URL"))
- ldap_url = getenv("COROSYNC_LDAP_URL");
- if (getenv("COROSYNC_LDAP_BASEDN"))
- ldap_basedn = getenv("COROSYNC_LDAP_BASEDN");
-
- /* Connect to the LDAP server */
- if (ldap_initialize(&ld, ldap_url)) {
- sprintf(error_reason, "ldap_initialize failed: %s\n", strerror(errno));
- return -1;
- }
- version = LDAP_VERSION3;
- ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
-
- /*
- * CC: Do I need to use sasl ?!
- */
- rc = ldap_simple_bind_s(ld, getenv("COROSYNC_LDAP_BINDDN"), getenv("COROSYNC_LDAP_BINDPWD"));
- if (rc != LDAP_SUCCESS) {
- sprintf(error_reason, "ldap_simple_bind failed: %s\n", ldap_err2string(rc));
- return -1;
- }
-
- rc = read_config_for(ld, objdb, OBJECT_PARENT_HANDLE, "cluster", "name=cluster");
-
- ldap_unbind(ld);
- return 0;
-}
diff --git a/config/plugins/ldap/example.ldif b/config/plugins/ldap/example.ldif
deleted file mode 100644
index 0182dcf..0000000
--- a/config/plugins/ldap/example.ldif
+++ /dev/null
@@ -1,137 +0,0 @@
-# Example cluster LDIF file
-# Christine Caulfield <ccaulfie(a)redhat.com>
-#
-# You WILL need to change this to suit your needs, in particular a search
-# and replace of dc=chrissie,dc=net with your own domanin name.
-#
-# Load with:
-# ldapmodify -x -a -D"cn=Directory Manager" -f example.ldif -c -v -W
-#
-#
-# What follows is the LDAP equivalent of the following cluster.conf file:
-#
-#<totem token="21000"/>
-#
-#<cluster config_version="1" name="cc_cluster">
-# <cman cluster_id="444"/>
-#
-# <fencedevices>
-# <fencedevice name="myapc"
-# password="apc"
-# username="apc"
-# ipaddr="myapc.chrissie.net"
-# agent="fence_apc"
-# </fencedevice>
-# </fencedevice>
-# <clusternodes>
-# <clusternode name="ford"
-# votes="1"
-# nodeid="32">
-# <fence>
-# <method name="apc">
-# <device name="myapc" port="4"/>
-# </method>
-# </fence>
-# </clusternode>
-#
-# <clusternode name="arthur"
-# votes="1"
-# nodeid="10">
-# </clusternode>
-#
-# <clusternode name="jeltz"
-# votes="2"
-# nodeid="1">
-# </clusternode>
-# </clusternodes>
-#</cluster>
-#
-#
-
-dn: cn=cluster,dc=chrissie,dc=net
-cn: cluster
-objectClass: rhcsCluster
-name: cc_cluster
-rhcsConfig-version: 1
-
-# Some cman parameters
-dn: cn=cman,cn=cluster,dc=chrissie,dc=net
-cn: cman
-objectClass: rhcsCman
-rhcsCluster-id: 444
-
-# Some totem parameters
-dn: cn=totem,cn=cluster,dc=chrissie,dc=net
-cn: totem
-objectClass: rhcsTotem
-rhcsToken: 21000
-
-# Define nodes
-dn: cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-cn: clusternodes
-objectClass: nsContainer
-
-
-dn: cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-cn: clusternode
-objectClass: nsContainer
-
-
-dn: name=jeltz,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-objectClass: rhcsNode
-name: jeltz
-rhcsNodeid: 1
-rhcsVotes: 2
-
-# Define a fence agent for this node ...!
-dn: cn=fence,name=jeltz,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-cn: fence
-objectclass: nsContainer
-
-dn: cn=method,cn=fence,name=jeltz,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-cn: method
-objectclass: nsContainer
-
-dn: name=apc,cn=method,cn=fence,name=jeltz,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-name: apc
-objectclass: rhcsFenceMethod
-
-dn: cn=device,name=apc,cn=method,cn=fence,name=jeltz,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-cn: device
-objectclass: nsContainer
-
-dn: name=myapc,cn=device,name=apc,cn=method,cn=fence,name=jeltz,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-name: myapc
-objectclass: rhcsFenceAgent
-rhcsPort: 4
-
-dn: name=arthur,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-objectClass: rhcsNode
-name: arthur
-rhcsNodeid: 10
-rhcsVotes: 1
-
-dn: name=ford,cn=clusternode,cn=clusternodes,cn=cluster,dc=chrissie,dc=net
-objectClass: rhcsNode
-name: ford
-rhcsNodeid: 32
-rhcsVotes: 1
-
-# Fence agent
-
-dn: cn=fencedevices,cn=cluster,dc=chrissie,dc=net
-cn: fencedevices
-objectClass: nsContainer
-
-dn: cn=fencedevice,cn=fencedevices,cn=cluster,dc=chrissie,dc=net
-cn: fencedevice
-objectClass: nsContainer
-
-
-dn: name=myapc,cn=fencedevice,cn=fencedevices,cn=cluster,dc=chrissie,dc=net
-objectClass: rhcsFencedevice
-name: myapc
-rhcsAgent: fence_apc
-rhcsIpaddr: myapc.chrissie.net
-rhcsUsername: apc
-rhcsPassword: apc
diff --git a/config/plugins/ldap/ldap-base.csv b/config/plugins/ldap/ldap-base.csv
deleted file mode 100644
index 79dea80..0000000
--- a/config/plugins/ldap/ldap-base.csv
+++ /dev/null
@@ -1,338 +0,0 @@
-# Max attribute value: 278
-# Max object class value: 59
-obj,rhcsCluster,cluster,1
-obj,rhcsCman,cman,3
-obj,rhcsTotem,totem,4
-obj,rhcsFencedevice,fencedevice,5
-obj,rhcsDevice,device,6
-obj,rhcsMethod,method,7
-attr,rhcsConfig-version,config_version,1
-attr,rhcsNodeid,nodeid,2
-attr,rhcsCluster-id,cluster_id,3
-attr,rhcsVotes,votes,4
-attr,rhcsTwo-node,two_node,5
-attr,rhcsExpected-votes,expected_votes,6
-attr,rhcsMax-queued,max_queued,7
-attr,rhcsToken,token,8
-attr,rhcsAgent,agent,9
-attr,rhcsUsername,username,10
-attr,rhcsPassword,password,11
-attr,rhcsIpaddr,ipaddr,12
-attr,rhcsPort,port,13
-attr,name,name,14
-attr,rhcsAlias,alias,15
-attr,rhcsQuorum-dev-poll,quorum_dev_poll,16
-attr,rhcsShutdown-timeout,shutdown_timeout,17
-attr,rhcsCcsd-poll,ccsd_poll,18
-attr,rhcsDebug-mask,debug_mask,19
-obj,rhcsMulticast,multicast,8
-attr,rhcsAddr,addr,20
-obj,rhcsClusternodes,clusternodes,9
-obj,rhcsClusternode,clusternode,10
-attr,rhcsWeight,weight,21
-obj,rhcsAltname,altname,11
-attr,rhcsMcast,mcast,22
-obj,rhcsDlm,dlm,12
-attr,rhcsLog-debug,log_debug,23
-attr,rhcsTimewarn,timewarn,24
-attr,rhcsProtocol,protocol,25
-attr,rhcsEnable-fencing,enable_fencing,26
-attr,rhcsEnable-quorum,enable_quorum,27
-attr,rhcsEnable-deadlk,enable_deadlk,28
-attr,rhcsEnable-plock,enable_plock,29
-attr,rhcsPlock-debug,plock_debug,30
-attr,rhcsPlock-rate-limit,plock_rate_limit,31
-attr,rhcsPlock-ownership,plock_ownership,32
-attr,rhcsDrop-resources-time,drop_resources_time,33
-attr,rhcsDrop-resources-count,drop_resources_count,34
-attr,rhcsDrop-resources-age,drop_resources_age,35
-obj,rhcsGfs-controld,gfs_controld,13
-attr,rhcsEnable-withdraw,enable_withdraw,36
-obj,rhcsLockspace,lockspace,14
-attr,rhcsNodir,nodir,37
-obj,rhcsMaster,master,15
-obj,rhcsGroup,group,16
-attr,rhcsGroupd-compat,groupd_compat,38
-obj,rhcsFencedevices,fencedevices,17
-attr,rhcsDevice,device,39
-attr,rhcsLogin,login,40
-attr,rhcsPasswd,passwd,41
-attr,rhcsPasswd-script,passwd_script,42
-attr,rhcsAuth,auth,43
-attr,rhcsLanplus,lanplus,44
-attr,rhcsNodename,nodename,45
-attr,rhcsSelf,self,46
-attr,rhcsServers,servers,47
-attr,rhcsCserver,cserver,48
-attr,rhcsRpowerpath,rpowerpath,49
-attr,rhcsAction,action,50
-attr,rhcsOption,option,51
-attr,rhcsSecure,secure,52
-attr,rhcsVerbose,verbose,53
-attr,rhcsSwitch,switch,54
-attr,rhcsIdentity-file,identity_file,55
-attr,rhcsSsl,ssl,56
-attr,rhcsPartition,partition,57
-attr,rhcsManaged,managed,58
-attr,rhcsExec,exec,59
-attr,rhcsVmware-type,vmware_type,60
-attr,rhcsVmware-datacenter,vmware_datacenter,61
-attr,rhcsDebug,debug,62
-attr,rhcsIp-family,ip_family,63
-attr,rhcsMulticast-address,multicast_address,64
-attr,rhcsMulticast-ttl,multicast_ttl,65
-attr,rhcsRetrans,retrans,66
-attr,rhcsHash,hash,67
-attr,rhcsKey-file,key_file,68
-attr,rhcsDomain,domain,69
-attr,rhcsUse-uuid,use_uuid,70
-attr,rhcsTimeout,timeout,71
-obj,rhcsFence-xvmd,fence_xvmd,18
-attr,rhcsUri,uri,72
-attr,rhcsMulticast-interface,multicast_interface,73
-obj,rhcsLogging,logging,19
-attr,rhcsTo-syslog,to_syslog,74
-attr,rhcsTo-logfile,to_logfile,75
-attr,rhcsSyslog-facility,syslog_facility,76
-attr,rhcsSyslog-priority,syslog_priority,77
-attr,rhcsLogfile,logfile,78
-attr,rhcsLogfile-priority,logfile_priority,79
-obj,rhcsLogging-subsys,logging_subsys,20
-attr,rhcsSubsys,subsys,80
-attr,rhcsConsensus,consensus,81
-attr,rhcsJoin,join,82
-attr,rhcsToken-retransmits-before-loss-const,token_retransmits_before_loss_const,83
-attr,rhcsRrp-mode,rrp_mode,84
-attr,rhcsSecauth,secauth,85
-attr,rhcsKeyfile,keyfile,86
-obj,rhcsRm,rm,21
-attr,rhcsLog-level,log_level,87
-attr,rhcsStatus-child-max,status_child_max,88
-attr,rhcsStatus-poll-interval,status_poll_interval,89
-attr,rhcsTransition-throttling,transition_throttling,90
-attr,rhcsCentral-processing,central_processing,91
-attr,rhcsLog-facility,log_facility,92
-obj,rhcsFailoverdomains,failoverdomains,22
-obj,rhcsFailoverdomain,failoverdomain,23
-attr,rhcsOrdered,ordered,93
-attr,rhcsRestricted,restricted,94
-attr,rhcsNofailback,nofailback,95
-obj,rhcsFailoverdomainnode,failoverdomainnode,24
-attr,rhcsPriority,priority,96
-obj,rhcsEvents,events,25
-obj,rhcsEvent,event,26
-attr,rhcsFile,file,97
-attr,rhcsClass,class,98
-attr,rhcsService,service,99
-attr,rhcsService-state,service_state,100
-attr,rhcsService-owner,service_owner,101
-attr,rhcsNode,node,102
-attr,rhcsNode-id,node_id,103
-attr,rhcsNode-state,node_state,104
-attr,rhcsNode-clean,node_clean,105
-attr,rhcsNode-local,node_local,106
-obj,rhcsResources,resources,27
-obj,rhcsFence-daemon,fence_daemon,28
-attr,rhcsPost-join-delay,post_join_delay,107
-attr,rhcsPost-fail-delay,post_fail_delay,108
-attr,rhcsOverride-path,override_path,109
-attr,rhcsOverride-time,override_time,110
-attr,rhcsClean-start,clean_start,111
-obj,rhcsQuorumd,quorumd,29
-attr,rhcsInterval,interval,112
-attr,rhcsTko,tko,113
-attr,rhcsMin-score,min_score,114
-attr,rhcsLabel,label,115
-attr,rhcsStatus-file,status_file,116
-attr,rhcsScheduler,scheduler,117
-attr,rhcsReboot,reboot,118
-attr,rhcsStop-cman,stop_cman,119
-attr,rhcsParanoid,paranoid,120
-attr,rhcsAllow-kill,allow_kill,121
-attr,rhcsMax-error-cycles,max_error_cycles,122
-obj,rhcsHeuristic,heuristic,30
-attr,rhcsProgram,program,123
-attr,rhcsScore,score,124
-obj,rhcsService,service,31
-attr,rhcsRef,ref,125
-attr,rhcsAutostart,autostart,126
-attr,rhcsHardrecovery,hardrecovery,127
-attr,rhcsExclusive,exclusive,128
-attr,rhcsNfslock,nfslock,129
-attr,rhcsNfs-client-cache,nfs_client_cache,130
-attr,rhcsRecovery,recovery,131
-attr,rhcsDepend,depend,132
-attr,rhcsDepend-mode,depend_mode,133
-attr,rhcsMax-restarts,max_restarts,134
-attr,rhcsRestart-expire-time,restart_expire_time,135
-attr,rhcs--independent-subtree,__independent_subtree,136
-attr,rhcs--enforce-timeouts,__enforce_timeouts,137
-obj,rhcsIp,ip,32
-attr,rhcsAddress,address,138
-attr,rhcsFamily,family,139
-attr,rhcsMonitor-link,monitor_link,140
-attr,rhcsSleeptime,sleeptime,141
-obj,rhcsNfsclient,nfsclient,33
-attr,rhcsTarget,target,142
-attr,rhcsPath,path,143
-attr,rhcsSvcname,svcname,144
-attr,rhcsFsid,fsid,145
-attr,rhcsOptions,options,146
-attr,rhcsAllow-recover,allow_recover,147
-attr,rhcsService-name,service_name,148
-attr,rhcsUse-cache,use_cache,149
-obj,rhcsNfsexport,nfsexport,34
-obj,rhcsScript,script,35
-obj,rhcsNetfs,netfs,36
-attr,rhcsMountpoint,mountpoint,150
-attr,rhcsHost,host,151
-attr,rhcsExport,export,152
-attr,rhcsFstype,fstype,153
-attr,rhcsNo-unmount,no_unmount,154
-attr,rhcsForce-unmount,force_unmount,155
-obj,rhcsClusterfs,clusterfs,37
-attr,rhcsSelf-fence,self_fence,156
-obj,rhcsSmb,smb,38
-attr,rhcsWorkgroup,workgroup,157
-obj,rhcsApache,apache,39
-attr,rhcsServer-root,server_root,158
-attr,rhcsConfig-file,config_file,159
-attr,rhcsHttpd-options,httpd_options,160
-attr,rhcsShutdown-wait,shutdown_wait,161
-obj,rhcsOpenldap,openldap,40
-attr,rhcsUrl-list,url_list,162
-attr,rhcsSlapd-options,slapd_options,163
-obj,rhcsSamba,samba,41
-attr,rhcsSmbd-options,smbd_options,164
-attr,rhcsNmbd-options,nmbd_options,165
-obj,rhcsMysql,mysql,42
-attr,rhcsListen-address,listen_address,166
-attr,rhcsMysqld-options,mysqld_options,167
-attr,rhcsStartup-wait,startup_wait,168
-obj,rhcsPostgres-8,postgres-8,43
-attr,rhcsPostmaster-user,postmaster_user,169
-attr,rhcsPostmaster-options,postmaster_options,170
-obj,rhcsTomcat-5,tomcat-5,44
-attr,rhcsTomcat-user,tomcat_user,171
-attr,rhcsCatalina-options,catalina_options,172
-attr,rhcsCatalina-base,catalina_base,173
-obj,rhcsLvm,lvm,45
-attr,rhcsVg-name,vg_name,174
-attr,rhcsLv-name,lv_name,175
-obj,rhcsVm,vm,46
-attr,rhcsMemory,memory,176
-attr,rhcsMigration-mapping,migration_mapping,177
-attr,rhcsBootloader,bootloader,178
-attr,rhcsRootdisk-physical,rootdisk_physical,179
-attr,rhcsRootdisk-virtual,rootdisk_virtual,180
-attr,rhcsSwapdisk-physical,swapdisk_physical,181
-attr,rhcsSwapdisk-virtual,swapdisk_virtual,182
-attr,rhcsVif,vif,183
-attr,rhcsMigrate,migrate,184
-attr,rhcsSnapshot,snapshot,185
-obj,rhcsSAPInstance,SAPInstance,47
-attr,rhcsInstanceName,InstanceName,186
-attr,rhcsDIR-EXECUTABLE,DIR_EXECUTABLE,187
-attr,rhcsDIR-PROFILE,DIR_PROFILE,188
-attr,rhcsSTART-PROFILE,START_PROFILE,189
-attr,rhcsSTART-WAITTIME,START_WAITTIME,190
-attr,rhcsAUTOMATIC-RECOVER,AUTOMATIC_RECOVER,191
-attr,rhcsPRE-START-USEREXIT,PRE_START_USEREXIT,192
-attr,rhcsPOST-START-USEREXIT,POST_START_USEREXIT,193
-attr,rhcsPRE-STOP-USEREXIT,PRE_STOP_USEREXIT,194
-attr,rhcsPOST-STOP-USEREXIT,POST_STOP_USEREXIT,195
-obj,rhcsSAPDatabase,SAPDatabase,48
-attr,rhcsSID,SID,196
-attr,rhcsDBTYPE,DBTYPE,197
-attr,rhcsNETSERVICENAME,NETSERVICENAME,198
-attr,rhcsDBJ2EE-ONLY,DBJ2EE_ONLY,199
-attr,rhcsJAVA-HOME,JAVA_HOME,200
-attr,rhcsSTRICT-MONITORING,STRICT_MONITORING,201
-attr,rhcsDIR-BOOTSTRAP,DIR_BOOTSTRAP,202
-attr,rhcsDIR-SECSTORE,DIR_SECSTORE,203
-attr,rhcsDB-JARS,DB_JARS,204
-obj,rhcsNamed,named,49
-attr,rhcsNamed-sdb,named_sdb,205
-attr,rhcsNamed-working-dir,named_working_dir,206
-attr,rhcsNamed-options,named_options,207
-obj,rhcsASEHAagent,ASEHAagent,50
-attr,rhcsSybase-home,sybase_home,208
-attr,rhcsSybase-ase,sybase_ase,209
-attr,rhcsSybase-ocs,sybase_ocs,210
-attr,rhcsServer-name,server_name,211
-attr,rhcsLogin-file,login_file,212
-attr,rhcsInterfaces-file,interfaces_file,213
-attr,rhcsSybase-user,sybase_user,214
-attr,rhcsStart-timeout,start_timeout,215
-attr,rhcsDeep-probe-timeout,deep_probe_timeout,216
-obj,rhcsFs,fs,51
-attr,rhcsForce-fsck,force_fsck,217
-obj,rhcsOracledb,oracledb,52
-attr,rhcsListener-name,listener_name,218
-attr,rhcsUser,user,219
-attr,rhcsHome,home,220
-attr,rhcsType,type,221
-attr,rhcsVhost,vhost,222
-obj,rhcsAction,action,53
-attr,rhcsDepth,depth,223
-obj,rhcsFence,fence,54
-obj,rhcsUnfence,unfence,55
-attr,rhcsBlade,blade,224
-attr,rhcsLpan,lpan,225
-attr,rhcsPserver,pserver,226
-attr,rhcsQuick-status,quick_status,227
-attr,rhcsBroadcast,broadcast,228
-attr,rhcsDisable-openais,disable_openais,229
-obj,rhcsInterface,interface,56
-attr,rhcsRingnumber,ringnumber,230
-attr,rhcsBindnetaddr,bindnetaddr,231
-attr,rhcsMcastaddr,mcastaddr,232
-attr,rhcsMcastport,mcastport,233
-attr,rhcsUse-virsh,use_virsh,234
-attr,rhcsXmlfile,xmlfile,235
-attr,rhcsHypervisor,hypervisor,236
-attr,rhcsHypervisor-uri,hypervisor_uri,237
-attr,rhcsMigration-uri,migration_uri,238
-attr,rhcsSkip-undefined,skip_undefined,239
-obj,rhcsLogging-daemon,logging_daemon,57
-obj,rhcsDrbd,drbd,58
-attr,rhcsResource,resource,240
-attr,rhcsUpgrading,upgrading,241
-attr,rhcsDisallowed,disallowed,242
-attr,rhcsIo-timeout,io_timeout,243
-attr,rhcsMaster-wins,master_wins,244
-attr,rhcsVersion,version,245
-attr,rhcsHelp,help,246
-attr,rhcsSeparator,separator,247
-attr,rhcsHmc-version,hmc_version,248
-attr,rhcsCmd-prompt,cmd_prompt,249
-attr,rhcsInet4-only,inet4_only,250
-attr,rhcsInet6-only,inet6_only,251
-attr,rhcsIpport,ipport,252
-attr,rhcsSnmp-version,snmp_version,253
-attr,rhcsCommunity,community,254
-attr,rhcsSnmp-auth-prot,snmp_auth_prot,255
-attr,rhcsSnmp-sec-level,snmp_sec_level,256
-attr,rhcsSnmp-priv-prot,snmp_priv_prot,257
-attr,rhcsSnmp-priv-passwd,snmp_priv_passwd,258
-attr,rhcsSnmp-priv-passwd-script,snmp_priv_passwd_script,259
-attr,rhcsUdpport,udpport,260
-attr,rhcsCipher,cipher,261
-attr,rhcsMethod,method,262
-attr,rhcsDrac-version,drac_version,263
-attr,rhcsModule-name,module_name,264
-attr,rhcsIo-fencing,io_fencing,265
-attr,rhcsRibcl,ribcl,266
-attr,rhcsKey,key,267
-attr,rhcsDevices,devices,268
-attr,rhcsAptpl,aptpl,269
-attr,rhcsSerial-device,serial_device,270
-attr,rhcsSerial-params,serial_params,271
-attr,rhcsChannel-address,channel_address,272
-obj,rhcsClvmd,clvmd,59
-attr,rhcsInterface,interface,273
-attr,rhcsHash-cluster-id,hash_cluster_id,274
-attr,rhcs--max-failures,__max_failures,275
-attr,rhcs--failure-expire-time,__failure_expire_time,276
-attr,rhcsStatus-program,status_program,277
-attr,rhcsFail-recv-const,fail_recv_const,278
diff --git a/config/plugins/xml/Makefile b/config/plugins/xml/Makefile
deleted file mode 100644
index abc5b75..0000000
--- a/config/plugins/xml/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-TARGET= config_xml.lcrso
-
-LCRSOT=$(TARGET)
-
-all: ${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
-
-CFLAGS += -fPIC -D_GNU_SOURCE
-CFLAGS += `xml2-config --cflags`
-CFLAGS += -I${incdir}
-
-LDFLAGS += `xml2-config --libs`
-LDFLAGS += -L${libdir}
-
-OBJS= config.o
-
-${TARGET}: ${OBJS}
- $(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
-
-clean: generalclean
-
--include $(OBJS:.o=.d)
diff --git a/config/plugins/xml/config.c b/config/plugins/xml/config.c
deleted file mode 100644
index 7dcf8ba..0000000
--- a/config/plugins/xml/config.c
+++ /dev/null
@@ -1,146 +0,0 @@
-#include <string.h>
-#include <syslog.h>
-
-#include <libxml/tree.h>
-
-#include <corosync/lcr/lcr_comp.h>
-#include <corosync/engine/objdb.h>
-#include <corosync/engine/config.h>
-
-static int xml_readconfig(struct objdb_iface_ver0 *objdb, const char **error_string);
-static int xml_reloadconfig(struct objdb_iface_ver0 *objdb, int flush,
- const char **error_string);
-static int init_config(struct objdb_iface_ver0 *objdb, const char *configfile,
- const char *error_string);
-static char error_reason[1024];
-
-#define DEFAULT_CONFIG DEFAULT_CONFIG_DIR "/" DEFAULT_CONFIG_FILE
-
-/*
- * Exports the interface for the service
- */
-
-static struct config_iface_ver0 xmlconfig_iface_ver0 = {
- .config_readconfig = xml_readconfig,
- .config_reloadconfig = xml_reloadconfig
-};
-
-static struct lcr_iface ifaces_ver0[2] = {
- {
- .name = "xmlconfig",
- .version = 0,
- .versions_replace = 0,
- .versions_replace_count = 0,
- .dependencies = 0,
- .dependency_count = 0,
- .constructor = NULL,
- .destructor = NULL,
- .interfaces = NULL,
- }
-};
-
-static struct lcr_comp xml_comp_ver0 = {
- .iface_count = 1,
- .ifaces = ifaces_ver0,
-};
-
-__attribute__ ((constructor))
-static void xml_comp_register(void)
-{
- lcr_interfaces_set(&ifaces_ver0[0], &xmlconfig_iface_ver0);
- lcr_component_register(&xml_comp_ver0);
-};
-
-static void addkeys(xmlAttrPtr tmpattr, struct objdb_iface_ver0 *objdb,
- hdb_handle_t object_handle)
-{
- for (tmpattr = tmpattr; tmpattr; tmpattr = tmpattr->next) {
- if (tmpattr->type == XML_ATTRIBUTE_NODE)
- objdb->object_key_create_typed(object_handle,
- (char *)tmpattr->name,
- (char *)tmpattr->children->
- content,
- strlen((char *)tmpattr->
- children->content) + 1,
- OBJDB_VALUETYPE_STRING);
- }
-}
-
-static void xml2objdb(xmlNodePtr tmpnode, struct objdb_iface_ver0 *objdb,
- hdb_handle_t parent)
-{
- hdb_handle_t object_handle = 0;
-
- for (tmpnode = tmpnode; tmpnode; tmpnode = tmpnode->next) {
- if (tmpnode->type == XML_ELEMENT_NODE) {
- objdb->object_create(parent, &object_handle,
- (char *)tmpnode->name,
- strlen((char *)tmpnode->name));
- if (tmpnode->properties)
- addkeys(tmpnode->properties, objdb,
- object_handle);
- }
- xml2objdb(tmpnode->children, objdb, object_handle);
- }
-}
-
-static int xml_reloadconfig(struct objdb_iface_ver0 *objdb, int flush,
- const char **error_string)
-{
- return xml_readconfig(objdb, error_string);
-}
-
-static int xml_readconfig(struct objdb_iface_ver0 *objdb, const char **error_string)
-{
- int ret = 0;
- const char *configfile = DEFAULT_CONFIG;
-
- /* We need to set this up to internal defaults too early */
- openlog("corosync", LOG_CONS | LOG_PID, SYSLOGFACILITY);
-
- if (getenv("COROSYNC_CLUSTER_CONFIG_FILE"))
- configfile = getenv("COROSYNC_CLUSTER_CONFIG_FILE");
-
- /* Read low-level totem/aisexec etc config from cluster.conf */
- if (!(ret = init_config(objdb, configfile, error_reason)))
- sprintf(error_reason, "Successfully read config from %s\n",
- configfile);
- else
- sprintf(error_reason, "Unable to read config from %s\n",
- configfile);
-
- *error_string = error_reason;
-
- return ret;
-}
-
-static int init_config(struct objdb_iface_ver0 *objdb, const char *configfile,
- const char *error_string)
-{
- int err = 0;
- xmlDocPtr doc = NULL;
- xmlNodePtr root_node = NULL;
-
- /* openfile */
-
- doc = xmlParseFile(configfile);
- if (!doc) {
- err = -1;
- goto fail;
- }
-
- root_node = xmlDocGetRootElement(doc);
- if (!root_node) {
- err = -1;
- goto fail;
- }
-
- /* load it in objdb */
- xml2objdb(root_node, objdb, OBJECT_PARENT_HANDLE);
-
-fail:
- if (doc)
- xmlFreeDoc(doc);
-
- return err;
-}
diff --git a/config/tools/Makefile b/config/tools/Makefile
deleted file mode 100644
index e339f3b..0000000
--- a/config/tools/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS=ccs_tool xml man
diff --git a/config/tools/ccs_tool/Makefile b/config/tools/ccs_tool/Makefile
deleted file mode 100644
index 7ebb24a..0000000
--- a/config/tools/ccs_tool/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-TARGET1 = ccs_tool
-TARGET2 = ccs_test
-
-SBINDIRT = $(TARGET1)
-SBINSYMT = $(TARGET2)
-
-include ../../../make/defines.mk
-
-all: depends ${TARGET1} ${TARGET2}
-
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-OBJS = ccs_tool.o \
- editconf.o
-
-CFLAGS += -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
-CFLAGS += `xml2-config --cflags`
-CFLAGS += -I${ccsincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${ccslibdir} -lccs
-LDFLAGS += `xml2-config --libs`
-LDFLAGS += -L${libdir}
-
-${TARGET1}: ${OBJS} ${LDDEPS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-${TARGET2}: ${TARGET1}
- ln -sf ${TARGET1} ${TARGET2}
-
-depends:
- $(MAKE) -C $(OBJDIR)/config/libs/libccsconfdb all
-
-clean: generalclean
-
--include $(OBJS:.o=.d)
diff --git a/config/tools/ccs_tool/ccs_tool.c b/config/tools/ccs_tool/ccs_tool.c
deleted file mode 100644
index 34805be..0000000
--- a/config/tools/ccs_tool/ccs_tool.c
+++ /dev/null
@@ -1,307 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <string.h>
-#include <errno.h>
-
-#include "copyright.cf"
-#include "editconf.h"
-#include "ccs.h"
-
-
-/*
- * Old libccs retruned -error (mostly!) but didn't set errno (sigh)
- * New libccs sets errno correctly
- */
-static char *errstring(int retcode)
-{
- return strerror(errno);
-}
-
-static void tool_print_usage(FILE *stream);
-
-int globalverbose=0;
-
-static void test_print_usage(FILE *stream);
-
-static int test_main(int argc, char *argv[], int old_format){
- int desc=0;
- int i=0;
- int error = 0;
- int force = 0, blocking = 0;
- char *str=NULL;
- char *cluster_name = NULL;
-
- if(argc <= 1){
- test_print_usage(stderr);
- exit(EXIT_FAILURE);
- }
-
- for(i=1; i < argc; i++){
- if(!strcmp(argv[i], "-h")){
- test_print_usage(stdout);
- exit(EXIT_SUCCESS);
- }
- if(!strcmp(argv[i], "-V")){
- printf("%s %s (built %s %s)\n", argv[0], RELEASE_VERSION, __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- }
- }
-
- if(!strcmp(argv[1], "connect")){
- for(i=2; i < argc; i++){
- if(!strcmp(argv[i], "force")){
- printf("Force is set.\n");
- force = 1;
- } else if(!strcmp(argv[i], "block")){
- printf("Blocking is set.\n");
- blocking = 1;
- } else {
- cluster_name = argv[i];
- printf("Setting cluster name to %s\n", cluster_name);
- }
- }
- if(blocking && !force){
- fprintf(stderr, "Blocking can only be used with \"force\".\n");
- exit(EXIT_FAILURE);
- }
- if(force){
- desc = ccs_force_connect(cluster_name, blocking);
- } else {
- if(cluster_name){
- fprintf(stderr, "A cluster name can only be specified when using 'force'.\n");
- exit(EXIT_FAILURE);
- }
- desc = ccs_connect();
- }
- if(desc < 0){
- fprintf(stderr, "ccs_connect failed: %s\n", errstring(-desc));
- exit(EXIT_FAILURE);
- } else {
- printf("Connect successful.\n");
- printf(" Connection descriptor = %d\n", desc);
- ccs_disconnect(desc);
- }
- }
- else if(!strcmp(argv[1], "disconnect")){
- if(argc < 3){
- fprintf(stderr, "Wrong number of arguments.\n");
- exit(EXIT_FAILURE);
- }
- desc = ccs_connect();
- if((error = ccs_disconnect(desc))){
- fprintf(stderr, "ccs_disconnect failed: %s\n", errstring(-error));
- exit(EXIT_FAILURE);
- } else {
- printf("Disconnect successful.\n");
- }
- }
- else if(!strcmp(argv[1], "get")){
- if(argc < 4){
- fprintf(stderr, "Wrong number of arguments.\n");
- exit(EXIT_FAILURE);
- }
- desc = ccs_connect();
- if((desc < 0) || (error = ccs_get(desc, argv[3], &str))){
- fprintf(stderr, "ccs_get failed: %s\n", errstring(-error));
- exit(EXIT_FAILURE);
- } else {
- if (old_format) {
- printf("Get successful.\n");
- printf(" Value = <%s>\n", str);
- }
- else {
- printf("%s\n", str);
- }
- if(str)free(str);
- ccs_disconnect(desc);
- }
- }
- else {
- fprintf(stderr, "Unknown command: %s\n", argv[1]);
- exit(EXIT_FAILURE);
- }
-
- exit(EXIT_SUCCESS);
-}
-
-static void test_print_usage(FILE *stream)
-{
- fprintf(stream,
- "Usage:\n"
- "\n"
- "ccs_test [Options] <Command>\n"
- "\n"
- "Options:\n"
- " -h Print usage.\n"
- " -V Print version information.\n"
- "\n"
- "Commands:\n"
- " connect <force> <block> Connect to CCS and return connection descriptor.\n"
- " disconnect <desc> Disconnect from CCS.\n"
- " get <desc> <request> Get a value from CCS.\n"
- );
-}
-
-static int xpath_query(int argc, char **argv)
-{
- int handle;
- char *ret;
- int i;
-
- if (argc < 2) {
- fprintf(stderr,
- "Usage:\n"
- "\n"
- "ccs_tool query [-n] <xpath query>\n"
- "\n"
- "options\n"
- " -n disable full XPath parsing\n");
- return 1;
- }
-
- /* Tell the library we want full XPath parsing */
- fullxpath = 1;
-
- if (strcmp(argv[1], "-n") == 0) {
- argv++;
- argc--;
-
- /* Actually ... no we don't */
- fullxpath = 0;
- }
-
- handle = ccs_connect();
-
- /* Process all the queries on the command-line */
- for (i=1; i<argc; i++) {
- if (!ccs_get(handle, argv[1], &ret)) {
- printf("%s\n", ret);
- free(ret);
- }
- else {
- fprintf(stderr, "Query failed: %s\n", strerror(errno));
- ccs_disconnect(handle);
- return -1;
- }
- }
- ccs_disconnect(handle);
- return 0;
-}
-
-static int tool_main(int argc, char *argv[])
-{
- optind = 1;
-
- if (argc < 2 || !strcmp(argv[optind], "-h")) {
- tool_print_usage(stdout);
- exit(EXIT_SUCCESS);
- }
- if (!strcmp(argv[optind], "-V")) {
- printf("%s %s (built %s %s)\n", argv[0], RELEASE_VERSION,
- __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- }
-
- if(optind < argc){
- if(!strcmp(argv[optind], "-verbose")){
- optind++;
- globalverbose=1;
- }
- if(!strcmp(argv[optind], "help")){
- tool_print_usage(stdout);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "query")){
- return xpath_query(argc-1, argv+1);
- }
- else if(!strcmp(argv[optind], "addnode")){
- add_node(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "delnode")){
- del_node(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "addfence")){
- add_fence(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "delfence")){
- del_fence(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "lsnode")){
- list_nodes(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "lsfence")){
- list_fences(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "create")){
- create_skeleton(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
- else if(!strcmp(argv[optind], "addnodeids")){
- add_nodeids(argc-1, argv+1);
- exit(EXIT_SUCCESS);
- }
-
- else {
- fprintf(stderr, "Unknown command, %s.\n"
- "Try 'ccs_tool help' for help.\n", argv[optind]);
- exit(EXIT_FAILURE);
- }
- } else {
- fprintf(stderr, "Too few arguments.\n"
- "Try 'ccs_tool help' for help.\n");
- exit(EXIT_FAILURE);
- }
- exit(EXIT_SUCCESS);
-}
-
-static void tool_print_usage(FILE *stream){
- fprintf(stream,
- "Usage:\n"
- " ccs_tool [options] <command>\n"
- "\n"
- "Options:\n"
- " -verbose Make some operations print more details.\n"
- " -h Print this usage and exit.\n"
- " -V Print version information and exit.\n"
- "\n"
- "Commands:\n"
- " help Print this usage and exit.\n"
- " query <xpath query> Query the cluster configuration.\n"
- " addnode <node> Add a node\n"
- " delnode <node> Delete a node\n"
- " lsnode List nodes\n"
- " lsfence List fence devices\n"
- " addfence <fencedev> Add a new fence device\n"
- " delfence <fencedev> Delete a fence device\n"
- " create Create a skeleton config file\n"
- " addnodeids Assign node ID numbers to all nodes\n"
- "\n");
-}
-
-
-int main(int argc, char *argv[])
-{
- char *name = strdup(argv[0]);
-
- /*
- * Don't be anal about the binary name.
- * We expect either 'ccs_tool' or 'ccs_test',
- * but interpret anything other than 'ccs_test'
- * as 'ccs_tool'.
- * That's not a bug, it's a feature.
- */
-
- if (strcmp(basename(name), "ccs_test") == 0)
- return test_main(argc, argv, 1);
- else
- return tool_main(argc, argv);
-}
diff --git a/config/tools/ccs_tool/editconf.c b/config/tools/ccs_tool/editconf.c
deleted file mode 100644
index 34f7893..0000000
--- a/config/tools/ccs_tool/editconf.c
+++ /dev/null
@@ -1,1225 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <getopt.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-
-#include <libxml/tree.h>
-
-#include "editconf.h"
-
-#define MAX_NODES 256
-
-const char *prog_name = "ccs_tool";
-
-#define die(fmt, args...) \
-do { \
- fprintf(stderr, "%s: ", prog_name); \
- fprintf(stderr, fmt "\n", ##args); \
- exit(EXIT_FAILURE); \
-} while (0)
-
-
-struct option_info
-{
- const char *name;
- const char *altname;
- const char *votes;
- const char *nodeid;
- const char *mcast_addr;
- const char *fence_type;
- const char *configfile;
- const char *outputfile;
- int do_delete;
-};
-
-static void config_usage(int rw)
-{
- fprintf(stderr, " -c --configfile Name of configuration file (" DEFAULT_CONFIG_DIR "/" DEFAULT_CONFIG_FILE ")\n");
- if (rw)
- {
- fprintf(stderr, " -o --outputfile Name of output file (defaults to same as --configfile)\n");
- }
-}
-
-static void help_usage(void)
-{
- fprintf(stderr, " -h --help Display this help text\n");
-}
-
-static void list_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options]\n", prog_name, name);
- fprintf(stderr, " -v --verbose Print all properties of the item\n");
- config_usage(0);
- help_usage();
-
- exit(0);
-}
-
-static void create_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [-2] <clustername>\n", prog_name, name);
- fprintf(stderr, " -2 Create a 2-node cman cluster config file\n");
- fprintf(stderr, " -n <num> Create skeleton entries for <num> nodes\n");
- fprintf(stderr, " -f <device> Add a fence device to the node skeletons\n");
- config_usage(0);
- help_usage();
- fprintf(stderr, "\n"
- "Note that \"create\" on its own will not create a valid configuration file.\n"
- "Fence agents and nodes will need to be added to it before handing it over\n"
- "to cman.\n"
- "\n"
- "eg:\n"
- " ccs_tool create MyCluster\n"
- " ccs_tool addfence apc fence_apc ipaddr=apc.domain.net login=apc passwd=apc\n"
- " ccs_tool addnode node1 -n 1 -f apc port=1\n"
- " ccs_tool addnode node2 -n 2 -f apc port=2\n"
- " ccs_tool addnode node3 -n 3 -f apc port=3\n"
- " ccs_tool addnode node4 -n 4 -f apc port=4\n"
- "\n");
- fprintf(stderr, "If you add -n <numbner> to the command then %s will add skeleton entries for\n", name);
- fprintf(stderr, "that many nodes. This file WILL NEED EDITTING MANUALLY before it can be used\n");
- fprintf(stderr, "by cman.\n");
-
- exit(0);
-}
-
-static void addfence_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options] <name> <agent> [param=value]\n", prog_name, name);
- config_usage(1);
- help_usage();
-
- exit(0);
-}
-
-static void delfence_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options] <name>\n", prog_name, name);
- config_usage(1);
- help_usage();
- fprintf(stderr, "\n");
- fprintf(stderr, "%s will allow you to remove a fence device that is in use by nodes.\n", name);
- fprintf(stderr, "This is to allow changes to be made, but be aware that it may produce an\n");
- fprintf(stderr, "invalid configuration file if you don't add it back in again.\n");
-
- exit(0);
-}
-
-static void delnode_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options] <name>\n", prog_name, name);
- config_usage(1);
- help_usage();
-
- exit(0);
-}
-
-static void addnodeid_usage(const char *name)
-{
- fprintf(stderr, "Add node IDs to all nodes in the config file that don't have them.\n");
- fprintf(stderr, "Nodes with IDs will not be afftected, so you can run this as many times\n");
- fprintf(stderr, "as you like without doing any harm.\n");
- fprintf(stderr, "It will optionally add a multicast address to the cluster config too.\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Usage: %s %s [options] <name>\n", prog_name, name);
- fprintf(stderr, " -n --nodeid Nodeid to start with (default 1)\n");
- fprintf(stderr, " -m --multicast Set or change the multicast address\n");
- fprintf(stderr, " -v --verbose Print nodeids that are assigned\n");
- config_usage(1);
- help_usage();
-
- exit(0);
-}
-
-static void addnode_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options] <nodename> [<fencearg>=<value>]...\n", prog_name, name);
- fprintf(stderr, " -n --nodeid Nodeid (required)\n");
- fprintf(stderr, " -v --votes Number of votes for this node (default 1)\n");
- fprintf(stderr, " -a --altname Alternative name/interface for multihomed hosts\n");
- fprintf(stderr, " -f --fence_type Name reference of fencing to use\n");
- config_usage(1);
- help_usage();
-
- fprintf(stderr, "\n");
- fprintf(stderr, "Examples:\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Add a new node to default configuration file:\n");
- fprintf(stderr, " %s %s newnode1 -n 1 -f wti7 port=1\n", prog_name, name);
- fprintf(stderr, "\n");
- fprintf(stderr, "Add a new node and dump config file to stdout rather than save it\n");
- fprintf(stderr, " %s %s -o- newnode2 -n 2 -f apc port=1\n", prog_name, name);
-
- exit(0);
-}
-
-/* Is it really ?
- * Actually, we don't check that this is a valid multicast address(!),
- * merely that it is a valid IP[46] address.
- */
-static int valid_mcast_addr(char *mcast)
-{
- struct addrinfo *ainfo;
- struct addrinfo ahints;
- int ret;
-
- memset(&ahints, 0, sizeof(ahints));
-
- ret = getaddrinfo(mcast, NULL, &ahints, &ainfo);
- if (ret) {
- freeaddrinfo(ainfo);
- return 0;
- }
- return 1;
-}
-
-static void save_file(xmlDoc *doc, struct option_info *ninfo)
-{
- char tmpconffile[strlen(ninfo->outputfile)+5];
- char oldconffile[strlen(ninfo->outputfile)+5];
- int using_stdout = 0;
- mode_t old_mode;
- int ret;
-
- old_mode = umask(026);
-
- if (strcmp(ninfo->outputfile, "-") == 0)
- using_stdout = 1;
-
- /*
- * Save it to a temp file before moving the old one out of the way
- */
- if (!using_stdout)
- {
- snprintf(tmpconffile, sizeof(tmpconffile), "%s.tmp", ninfo->outputfile);
- snprintf(oldconffile, sizeof(oldconffile), "%s.old", ninfo->outputfile);
- }
- else
- {
- strcpy(tmpconffile, ninfo->outputfile);
- }
-
- xmlKeepBlanksDefault(0);
- ret = xmlSaveFormatFile(tmpconffile, doc, 1);
- if (ret == -1)
- die("Error writing new config file %s", ninfo->outputfile);
-
- if (!using_stdout)
- {
- if (rename(ninfo->outputfile, oldconffile) == -1 && errno != ENOENT)
- die("Can't move old config file out of the way\n");
-
- if (rename(tmpconffile, ninfo->outputfile))
- {
- perror("Error renaming new file to its real filename");
-
- /* Drat, that failed, try to put the old one back */
- if (rename(oldconffile, ninfo->outputfile))
- die("Can't move old config fileback in place - clean up after me please\n");
- }
- }
-
- /* free the document */
- xmlFreeDoc(doc);
-
- umask(old_mode);
-}
-
-static void validate_int_arg(char argopt, char *arg)
-{
- char *tmp;
- int val;
-
- val = strtol(arg, &tmp, 10);
- if (tmp == arg || tmp != arg + strlen(arg))
- die("argument to %c (%s) is not an integer", argopt, arg);
-
- if (val < 0)
- die("argument to %c cannot be negative", argopt);
-}
-
-/* Get the config_version string from the file */
-static xmlChar *find_version(xmlNode *root)
-{
- if (xmlHasProp(root, BAD_CAST "config_version"))
- {
- xmlChar *ver;
-
- ver = xmlGetProp(root, BAD_CAST "config_version");
- return ver;
- }
- return NULL;
-}
-
-/* Get the cluster name string from the file */
-static xmlChar *cluster_name(xmlNode *root)
-{
- if (xmlHasProp(root, BAD_CAST "name"))
- {
- xmlChar *ver;
-
- ver = xmlGetProp(root, BAD_CAST "name");
- return ver;
- }
- return NULL;
-}
-
-static void increment_version(xmlNode *root_element)
-{
- int ver;
- unsigned char *version_string;
- char newver[32];
-
- /* Increment version */
- version_string = find_version(root_element);
- if (!version_string)
- die("Can't find \"config_version\" in config file\n");
-
- ver = atoi((char *)version_string);
- snprintf(newver, sizeof(newver), "%d", ++ver);
- xmlSetProp(root_element, BAD_CAST "config_version", BAD_CAST newver);
-}
-
-static xmlNode *findnode(xmlNode *root, const char *name)
-{
- xmlNode *cur_node;
-
- for (cur_node = root->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, name)==0)
- {
- return cur_node;
- }
- }
- return NULL;
-}
-
-/* Return the fence type name (& node) for a cluster node */
-static xmlChar *get_fence_type(xmlNode *clusternode, xmlNode **fencenode)
-{
- xmlNode *f;
-
- f = findnode(clusternode, "fence");
- if (f)
- {
- f = findnode(f, "method");
- if (f)
- {
- f = findnode(f, "device");
- *fencenode = f;
- return xmlGetProp(f, BAD_CAST "name");
- }
- }
- return NULL;
-}
-
-/* Check the fence type exists under <fencedevices> */
-static xmlNode *valid_fence_type(xmlNode *root, const char *fencetype)
-{
- xmlNode *devs;
- xmlNode *cur_node;
-
- devs = findnode(root, "fencedevices");
- if (!devs)
- return NULL;
-
- for (cur_node = devs->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "fencedevice") == 0)
- {
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
- if (strcmp((char *)name, fencetype) == 0)
- return cur_node;
- }
- }
- return NULL;
-}
-
-/* Check the nodeid is not already in use by another node */
-static xmlNode *get_by_nodeid(xmlNode *root, int nodeid)
-{
- xmlNode *cnodes;
- xmlNode *cur_node;
-
- cnodes = findnode(root, "clusternodes");
- if (!cnodes)
- return NULL;
-
- for (cur_node = cnodes->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0)
- {
- xmlChar *idstring = xmlGetProp(cur_node, BAD_CAST "nodeid");
- if (idstring && atoi((char *)idstring) == nodeid)
- return cur_node;
- }
- }
- return NULL;
-}
-
-
-/* Get the multicast address node.
- */
-static xmlNode *find_multicast_addr(xmlNode *clusternodes)
-{
- xmlNode *clnode = findnode(clusternodes, "cman");
- if (clnode)
- {
- xmlNode *mcast = findnode(clnode, "multicast");
- return mcast;
- }
- return NULL;
-}
-
-static xmlNode *find_node(xmlNode *clusternodes, const char *nodename)
-{
- xmlNode *cur_node;
-
- for (cur_node = clusternodes->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0)
- {
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
- if (strcmp((char *)name, nodename) == 0)
- return cur_node;
- }
- }
- return NULL;
-}
-
-/* Print name=value pairs for a (n XML) node.
- * "ignore" is a string to ignore if present as a property (probably already printed on the main line)
- */
-static int print_properties(xmlNode *node, const char *prefix, const char *ignore, const char *ignore2)
-{
- xmlAttr *attr;
- int done_prefix = 0;
-
- for (attr = node->properties; attr; attr = attr->next)
- {
- /* Don't print "name=" */
- if (strcmp((char *)attr->name, "name") &&
- strcmp((char *)attr->name, ignore) &&
- strcmp((char *)attr->name, ignore2)
- )
- {
- if (!done_prefix)
- {
- done_prefix = 1;
- printf("%s", prefix);
- }
- printf(" %s=%s", attr->name, xmlGetProp(node, attr->name));
- }
- }
- if (done_prefix)
- printf("\n");
- return done_prefix;
-}
-
-/* Add name=value pairs from the commandline as properties to a node */
-static void add_fence_args(xmlNode *fencenode, int argc, char **argv, int optindex)
-{
- int i;
-
- for (i = optindex; i<argc; i++)
- {
- char *prop;
- char *value;
- char *equals;
-
- prop = strdup(argv[i]);
- // FIXME: handle failed strdup
- equals = strchr(prop, '=');
- if (!equals)
- die("option '%s' is not opt=value pair\n", prop);
-
- value = equals+1;
- *equals = '\0';
-
- /* "name" is used for the fence type itself, so this is just
- * to protect the user from their own stupidity
- */
- if (strcmp(prop, "name") == 0)
- die("Can't use \"name\" as a fence argument name\n");
-
- xmlSetProp(fencenode, BAD_CAST prop, BAD_CAST value);
- free(prop);
- }
-}
-
-static void add_clusternode(xmlNode *root_element, struct option_info *ninfo,
- int argc, char **argv, int optindex)
-{
- xmlNode *clusternodes;
- xmlNode *newnode;
-
- xmlNode *newfence;
- xmlNode *newfencemethod;
- xmlNode *newfencedevice;
-
- clusternodes = findnode(root_element, "clusternodes");
- if (!clusternodes)
- die("Can't find \"clusternodes\" in %s\n", ninfo->configfile);
-
- /* Don't allow duplicate node names */
- if (find_node(clusternodes, ninfo->name))
- die("node %s already exists in %s\n", ninfo->name, ninfo->configfile);
-
- /* Check for duplicate node ID */
- if (!ninfo->nodeid)
- die("nodeid not specified\n");
-
- if (get_by_nodeid(root_element, atoi((char *)ninfo->nodeid)))
- die("nodeid %s already in use\n", ninfo->nodeid);
-
- /* Don't allow random fence types */
- if (ninfo->fence_type && !valid_fence_type(root_element, ninfo->fence_type))
- die("fence type '%s' not known\n", ninfo->fence_type);
-
- /* Add the new node */
- newnode = xmlNewNode(NULL, BAD_CAST "clusternode");
- xmlSetProp(newnode, BAD_CAST "name", BAD_CAST ninfo->name);
- xmlSetProp(newnode, BAD_CAST "votes", BAD_CAST ninfo->votes);
- xmlSetProp(newnode, BAD_CAST "nodeid", BAD_CAST ninfo->nodeid);
- xmlAddChild(clusternodes, newnode);
-
- if (ninfo->altname)
- {
- xmlNode *altnode;
-
- altnode = xmlNewNode(NULL, BAD_CAST "altname");
- xmlSetProp(altnode, BAD_CAST "name", BAD_CAST ninfo->altname);
- xmlAddChild(newnode, altnode);
- }
-
- /* Add the fence attributes */
- if (ninfo->fence_type)
- {
- newfence = xmlNewNode(NULL, BAD_CAST "fence");
- newfencemethod = xmlNewNode(NULL, BAD_CAST "method");
- xmlSetProp(newfencemethod, BAD_CAST "name", BAD_CAST "single");
-
- newfencedevice = xmlNewNode(NULL, BAD_CAST "device");
- xmlSetProp(newfencedevice, BAD_CAST "name", BAD_CAST ninfo->fence_type);
-
- /* Add name=value options */
- add_fence_args(newfencedevice, argc, argv, optindex+1);
-
- xmlAddChild(newnode, newfence);
- xmlAddChild(newfence, newfencemethod);
- xmlAddChild(newfencemethod, newfencedevice);
- }
-}
-
-static xmlDoc *open_configfile(struct option_info *ninfo)
-{
- xmlDoc *doc;
-
- /* Init libxml */
- xmlInitParser();
- LIBXML_TEST_VERSION;
-
- if (!ninfo->configfile)
- ninfo->configfile = DEFAULT_CONFIG_DIR "/" DEFAULT_CONFIG_FILE;
- if (!ninfo->outputfile)
- ninfo->outputfile = ninfo->configfile;
-
- /* Load XML document */
- doc = xmlParseFile(ninfo->configfile);
- if (doc == NULL)
- die("Error: unable to parse requested configuration file\n");
-
- return doc;
-
-}
-
-static void del_clusternode(xmlNode *root_element, struct option_info *ninfo)
-{
- xmlNode *clusternodes;
- xmlNode *oldnode;
-
- clusternodes = findnode(root_element, "clusternodes");
- if (!clusternodes)
- {
- fprintf(stderr, "Can't find \"clusternodes\" in %s\n", ninfo->configfile);
- exit(1);
- }
-
- oldnode = find_node(clusternodes, ninfo->name);
- if (!oldnode)
- {
- fprintf(stderr, "node %s does not exist in %s\n", ninfo->name, ninfo->configfile);
- exit(1);
- }
-
- xmlUnlinkNode(oldnode);
-}
-
-struct option addnode_options[] =
-{
- { "votes", required_argument, NULL, 'v'},
- { "nodeid", required_argument, NULL, 'n'},
- { "altname", required_argument, NULL, 'a'},
- { "fence_type", required_argument, NULL, 'f'},
- { "outputfile", required_argument, NULL, 'o'},
- { "configfile", required_argument, NULL, 'c'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option delnode_options[] =
-{
- { "outputfile", required_argument, NULL, 'o'},
- { "configfile", required_argument, NULL, 'c'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option addfence_options[] =
-{
- { "outputfile", required_argument, NULL, 'o'},
- { "configfile", required_argument, NULL, 'c'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option addnodeid_options[] =
-{
- { "outputfile", required_argument, NULL, 'o'},
- { "configfile", required_argument, NULL, 'c'},
- { "multicast", required_argument, NULL, 'm'},
- { "nodeid", no_argument, NULL, 'n'},
- { "verbose", no_argument, NULL, 'v'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option list_options[] =
-{
- { "configfile", required_argument, NULL, 'c'},
- { "verbose", no_argument, NULL, 'v'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option create_options[] =
-{
- { "configfile", required_argument, NULL, 'c'},
- { "nodes", required_argument, NULL, 'n'},
- { "fence", required_argument, NULL, 'f'},
- { "verbose", no_argument, NULL, 'v'},
- { NULL, 0, NULL, 0 },
-};
-
-
-static int next_nodeid(int startid, int *nodeids, int nodecount)
-{
- int i;
- int nextid = startid;
-
-retry:
- for (i=0; i<nodecount; i++)
- {
- if (nodeids[i] == nextid)
- {
- nextid++;
- goto retry;
- }
- }
-
- return nextid;
-}
-
-void add_nodeids(int argc, char **argv)
-{
- struct option_info ninfo;
- unsigned char *nodenames[MAX_NODES];
- xmlDoc *doc;
- xmlNode *root_element;
- xmlNode *clusternodes;
- xmlNode *cur_node;
- xmlNode *mcast;
- int verbose = 0;
- int opt;
- int i;
- int nodenumbers[MAX_NODES];
- int nodeidx;
- int totalnodes;
- int nextid;
-
- memset(nodenames, 0, sizeof(nodenames));
- memset(nodenumbers, 0, sizeof(nodenumbers));
- memset(&ninfo, 0, sizeof(ninfo));
- ninfo.nodeid = "1";
-
- while ( (opt = getopt_long(argc, argv, "n:o:c:m:vh?", addnodeid_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'n':
- validate_int_arg(opt, optarg);
- ninfo.nodeid = strdup(optarg);
- break;
-
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
-
- case 'o':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case 'm':
- if (!valid_mcast_addr(optarg)) {
- fprintf(stderr, "%s is not a valid multicast address\n", optarg);
- return;
- }
- ninfo.mcast_addr = strdup(optarg);
- break;
-
- case 'v':
- verbose++;
- break;
-
- case '?':
- default:
- addnodeid_usage(argv[0]);
- }
- }
-
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
-
- increment_version(root_element);
-
- /* Warn if the cluster doesn't have a multicast address */
- mcast = find_multicast_addr(root_element);
- if (!mcast & !ninfo.mcast_addr) {
- fprintf(stderr, "\nWARNING: The cluster does not have a multicast address.\n");
- fprintf(stderr, "A default will be assigned a run-time which might not suit your installation\n\n");
- }
-
- if (ninfo.mcast_addr) {
- if (!mcast) {
- xmlNode *cman = xmlNewNode(NULL, BAD_CAST "cman");
- mcast = xmlNewNode(NULL, BAD_CAST "multicast");
-
- xmlAddChild(cman, mcast);
- xmlAddChild(root_element, cman);
- }
- xmlSetProp(mcast, BAD_CAST "addr", BAD_CAST ninfo.mcast_addr);
- }
-
- /* Get a list of nodes that /do/ have nodeids so we don't generate
- any duplicates */
- nodeidx=0;
- clusternodes = findnode(root_element, "clusternodes");
- if (!clusternodes)
- die("Can't find \"clusternodes\" in %s\n", ninfo.configfile);
-
-
- for (cur_node = clusternodes->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0)
- {
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
- xmlChar *nodeid = xmlGetProp(cur_node, BAD_CAST "nodeid");
- nodenames[nodeidx] = name;
- if (nodeid)
- nodenumbers[nodeidx] = atoi((char*)nodeid);
- nodeidx++;
- }
- }
- totalnodes = nodeidx;
-
- /* Loop round nodes adding nodeIDs where they don't exist. */
- nextid = next_nodeid(atoi(ninfo.nodeid), nodenumbers, totalnodes);
- for (i=0; i<totalnodes; i++)
- {
- if (nodenumbers[i] == 0)
- {
- nodenumbers[i] = nextid;
- nextid = next_nodeid(nextid, nodenumbers, totalnodes);
- if (verbose)
- fprintf(stderr, "Node %s now has id %d\n", nodenames[i], nodenumbers[i]);
- }
- }
-
- /* Now write them into the tree */
- nodeidx = 0;
- for (cur_node = clusternodes->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0)
- {
- char tmp[80];
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
-
- assert(strcmp((char*)nodenames[nodeidx], (char*)name) == 0);
-
- sprintf(tmp, "%d", nodenumbers[nodeidx]);
- xmlSetProp(cur_node, BAD_CAST "nodeid", BAD_CAST tmp);
- nodeidx++;
- }
- }
-
-
- /* Write it out */
- save_file(doc, &ninfo);
-
- /* Shutdown libxml */
- xmlCleanupParser();
-}
-
-void add_node(int argc, char **argv)
-{
- struct option_info ninfo;
- int opt;
- xmlDoc *doc;
- xmlNode *root_element;
-
- memset(&ninfo, 0, sizeof(ninfo));
- ninfo.votes = "1";
-
- while ( (opt = getopt_long(argc, argv, "v:n:a:f:o:c:h?", addnode_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'v':
- validate_int_arg(opt, optarg);
- ninfo.votes = optarg;
- break;
-
- case 'n':
- validate_int_arg(opt, optarg);
- ninfo.nodeid = optarg;
- break;
-
- case 'a':
- ninfo.altname = strdup(optarg);
- break;
-
- case 'f':
- ninfo.fence_type = strdup(optarg);
- break;
-
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
-
- case 'o':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case '?':
- default:
- addnode_usage(argv[0]);
- }
- }
-
- /* Get node name parameter */
- if (optind < argc)
- ninfo.name = strdup(argv[optind]);
- else
- addnode_usage(argv[0]);
-
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
-
- increment_version(root_element);
-
- add_clusternode(root_element, &ninfo, argc, argv, optind);
-
- /* Write it out */
- save_file(doc, &ninfo);
- /* Shutdown libxml */
- xmlCleanupParser();
-
-}
-
-void del_node(int argc, char **argv)
-{
- struct option_info ninfo;
- int opt;
- xmlDoc *doc;
- xmlNode *root_element;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "o:c:h?", delnode_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
-
- case 'o':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case '?':
- default:
- delnode_usage(argv[0]);
- }
- }
-
- /* Get node name parameter */
- if (optind < argc)
- ninfo.name = strdup(argv[optind]);
- else
- delnode_usage(argv[0]);
-
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
-
- increment_version(root_element);
-
- del_clusternode(root_element, &ninfo);
-
- /* Write it out */
- save_file(doc, &ninfo);
-}
-
-void list_nodes(int argc, char **argv)
-{
- xmlNode *cur_node;
- xmlNode *root_element;
- xmlNode *clusternodes;
- xmlNode *fencenode = NULL;
- xmlDocPtr doc;
- xmlNode *mcast;
- struct option_info ninfo;
- int opt;
- int verbose = 0;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "c:vh?", list_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
- case 'v':
- verbose++;
- break;
- case '?':
- default:
- list_usage(argv[0]);
- }
- }
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
-
-
- printf("\nCluster name: %s, config_version: %s\n\n",
- (char *)cluster_name(root_element),
- (char *)find_version(root_element));
-
- clusternodes = findnode(root_element, "clusternodes");
- if (!clusternodes)
- die("Can't find \"clusternodes\" in %s\n", ninfo.configfile);
-
- mcast = find_multicast_addr(root_element);
- if (mcast)
- printf("Multicast address for cluster: %s\n\n", xmlGetProp(mcast, BAD_CAST "addr"));
-
- printf("Nodename Votes Nodeid Fencetype\n");
- for (cur_node = clusternodes->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "clusternode") == 0)
- {
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
- xmlChar *votes = xmlGetProp(cur_node, BAD_CAST "votes");
- xmlChar *nodeid = xmlGetProp(cur_node, BAD_CAST "nodeid");
- xmlChar *ftype = get_fence_type(cur_node, &fencenode);
-
- if (!nodeid)
- nodeid=(unsigned char *)"0";
- if (!votes)
- votes = (unsigned char *)"1";
-
- printf("%-32s %3d %3d %s\n", name, atoi((char *)votes),
- atoi((char *)nodeid),
- ftype?ftype:(xmlChar *)"");
- if (verbose)
- {
- xmlNode *a = findnode(cur_node, "altname");
- if (a)
- {
- printf(" altname %s=%s", "name", xmlGetProp(a, BAD_CAST "name"));
- if (!print_properties(a, "","",""))
- printf("\n");
- }
- print_properties(cur_node, " Node properties: ", "votes", "nodeid");
- print_properties(fencenode, " Fence properties: ", "agent", "");
- }
-
- }
- }
-}
-
-void create_skeleton(int argc, char **argv)
-{
- char *fencename = NULL;
- char *clustername;
- struct option_info ninfo;
- struct stat st;
- FILE *outfile;
- int i;
- int twonode = 0;
- int numnodes=0;
- int opt;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "c:2hn:f:?", create_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case '2':
- twonode = 1;
- numnodes = 2;
- break;
- case 'n':
- numnodes = atoi(optarg);
- break;
- case 'f':
- fencename = strdup(optarg);
- break;
-
- case '?':
- default:
- create_usage(argv[0]);
- }
- }
- if (!ninfo.outputfile)
- ninfo.outputfile = DEFAULT_CONFIG_DIR "/" DEFAULT_CONFIG_FILE;
- ninfo.configfile = "-";
-
- if (argc - optind < 1)
- create_usage(argv[0]);
-
- clustername = argv[optind];
-
- if (stat(ninfo.outputfile, &st) == 0)
- die("%s already exists", ninfo.outputfile);
-
- /* Init libxml */
- outfile = fopen(ninfo.outputfile, "w+");
- if (!outfile) {
- perror(" Can't open output file");
- return;
- }
-
- fprintf(outfile, "<?xml version=\"1.0\"?>\n");
- fprintf(outfile, "<cluster name=\"%s\" config_version=\"1\">\n", clustername);
- fprintf(outfile, "\n");
- if (twonode) {
- fprintf(outfile, " <cman two_node=\"1\" expected_votes=\"1\"/>\n");
- }
-
- fprintf(outfile, " <clusternodes>\n");
- for (i=1; i <= numnodes; i++) {
- fprintf(outfile, " <clusternode name=\"NEEDNAME-%02d\" votes=\"1\" nodeid=\"%d\">\n", i, i);
- fprintf(outfile, " <fence>\n");
- fprintf(outfile, " <method name=\"single\">\n");
- if (fencename) {
- fprintf(outfile, " <device name=\"fence1\" ADDARGS/>\n");
- }
- fprintf(outfile, " </method>\n");
- fprintf(outfile, " </fence>\n");
- fprintf(outfile, " </clusternode>\n");
- }
- fprintf(outfile, " </clusternodes>\n");
- fprintf(outfile, "\n");
- fprintf(outfile, " <fencedevices>\n");
- if (fencename) {
- fprintf(outfile, " <fencedevice name=\"fence1\" agent=\"%s\" ADDARGS/>\n", fencename);
- }
- fprintf(outfile, " </fencedevices>\n");
- fprintf(outfile, "\n");
- fprintf(outfile, " <rm>\n");
- fprintf(outfile, " <failoverdomains/>\n");
- fprintf(outfile, " <resources/>\n");
- fprintf(outfile, " </rm>\n");
- fprintf(outfile, "</cluster>\n");
-
- fclose(outfile);
-}
-
-void add_fence(int argc, char **argv)
-{
- xmlNode *root_element;
- xmlNode *fencedevices;
- xmlNode *fencenode = NULL;
- xmlDocPtr doc;
- char *fencename;
- char *agentname;
- struct option_info ninfo;
- int opt;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "c:o:h?", list_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
- case 'o':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case '?':
- default:
- addfence_usage(argv[0]);
- }
- }
-
- if (argc - optind < 2)
- addfence_usage(argv[0]);
-
- doc = open_configfile(&ninfo);
- root_element = xmlDocGetRootElement(doc);
-
- increment_version(root_element);
-
- fencedevices = findnode(root_element, "fencedevices");
- if (!fencedevices)
- die("Can't find \"fencedevices\" %s\n", ninfo.configfile);
-
- /* First param is the fence name - check it doesn't already exist */
- fencename = argv[optind++];
-
- if (valid_fence_type(root_element, fencename))
- die("fence type %s already exists\n", fencename);
-
- agentname = argv[optind++];
-
- /* Add it */
- fencenode = xmlNewNode(NULL, BAD_CAST "fencedevice");
- xmlSetProp(fencenode, BAD_CAST "name", BAD_CAST fencename);
- xmlSetProp(fencenode, BAD_CAST "agent", BAD_CAST agentname);
-
- /* Add name=value options */
- add_fence_args(fencenode, argc, argv, optind);
-
- xmlAddChild(fencedevices, fencenode);
-
- save_file(doc, &ninfo);
-}
-
-void del_fence(int argc, char **argv)
-{
- xmlNode *root_element;
- xmlNode *fencedevices;
- xmlNode *fencenode;
- xmlDocPtr doc;
- char *fencename;
- struct option_info ninfo;
- int opt;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "c:o:hv?", list_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
- case 'o':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case '?':
- default:
- delfence_usage(argv[0]);
- }
- }
-
- if (argc - optind < 1)
- delfence_usage(argv[0]);
-
- fencename = argv[optind];
-
- doc = open_configfile(&ninfo);
- root_element = xmlDocGetRootElement(doc);
- increment_version(root_element);
-
- fencedevices = findnode(root_element, "fencedevices");
- if (!fencedevices)
- die("Can't find \"fencedevices\" in %s\n", ninfo.configfile);
-
- fencenode = valid_fence_type(root_element, fencename);
- if (!fencenode)
- die("fence type %s does not exist\n", fencename);
-
- xmlUnlinkNode(fencenode);
-
- save_file(doc, &ninfo);
-}
-
-void list_fences(int argc, char **argv)
-{
- xmlNode *cur_node;
- xmlNode *root_element;
- xmlNode *fencedevices;
- xmlDocPtr doc;
- struct option_info ninfo;
- int opt;
- int verbose=0;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "c:hv?", list_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
- case 'v':
- verbose++;
- break;
- case '?':
- default:
- list_usage(argv[0]);
- }
- }
- doc = open_configfile(&ninfo);
- root_element = xmlDocGetRootElement(doc);
-
- fencedevices = findnode(root_element, "fencedevices");
- if (!fencedevices)
- die("Can't find \"fencedevices\" in %s\n", ninfo.configfile);
-
-
- printf("Name Agent\n");
- for (cur_node = fencedevices->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "fencedevice") == 0)
- {
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
- xmlChar *agent = xmlGetProp(cur_node, BAD_CAST "agent");
-
- printf("%-16s %s\n", name, agent);
- if (verbose)
- print_properties(cur_node, " Properties: ", "agent", "");
- }
- }
-}
-
diff --git a/config/tools/ccs_tool/editconf.h b/config/tools/ccs_tool/editconf.h
deleted file mode 100644
index 1847e2c..0000000
--- a/config/tools/ccs_tool/editconf.h
+++ /dev/null
@@ -1,8 +0,0 @@
-void add_node(int argc, char **argv);
-void add_nodeids(int argc, char **argv);
-void add_fence(int argc, char **argv);
-void del_node(int argc, char **argv);
-void del_fence(int argc, char **argv);
-void list_nodes(int argc, char **argv);
-void list_fences(int argc, char **argv);
-void create_skeleton(int argc, char **argv);
diff --git a/config/tools/ldap/Makefile b/config/tools/ldap/Makefile
deleted file mode 100644
index f58c788..0000000
--- a/config/tools/ldap/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-TARGET= confdb2ldif
-
-SBINDIRT=$(TARGET)
-
-SUBDIRS=rng2ldif
-
-all: ${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
-include $(OBJDIR)/make/passthrough.mk
-
-OBJS= confdb2ldif.o
-
-CFLAGS += -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
-CFLAGS += -I${corosyncincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${corosynclibdir} -lconfdb
-LDFLAGS += -L${libdir}
-
-${TARGET}: ${OBJS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-clean: generalclean
-
--include $(OBJS:.o=.d)
diff --git a/config/tools/ldap/confdb2ldif.c b/config/tools/ldap/confdb2ldif.c
deleted file mode 100644
index 6891f27..0000000
--- a/config/tools/ldap/confdb2ldif.c
+++ /dev/null
@@ -1,179 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <signal.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/un.h>
-
-#include <corosync/confdb.h>
-
-confdb_callbacks_t callbacks = {
-};
-
-static const char *ldap_attr_name(const char *attrname)
-{
- static char newname[1024];
- int i;
-
- if (strcmp(attrname, "name") == 0)
- return attrname;
-
- sprintf(newname, "rhcs");
- for (i=0; i<strlen(attrname)+1; i++) {
- if (i == 0)
- newname[4+i] = attrname[i] & 0x5F;
- else
- if (attrname[i] == '_')
- newname[4+i] = '-';
- else
- newname[4+i] = attrname[i];
- }
- return newname;
-}
-
-
-/* Recursively dump the object tree */
-static void print_config_tree(confdb_handle_t handle, hdb_handle_t parent_object_handle, const char *dn, char *fulldn)
-{
- hdb_handle_t object_handle;
- char object_name[1024];
- size_t object_name_len;
- char key_name[1024];
- char *key_value=NULL;
- confdb_value_types_t type;
- size_t key_value_len;
- char cumulative_dn[4096];
- int res;
- int keycount=0;
-
- printf("\ndn: %s\n", fulldn);
-
- /* Show the keys */
- res = confdb_key_iter_start(handle, parent_object_handle);
- if (res != CS_OK) {
- printf( "error resetting key iterator for object "HDB_X_FORMAT": %d\n", parent_object_handle, res);
- return;
- }
-
- while ( (res = confdb_key_iter_typed2(handle, parent_object_handle, key_name,
- (void**)&key_value, &key_value_len, &type)) == CS_OK) {
- key_value[key_value_len] = '\0';
-
- printf("%s: %s\n", ldap_attr_name(key_name), key_value);
- keycount++;
- free(key_value);
- key_value=NULL;
- }
- if (strncmp(fulldn, "cn=", 3) == 0) {
- printf("cn: %s\n", dn);
- }
-
-
- /* Determine objectclass... */
- if (keycount == 0) {
- printf("objectclass: nsContainer\n");
- }
- else {
- printf("objectclass: %s\n", ldap_attr_name(dn));
- }
-
- /* Show sub-objects */
- res = confdb_object_iter_start(handle, parent_object_handle);
- if (res != CS_OK) {
- printf( "error resetting object iterator for object "HDB_X_FORMAT": %d\n", parent_object_handle, res);
- return;
- }
-
- while ( (res = confdb_object_iter(handle, parent_object_handle, &object_handle, object_name, &object_name_len)) == CS_OK) {
- hdb_handle_t parent;
-
- res = confdb_object_parent_get(handle, object_handle, &parent);
- if (res != CS_OK) {
- printf( "error getting parent for object "HDB_X_FORMAT": %d\n", object_handle, res);
- return;
- }
-
- object_name[object_name_len] = '\0';
-
- /* Check for "name", and create dummy parent object */
- res = confdb_key_get_typed2(handle, object_handle, "name", (void **)&key_value, &key_value_len, &type);
- if (res == CS_OK) {
- sprintf(cumulative_dn, "cn=%s,%s", object_name, fulldn);
- printf("\n");
- printf("dn: %s\n", cumulative_dn);
- printf("cn: %s\n", object_name);
- printf("objectclass: %s\n", "nsContainer");
- snprintf(cumulative_dn, sizeof(cumulative_dn) - 1, "name=%s,cn=%s,%s", key_value, object_name, fulldn);
- free(key_value);
- key_value = NULL;
- }
- else {
- sprintf(cumulative_dn, "cn=%s,%s", object_name, fulldn);
- }
-
- /* Down we go ... */
- print_config_tree(handle, object_handle, object_name, cumulative_dn);
- }
-}
-
-
-int main(int argc, char *argv[])
-{
- confdb_handle_t handle;
- int result;
- hdb_handle_t cluster_handle;
- const char *clusterroot = "cluster";
- char basedn[1024];
-
- if (argc == 1) {
- fprintf(stderr, "usage: \n");
- fprintf(stderr, " %s <dn> [<objdb root>]\n", argv[0]);
- fprintf(stderr, "\n");
- fprintf(stderr, " eg: \n");
- fprintf(stderr, " %s dc=mycompany,dc=com\n", argv[0]);
- fprintf(stderr, " %s dc=mycompany,dc=com rhcluster\n", argv[0]);
- fprintf(stderr, "\n");
- fprintf(stderr, "objdb root defaults to 'cluster'\n");
- fprintf(stderr, "\n");
- return 0;
- }
-
- if (argc > 2) {
- clusterroot = argv[2];
- }
-
- result = confdb_initialize (&handle, &callbacks);
- if (result != CS_OK) {
- printf ("Could not initialize Cluster Configuration Database API instance error %d\n", result);
- exit (1);
- }
-
- /* Find the starting object ... this should be a param */
-
- result = confdb_object_find_start(handle, OBJECT_PARENT_HANDLE);
- if (result != CS_OK) {
- printf ("Could not start object_find %d\n", result);
- exit (1);
- }
-
- result = confdb_object_find(handle, OBJECT_PARENT_HANDLE, clusterroot, strlen(clusterroot), &cluster_handle);
- if (result != CS_OK) {
- printf ("Could not object_find \"cluster\": %d\n", result);
- exit (1);
- }
-
- sprintf(basedn, "name=%s,%s", clusterroot, argv[1]);
-
- /* Print a header */
- printf("# This file was generated by confdb2ldif, from an existing cluster configuration\n");
- printf("#\n");
-
- /* Print the configuration */
- print_config_tree(handle, cluster_handle, clusterroot, basedn);
-
-
- result = confdb_finalize (handle);
- return (0);
-}
diff --git a/config/tools/ldap/rng2ldif/Makefile b/config/tools/ldap/rng2ldif/Makefile
deleted file mode 100644
index 75a2b03..0000000
--- a/config/tools/ldap/rng2ldif/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-TARGET1= rng2ldif
-TARGET2= genclass
-
-all: ${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 += -I.
-CFLAGS += `xml2-config --cflags`
-CFLAGS += -I${incdir}
-
-LDFLAGS += `xml2-config --libs`
-LDFLAGS += -L${libdir}
-
-OBJS1= rng2ldif.o \
- tree.o
-
-OBJS2= genclass.o
-
-SHAREDOBJS= zalloc.o \
- value-list.o \
- ldaptypes.o \
- name.o
-
-${TARGET1}: ${SHAREDOBJS} ${OBJS1}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-${TARGET2}: ${SHAREDOBJS} ${OBJS2}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-ldif-update: all $(SRCDIR)/config/plugins/ldap/ldap-base.csv
- make -C $(OBJDIR)/config/tools/xml cluster.rng
- ./rng2ldif $(OBJDIR)/config/tools/xml/cluster.rng \
- $(SRCDIR)/config/plugins/ldap/ldap-base.csv \
- $(SRCDIR)/config/plugins/ldap/99cluster.ldif
-
-clean: generalclean
-
--include $(OBJS1:.o=.d)
--include $(OBJS2:.o=.d)
--include $(SHAREDOBJS:.o=.d)
diff --git a/config/tools/ldap/rng2ldif/debug.h b/config/tools/ldap/rng2ldif/debug.h
deleted file mode 100644
index 907e096..0000000
--- a/config/tools/ldap/rng2ldif/debug.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _DEBUG_H
-#define _DEBUG_H
-
-#ifdef DEBUG
-#define dbg_printf printf
-#else
-#define dbg_printf(args...)
-#endif
-
-#endif
diff --git a/config/tools/ldap/rng2ldif/genclass.c b/config/tools/ldap/rng2ldif/genclass.c
deleted file mode 100644
index 7607714..0000000
--- a/config/tools/ldap/rng2ldif/genclass.c
+++ /dev/null
@@ -1,102 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include "value-list.h"
-#include "tree.h"
-
-
-static void
-id_gen_object_struct(struct idinfo *oi, FILE *fp)
-{
- struct idval *v;
-
- fprintf(fp, "struct objectclasses\n");
- fprintf(fp, "{\n");
- fprintf(fp, "\tchar *name;\n");
- fprintf(fp, "\tchar *class;\n");
- fprintf(fp, "} objectclasses[] = \n");
- fprintf(fp, "{\n");
-
- for (v = oi->head; v->next; v = v->next) {
- if (v->type != OBJ)
- continue;
- fprintf(fp, "\t{ \"%s\", \"%s\" }, \n",
- v->rawname, v->name);
- }
-
- fprintf(fp, "\t{ \"%s\", \"%s\" }\n};\n",
- v->rawname, v->name);
-}
-
-
-static int
-write_class_struct(char *csv, char *arg, struct idinfo *ids)
-{
- char filename[4096];
- FILE *out = NULL;
- int fd = -1;
-
- if (!strcmp(arg, "-")) {
- out = stdout;
- } else {
- snprintf(filename, sizeof(filename), "%s.XXXXXX", arg);
- fd = mkstemp(filename);
- if (fd < 0) {
- perror("mkstemp");
- return -1;
- }
-
- out = fdopen(fd, "w");
- if (out == NULL) {
- perror("fdopen");
- close(fd);
- return -1;
- }
- }
-
- fprintf(out, "/* Begin autogenerated class struct from %s */\n", csv);
- id_gen_object_struct(ids, out);
- fprintf(out, "/* End autogenerated class struct */\n");
-
- fflush(out);
-
- if (fd >= 0) {
- fsync(fd);
- fclose(out);
- close(fd);
- rename(filename, arg);
- }
-
- return 0;
-}
-
-
-int
-main(int argc, char **argv)
-{
- struct idinfo info;
-
- memset(&info, 0, sizeof(info));
-
- if (argc < 3) {
- printf("Translate csv -> C structure\n"
- "file for future reuse of IDs\n");
- printf("Usage: %s file.csv output.c\n",
- argv[0]);
- return 1;
- }
-
- if (id_readfile(&info, argv[1]) < 0) {
- printf("Can't read %s\n", argv[1]);
- return 1;
- }
-
- write_class_struct(argv[1], argv[2], &info);
-
- return 0;
-}
diff --git a/config/tools/ldap/rng2ldif/ldaptypes.c b/config/tools/ldap/rng2ldif/ldaptypes.c
deleted file mode 100644
index beb0de9..0000000
--- a/config/tools/ldap/rng2ldif/ldaptypes.c
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include "ldaptypes.h"
-#include "debug.h"
-
-struct type_entry {
- const char *rng_name;
- const char *ldap_equality;
- const char *ldap_syntax;
-};
-
-
-struct type_entry type_table[] = {
-{ "boolean", "booleanMatch", "1.3.6.1.4.1.1466.115.121.1.7" },
-{ "integer", "integerMatch", "1.3.6.1.4.1.1466.115.121.1.27" },
-{ "positiveInteger", "integerMatch", "1.3.6.1.4.1.1466.115.121.1.27" },
-{ "nonNegativeInteger", "integerMatch", "1.3.6.1.4.1.1466.115.121.1.27" },
-{ "string", "caseExactIA5Match", "1.3.6.1.4.1.1466.115.121.1.26" },
-{ "ID", "caseExactIA5Match", "1.3.6.1.4.1.1466.115.121.1.26" },
-{ NULL, "caseExactIA5Match", "1.3.6.1.4.1.1466.115.121.1.26" } };
-
-
-void
-find_ldap_type_info(const char *name,
- char **equality,
- char **syntax)
-{
- int x;
-
- for (x = 0; type_table[x].rng_name != NULL; x++)
- if (!strcasecmp(name, type_table[x].rng_name))
- break;
- dbg_printf("%s @ index %d\n", name, x);
-
- *equality = (char *)type_table[x].ldap_equality;
- *syntax = (char *)type_table[x].ldap_syntax;
-}
-
-
-#ifdef STANDALONE
-#include <stdio.h>
-int
-main(int argc, char **argv)
-{
- char *eq, *syn;
-
- find_ldap_type_info(argv[1], &eq, &syn);
-
- printf("EQUALITY %s\nSYNTAX %s\n", eq, syn);
-
- return 0;
-}
-#endif
diff --git a/config/tools/ldap/rng2ldif/ldaptypes.h b/config/tools/ldap/rng2ldif/ldaptypes.h
deleted file mode 100644
index 1546cf3..0000000
--- a/config/tools/ldap/rng2ldif/ldaptypes.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _LDAPTYPES_H
-#define _LDAPTYPES_H
-
-void find_ldap_type_info(const char *name,
- char **equality,
- char **syntax);
-
-#endif
diff --git a/config/tools/ldap/rng2ldif/name.c b/config/tools/ldap/rng2ldif/name.c
deleted file mode 100644
index 8cc5ef7..0000000
--- a/config/tools/ldap/rng2ldif/name.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <ctype.h>
-#include "name.h"
-#include "zalloc.h"
-
-char *
-normalize_name(const char *name)
-{
- char *ret_val;
- int size = 4, x;
-
- if (!strcasecmp(name, "name")) {
- ret_val = strdup(name);
- assert(ret_val!=NULL);
- goto out;
- }
-
- size = strlen(name)+5;
- ret_val = zalloc(size); /* 1 byte for null, 4 for rhcs */
- if (!ret_val)
- return NULL;
-
- snprintf(ret_val, size, "rhcs%s", name);
-
-out:
- for (x = 0; x < 4; x++)
- ret_val[x] |= 32;
- if (ret_val[4] == '_')
- ret_val[4] = '-';
- else
- ret_val[4] &= ~32;
- for (x = 5; x < size; x++) {
- if (ret_val[x] == '_') {
- ret_val[x] = '-';
- }
- }
-
- return ret_val;
-}
-
-#ifdef STANDALONE
-int
-main(int argc, char **argv)
-{
- char *val;
- if (argc < 2)
- return -1;
-
- val = normalize_name(argv[1]);
- if (!val)
- fprintf(stderr, "oops\n");
- printf("%s\n", val);
- free(val);
- return 0;
-}
-#endif
diff --git a/config/tools/ldap/rng2ldif/name.h b/config/tools/ldap/rng2ldif/name.h
deleted file mode 100644
index a332b45..0000000
--- a/config/tools/ldap/rng2ldif/name.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _NAME_H
-#define _NAME_H
-
-char *normalize_name(const char *name);
-
-#endif
diff --git a/config/tools/ldap/rng2ldif/rng2ldif.c b/config/tools/ldap/rng2ldif/rng2ldif.c
deleted file mode 100644
index 6b24dd2..0000000
--- a/config/tools/ldap/rng2ldif/rng2ldif.c
+++ /dev/null
@@ -1,232 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <string.h>
-#include <unistd.h>
-#include <time.h>
-
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include "value-list.h"
-#include "tree.h"
-
-
-struct faux_list {
- struct faux_list *next;
-};
-
-
-static void __attribute__((noinline))
-reverse(struct faux_list **list)
-{
- struct faux_list *node = NULL;
- struct faux_list *newlist = NULL;
-
- if (!list || (*list == NULL))
- return;
-
- while ((*list) != NULL) {
- node = *list;
- *list = node->next;
- node->next = newlist;
- newlist = node;
- }
- *list = node;
-}
-
-
-static int
-print_attr_node(FILE *fp, struct ldap_attr_node *node)
-{
- if (!node)
- return -1;
- if (!fp)
- fp = stdout;
-
- if (!strcasecmp(node->name, "name")) {
- /* Don't print 'name' out as an attr. */
- return 0;
- }
-
- fprintf(fp, "attributeTypes: (\n");
- fprintf(fp, " 1.3.6.1.4.1.2312.8.1.1.%d NAME '%s'\n",
- node->idval->value, node->name);
- fprintf(fp, " EQUALITY %s\n", node->ldap_equality);
- fprintf(fp, " SYNTAX %s\n", node->ldap_syntax);
- fprintf(fp, " SINGLE-VALUE\n )\n");
- return 0;
-}
-
-
-static int
-print_obj_node(FILE *fp, struct ldap_object_node *node)
-{
- struct ldap_attr_meta_node *n;
- const char *cmt = "";
-
- if (!node)
- return -1;
- if (!fp)
- fp = stdout;
-
- if (!node->required_attrs && !node->optional_attrs) {
- cmt = "#";
- fprintf(fp, "### Placeholder for %s\n", node->name);
- fprintf(fp,
- "### This object class currently has no attributes\n");
- }
-
- fprintf(fp, "%sobjectClasses: (\n", cmt);
- fprintf(fp, "%s 1.3.6.1.4.1.2312.8.1.2.%d NAME '%s' SUP top STRUCTURAL\n", cmt, node->idval->value, node->name);
-
- if (node->required_attrs) {
- fprintf(fp, "%s MUST ( ", cmt);
-
- if (node->need_cn) {
- fprintf(fp, "cn $ ");
- }
-
- for (n = node->required_attrs; n->next != NULL; n = n->next)
- fprintf(fp, "%s $ ", n->node->name);
- fprintf(fp, "%s )\n", n->node->name);
- } else {
- if (node->need_cn) {
- fprintf(fp, "%s MUST ( cn )\n", cmt);
- }
- }
-
- if (node->optional_attrs) {
- fprintf(fp, "%s MAY ( ", cmt);
- for (n = node->optional_attrs; n->next != NULL; n = n->next)
- fprintf(fp, "%s $ ", n->node->name);
- fprintf(fp, "%s )\n", n->node->name);
- }
- fprintf(fp, "%s )\n", cmt);
- return 0;
-}
-
-
-static xmlDocPtr
-open_relaxng(const char *filename)
-{
- xmlDocPtr p;
- xmlNodePtr n;
-
- p = xmlParseFile(filename);
- if (!p) {
- printf("Failed to parse %s\n", filename);
- }
-
- n = xmlDocGetRootElement(p);
- if (xmlStrcmp(n->name, (xmlChar *)"grammar")) {
- printf("%s is not a relaxng grammar\n", filename);
- xmlFreeDoc(p);
- return NULL;
- }
-
- return p;
-}
-
-
-static int
-write_ldap_schema(const char *rng, const char *arg,
- struct ldap_attr_node *attrs,
- struct ldap_object_node *objs)
-{
- struct ldap_attr_node *attr = NULL;
- struct ldap_object_node *obj = NULL;
- char filename[4096];
- FILE *out_ldap = NULL;
- char now_asc[128];
- time_t now;
- struct tm now_tm;
- int fd = -1;
-
- if (!strcmp(arg, "-")) {
- out_ldap = stdout;
- } else {
- snprintf(filename, sizeof(filename), "%s.XXXXXX", arg);
- fd = mkstemp(filename);
- if (fd < 0) {
- perror("mkstemp");
- return -1;
- }
-
- out_ldap = fdopen(fd, "w");
- if (out_ldap == NULL) {
- perror("fdopen");
- close(fd);
- return -1;
- }
- }
-
- now = time(NULL);
- memset(&now_tm, 0, sizeof(now_tm));
- if (localtime_r(&now, &now_tm) == NULL) {
- snprintf(now_asc, sizeof(now_asc), "???");
- } else {
- strftime(now_asc, sizeof(now_asc), "%F %T", &now_tm);
- }
-
- fprintf(out_ldap, "# Auto-generated @ %s\n", now_asc);
- fprintf(out_ldap, "dn: cn=schema\n");
-
- for (attr = attrs; attr; attr = attr->next)
- print_attr_node(out_ldap, attr);
- for (obj = objs; obj; obj= obj->next)
- print_obj_node(out_ldap, obj);
-
- fflush(out_ldap);
-
- if (fd >= 0) {
- fsync(fd);
- fclose(out_ldap);
- close(fd);
- rename(filename, arg);
- }
-
- return 0;
-}
-
-
-int
-main(int argc, char **argv)
-{
- struct ldap_attr_node *attrs = NULL;
- struct ldap_object_node *objs = NULL;
- struct idinfo info;
- xmlDocPtr doc;
-
- memset(&info, 0, sizeof(info));
-
- if (argc < 4) {
- printf("Translate cluster RelaxNG -> LDIF schema and update\n"
- "global .csv file for future reuse of IDs\n");
- printf("Usage: %s cluster.rng ldap-base.csv cluster.ldif\n",
- argv[0]);
- return 1;
- }
-
- doc = open_relaxng(argv[1]);
- if (doc == NULL) {
- printf("Cannot continue\n");
- return 1;
- }
-
- if (id_readfile(&info, argv[2]) < 0) {
- printf("Can't read %s\n", argv[2]);
- return 1;
- }
-
- find_objects(xmlDocGetRootElement(doc), &objs, &attrs, &info);
-
- reverse((struct faux_list **)&attrs);
- reverse((struct faux_list **)&objs);
-
- if (write_ldap_schema(argv[1], argv[3], attrs, objs) < 0)
- return -1;
-
- id_writefile(&info, argv[2]);
-
- return 0;
-}
diff --git a/config/tools/ldap/rng2ldif/tree.c b/config/tools/ldap/rng2ldif/tree.c
deleted file mode 100644
index 4c6c28f..0000000
--- a/config/tools/ldap/rng2ldif/tree.c
+++ /dev/null
@@ -1,433 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/xpath.h>
-#include <assert.h>
-
-#include "zalloc.h"
-#include "value-list.h"
-#include "tree.h"
-#include "name.h"
-#include "ldaptypes.h"
-#include "debug.h"
-
-
-static struct ldap_attr_node *
-find_attr_byname(struct ldap_attr_node *attrs, const char *name)
-{
- struct ldap_attr_node *n;
-
- for (n = attrs; n; n = n->next) {
- if (!strcmp(n->name, name))
- return n;
- }
- return NULL;
-}
-
-
-static struct ldap_attr_meta_node *
-find_meta_attr(struct ldap_attr_meta_node *metas, struct ldap_attr_node *attr)
-{
- struct ldap_attr_meta_node *n;
-
- for (n = metas; n; n = n->next) {
- if (n->node == attr)
- return n;
- }
- return NULL;
-}
-
-
-static struct ldap_attr_meta_node *
-find_meta_attr_byname(struct ldap_attr_meta_node *metas, const char *name)
-{
- struct ldap_attr_meta_node *n;
-
- for (n = metas; n; n = n->next) {
- if (!strcmp(n->node->name, name))
- return n;
- }
- return NULL;
-}
-
-
-static int
-find_data_match_fn(xmlNodePtr curr_node, char **match_fn, char **ldap_syntax)
-{
- xmlNodePtr n = NULL;
- char *type = NULL;
- int need_free = 1;
-
- for (n = curr_node; n; n = n->next) {
- if (!n->name ||
- strcasecmp((char *)n->name, "data"))
- continue;
- break;
- }
-
- if (n)
- type = (char *)xmlGetProp(n, (xmlChar *)"type");
-
- dbg_printf("type %s\n", type);
-
- if (!type) {
- type = (char *)"string";
- need_free = 0;
- }
-
- find_ldap_type_info(type, match_fn, ldap_syntax);
-
- if (need_free)
- xmlFree(type);
-
- return 1;
-}
-
-
-static struct ldap_attr_node *
-get_attr(xmlNodePtr curr_node, struct ldap_attr_node **attrs,
- struct idinfo *ids)
-{
- struct ldap_attr_node *n;
- struct idval *v;
- char *name, *normalized;
-
- name = (char *)xmlGetProp(curr_node, (xmlChar *)"name");
- normalized = normalize_name((const char *)name);
-
- n = find_attr_byname(*attrs, normalized);
- if (n) {
- free(normalized);
- return n;
- }
-
- n = zalloc(sizeof(*n));
-
- v = id_find(ids, normalized, ATTR, 0);
- if (!v) {
- v = zalloc(sizeof(*v));
- v->name = normalized;
- v->type = ATTR;
- v->rawname = (char *)name;
- id_insert(ids, v);
- } else {
- free(normalized);
- }
-
- n->idval = v;
- n->name = n->idval->name;
-
- dbg_printf("Lookin for data type for %s\n", n->name);
- find_data_match_fn(curr_node->xmlChildrenNode, &n->ldap_equality,
- &n->ldap_syntax);
-
- n->next = *attrs;
- *attrs = n;
-
- return n;
-}
-
-
-static struct ldap_object_node *
-find_obj(struct ldap_object_node *objs, const char *name)
-{
- struct ldap_object_node *n;
-
- for (n = objs; n; n = n->next) {
- if (!strcmp(n->name, name))
- return n;
- }
- return NULL;
-}
-
-
-static xmlNodePtr
-find_ref(xmlNodePtr curr_node)
-{
- xmlNodePtr n;
- char *name;
- char *tmp_name;
-
- dbg_printf("Trying to parse ref tag\n");
- name = (char *)xmlGetProp(curr_node, (xmlChar *)"name");
-
- n = xmlDocGetRootElement(curr_node->doc);
- n = n->xmlChildrenNode;
- for (; n; n = n->next) {
- if (n->type != XML_ELEMENT_NODE)
- continue;
- if (strcasecmp((char *)n->name, "define"))
- continue;
-
- tmp_name = (char *)xmlGetProp(n, (xmlChar *)"name");
- if (!tmp_name)
- continue;
- if (strcmp(tmp_name, name))
- continue;
-
- break;
- }
-
- if (!n) {
- fprintf(stderr, "Error in RelaxNG schema!\n");
- fprintf(stderr, "Unterminated reference: %s\n",
- name);
- exit(1);
- }
-
- return n->xmlChildrenNode;
-}
-
-
-static int
-find_optional_attributes(xmlNodePtr curr_node, int in_block,
- struct ldap_object_node *curr_obj,
- struct ldap_attr_node **attrs,
- struct idinfo *ids)
-{
- xmlNodePtr node;
- struct ldap_attr_node *attr;
- struct ldap_attr_meta_node *n;
-
- if (!curr_node || (curr_node->type == XML_ELEMENT_NODE &&
- (curr_node->name && !strcasecmp((char *)curr_node->name, "element")))) {
- return 0;
- }
-
- dbg_printf("lookin for optionals\n");
-
- for (node = curr_node; node; node = node->next) {
- if (node->type != XML_ELEMENT_NODE)
- continue;
- if (!strcasecmp((char *)node->name, "ref")) {
- find_optional_attributes(
- find_ref(node), 1, curr_obj, attrs, ids);
- }
- if (!strcasecmp((char *)node->name, "choice")) {
- find_optional_attributes(node->xmlChildrenNode, 1,
- curr_obj,
- attrs, ids);
- continue;
- }
- if (!strcasecmp((char *)node->name, "group")) {
- find_optional_attributes(node->xmlChildrenNode, 1,
- curr_obj,
- attrs, ids);
- continue;
- }
- if (!strcasecmp((char *)node->name, "optional")) {
- find_optional_attributes(node->xmlChildrenNode, 1,
- curr_obj,
- attrs, ids);
- continue;
- }
-
- if (!node->name || strcmp((char *)node->name,
- "attribute")) {
- continue;
- }
-
- if (!in_block)
- continue;
-
- attr = get_attr(node, attrs, ids);
- n = zalloc(sizeof(*n));
-
- dbg_printf("opt attr '%s'\n", attr->idval->name);
-
- if (find_meta_attr(curr_obj->required_attrs,
- attr)) {
- dbg_printf("skipping dup attr\n");
- continue;
- }
- if (find_meta_attr(curr_obj->optional_attrs,
- attr)) {
- dbg_printf("skipping dup attr on optional list\n");
- continue;
- }
-
- n->node = attr;
- n->next = curr_obj->optional_attrs;
- curr_obj->optional_attrs = n;
- }
- return 0;
-}
-
-
-static int
-find_required_attributes(xmlNodePtr curr_node,
- struct ldap_object_node *curr_obj,
- struct ldap_attr_node **attrs,
- struct idinfo *ids)
-{
- xmlNodePtr node;
- struct ldap_attr_node *attr;
- struct ldap_attr_meta_node *n;
-
- dbg_printf("lookin for required\n");
-
- for (node = curr_node; node; node = node->next) {
- if (node->type != XML_ELEMENT_NODE)
- continue;
- if (xmlStrcmp(node->name, (xmlChar *)"attribute"))
- continue;
-
- attr = get_attr(node, attrs, ids);
- n = zalloc(sizeof(*n));
-
- dbg_printf("req attr '%s'\n", attr->idval->name);
-
- if (find_meta_attr(curr_obj->required_attrs,
- attr)) {
- dbg_printf("skipping dup attr\n");
- continue;
- }
- if (find_meta_attr(curr_obj->optional_attrs,
- attr)) {
- dbg_printf("skipping dup attr on optional list\n");
- continue;
- }
-
- n->node = attr;
- n->next = curr_obj->required_attrs;
- curr_obj->required_attrs = n;
- }
- return 0;
-}
-
-
-static struct ldap_object_node *
-parse_element_tag(xmlNodePtr curr_node,
- struct ldap_object_node **objs,
- struct ldap_attr_node **attrs,
- struct idinfo *ids)
-{
- struct ldap_object_node *obj;
- char *n, *normalized;
- struct idval *v;
- int need_cn = 1;
-
- dbg_printf("Trying to parse element tag\n");
- n = (char *)xmlGetProp(curr_node, (xmlChar *)"name");
- normalized = normalize_name(n);
- v = id_find(ids, normalized, OBJ, 0);
-
- if (!v) {
- v = zalloc(sizeof(*v));
- v->name = normalized;
- v->rawname = n;
- v->type = OBJ;
- id_insert(ids, v);
- }
-
- obj = find_obj(*objs, v->name);
-
- if (!obj) {
- obj = zalloc(sizeof(*obj));
- obj->name = v->name;
- obj->idval = v;
- obj->next = *objs;
- *objs = obj;
- dbg_printf("New object class %s \n",obj->name);
- }
-
- find_optional_attributes(curr_node->xmlChildrenNode, 0,
- obj, attrs, ids);
- find_required_attributes(curr_node->xmlChildrenNode,
- obj, attrs, ids);
-
- if (find_meta_attr_byname(obj->required_attrs, "name") ||
- find_meta_attr_byname(obj->required_attrs, "cn")) {
- need_cn = 0;
- }
-
- if (need_cn &&
- (find_meta_attr_byname(obj->optional_attrs, "name") ||
- find_meta_attr_byname(obj->optional_attrs, "cn"))) {
- need_cn = 0;
- }
-
- if (need_cn) {
- dbg_printf("Object class might %s need 'MUST ( cn )' for proper LDIF\n", obj->name);
- obj->need_cn = 1;
- }
-
- return obj;
-}
-
-
-#if 0
-static struct ldap_object_node *
-parse_ref_tag(xmlNodePtr curr_node,
- struct ldap_object_node **objs,
- struct ldap_attr_node **attrs,
- struct idinfo *ids)
-{
- xmlXPathObjectPtr xobj;
- xmlXPathContextPtr xctx;
- char query[1024];
- char *n;
-
- dbg_printf("Trying to parse ref tag\n");
- n = (char *)xmlGetProp(curr_node, (xmlChar *)"name");
-
- snprintf(query, sizeof(query), "//define[@name=\"%s\"]", n);
- xctx = xmlXPathNewContext(curr_node->doc);
- assert(xctx);
- xobj = xmlXPathEvalExpression((xmlChar *)query, xctx);
-
- printf("%d nodes match %s\n", xobj->nodesetval->nodeNr, query);
-
- assert(0);
- return NULL;
-}
-#endif
-
-int
-find_objects(xmlNodePtr curr_node,
- struct ldap_object_node **objs,
- struct ldap_attr_node **attrs,
- struct idinfo *ids)
-{
- struct ldap_object_node *obj = NULL;
- int ret = 0;
-
- if (!curr_node)
- /* no objects found */
- return 0;
-
- for (; curr_node; curr_node = curr_node->next) {
- if (curr_node->type != XML_ELEMENT_NODE)
- continue;
- if (!strcasecmp((char *)curr_node->name, "element")) {
- obj = parse_element_tag(curr_node, objs, attrs, ids);
- ret = 1;
- } else {
- dbg_printf("Descend on %s\n", curr_node->name);
- }
-
- if (find_objects(curr_node->xmlChildrenNode,
- objs, attrs, ids)) {
- ret = 1;
- } else if (obj) {
- /*
- * We have an object, but when we
- * looked for children, it did not
- * have any. So, we can omit the
- * requirement for 'cn' in the
- * output LDIF here
- */
- if (obj->need_cn) {
- dbg_printf("Object class %s does not have"
- " any children; not outputting "
- "'MUST ( cn )'\n", obj->name);
- }
- obj->need_cn = 0;
- }
- }
-
- /* Child objects were found */
- return ret;
-}
diff --git a/config/tools/ldap/rng2ldif/tree.h b/config/tools/ldap/rng2ldif/tree.h
deleted file mode 100644
index f55c556..0000000
--- a/config/tools/ldap/rng2ldif/tree.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef _TREE_H
-#define _TREE_H
-
-struct ldap_attr_list {
- struct ldap_attr_node *head, *tail;
-};
-
-struct ldap_attr_node {
- struct ldap_attr_node *next;
- char *name; /* self->idval->name; do not free() */
- char *desc;
- char *ldap_equality;
- char *ldap_syntax;
- struct idval *idval;
-};
-
-struct ldap_attr_meta_node {
- struct ldap_attr_meta_node *next;
- struct ldap_attr_node *node;
-};
-
-struct ldap_object_node {
- struct ldap_object_node *next;
- char *name; /* self->idval->name; do not free() */
- char *desc;
- struct idval *idval;
- struct ldap_attr_meta_node *optional_attrs;
- struct ldap_attr_meta_node *required_attrs;
- int need_cn; /* If we don't have a 'name' or a 'cn' attribute,
- add one when we output the LDIF */
-};
-
-int
-find_objects(xmlNodePtr curr_node,
- struct ldap_object_node **objs,
- struct ldap_attr_node **attrs,
- struct idinfo *ids);
-
-
-#endif
diff --git a/config/tools/ldap/rng2ldif/value-list.c b/config/tools/ldap/rng2ldif/value-list.c
deleted file mode 100644
index 1de9181..0000000
--- a/config/tools/ldap/rng2ldif/value-list.c
+++ /dev/null
@@ -1,191 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <unistd.h>
-#include <string.h>
-#include "value-list.h"
-#include "zalloc.h"
-
-void
-id_insert(struct idinfo *i, struct idval *v)
-{
- if (v->type == ATTR) {
- if (v->value > i->max_attr)
- i->max_attr = v->value;
- if (!v->value)
- v->value = ++i->max_attr;
- } else /* if type == OBJ */ {
- if (v->value > i->max_obj)
- i->max_obj = v->value;
- if (!v->value)
- v->value = ++i->max_obj;
- }
-
- if (!i->head)
- i->head = v;
- if (i->tail)
- i->tail->next = v;
- i->tail = v;
-}
-
-
-struct idval *
-id_find(struct idinfo *oi, const char *val, int type, int id)
-{
- struct idval *v;
-
- if (!val && !id)
- return NULL;
-
- /* linear search */
- for (v = oi->head; v; v = v->next) {
- if (v->type != type)
- continue;
- if (val && !strcmp(val, v->name))
- return v;
- if (id && id == v->value)
- return v;
- }
-
- return NULL;
-}
-
-
-void
-id_dump(struct idinfo *oi, FILE *fp)
-{
- struct idval *v;
-
- fprintf(fp, "# Max attribute value: %d\n", oi->max_attr);
- fprintf(fp, "# Max object class value: %d\n", oi->max_obj);
-
- for (v = oi->head; v; v = v->next) {
- fprintf(fp, "%s,%s,%s,%d\n", v->type==OBJ?"obj":"attr",
- v->name, v->rawname, v->value);
- }
-}
-
-
-
-int
-id_writefile(struct idinfo *oi, char *filename)
-{
- char tmpfn[4096];
- FILE *fp;
- int fd;
-
- snprintf(tmpfn, sizeof(tmpfn), "%s.XXXXXX", filename);
- fd = mkstemp(tmpfn);
- if (fd < 0)
- return -1;
-
- fp = fdopen(fd, "w");
- if (!fp) {
- close(fd);
- unlink(tmpfn);
- return -1;
- }
-
- id_dump(oi, fp);
- fflush(fp);
- fsync(fd);
- fclose(fp);
- close(fd);
-
- /* done */
- rename(tmpfn, filename);
-
- return 0;
-}
-
-
-int
-id_readfile(struct idinfo *oi, char *filename)
-{
- char *c, *valp;
- struct idval *v;
- struct idval *tmp;
- FILE *fp;
- char buf[4096];
- int len, lineno = 0, entries = 0;
-
- fp = fopen(filename, "r");
- if (!filename) {
- perror("fopen");
- return 1;
- }
-
- while (fgets(buf, sizeof(buf), fp)) {
- ++lineno;
- if (!strlen(buf))
- continue;
- if (buf[0] == '#')
- continue;
- len = strlen(buf);
- while (buf[len-1] < ' ') {
- buf[len-1] = 0;
- --len;
- }
- v = zalloc(sizeof(*v));
-
- /* Attribute / object */
- c = strchr(buf, ',');
- if (!c || strlen(c) == 1) {
- fprintf(stderr,
- "%s: Malformed input on line %d: '%s'\n",
- filename, lineno, buf);
- exit(-2);
- }
-
- *c = 0;
- c++;
- if (!strncasecmp(buf, "attr",4)) {
- v->type = ATTR;
- } else if (!strncasecmp(buf, "obj", 3)) {
- v->type = OBJ;
- } else {
- fprintf(stderr, "%s: Unknown type on line %d: '%s'\n",
- filename, lineno, buf);
- exit(-2);
- }
-
- valp = strchr(c, ',');
- if (valp) {
- *valp = 0;
- valp++;
- }
- v->name = strdup(c);
- assert(v->name);
-
- c = valp;
-
- valp = strchr(c, ',');
- v->value = 0;
- if (valp) {
- *valp = 0;
- valp++;
- if (strlen(valp))
- v->value = atoi(valp);
- }
-
- v->rawname = strdup(c);
- assert(v->rawname);
-
- if (!id_find(oi, v->name, v->type, 0)) {
- tmp = id_find(oi, NULL, v->type, v->value);
- if (tmp) {
- fprintf(stderr, "%s: Duplicate id value: "
- "%d & %d, type %d\n", filename,
- tmp->value, v->value, v->type);
- exit(-1);
- }
- id_insert(oi, v);
- }
-
- ++entries;
- }
-
- fclose(fp);
-
- return 0;
-}
diff --git a/config/tools/ldap/rng2ldif/value-list.h b/config/tools/ldap/rng2ldif/value-list.h
deleted file mode 100644
index 2e43326..0000000
--- a/config/tools/ldap/rng2ldif/value-list.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _VALUE_LIST_H
-#define _VALUE_LIST_H
-
-struct idval {
- struct idval *next;
- char *name;
- char *rawname;
- int type;
- int value;
-};
-
-struct idinfo {
- struct idval *head;
- struct idval *tail;
- int max_obj;
- int max_attr;
-};
-
-void id_insert(struct idinfo *i, struct idval *v);
-struct idval * id_find(struct idinfo *oi, const char *val, int type, int id);
-void id_dump(struct idinfo *oi, FILE *fp);
-int id_readfile(struct idinfo *oi, char *filename);
-int id_writefile(struct idinfo *oi, char *filename);
-
-#define OBJ 1
-#define ATTR 0
-
-#endif
diff --git a/config/tools/ldap/rng2ldif/zalloc.c b/config/tools/ldap/rng2ldif/zalloc.c
deleted file mode 100644
index f05306d..0000000
--- a/config/tools/ldap/rng2ldif/zalloc.c
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <malloc.h>
-#include <string.h>
-#include <assert.h>
-#include "zalloc.h"
-
-void *
-zalloc(size_t size)
-{
- void *ret;
- size_t oddball;
-
- oddball = ( size % sizeof(void *) );
- if (oddball) {
- size -= oddball;
- size += sizeof(void *);
- }
-
- ret = malloc(size);
- if (!ret)
- assert(0);
- memset(ret, 0, size);
- return ret;
-}
diff --git a/config/tools/ldap/rng2ldif/zalloc.h b/config/tools/ldap/rng2ldif/zalloc.h
deleted file mode 100644
index 0992ec2..0000000
--- a/config/tools/ldap/rng2ldif/zalloc.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ZALLOC_H
-#define _ZALLOC_H
-
-void *zalloc(size_t size);
-
-#endif
diff --git a/config/tools/man/Makefile b/config/tools/man/Makefile
deleted file mode 100644
index 65d07e0..0000000
--- a/config/tools/man/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-MANTARGET= \
- ccs_config_dump.8 \
- ccs_config_validate.8 \
- ccs_update_schema.8 \
- ccs_tool.8
-
-include ../../../make/defines.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-all:
-
-clean:
diff --git a/config/tools/man/ccs_config_dump.8 b/config/tools/man/ccs_config_dump.8
deleted file mode 100644
index 412aebb..0000000
--- a/config/tools/man/ccs_config_dump.8
+++ /dev/null
@@ -1,35 +0,0 @@
-.TH "ccs_config_dump" "8" "" "" ""
-.SH "NAME"
-ccs_config_dump \- Tool to generate XML output of running configuration.
-
-.SH "SYNOPSIS"
-.B ccs_config_dump
-[\fIOPTION\fR]..
-
-.SH "DESCRIPTION"
-
-\fBccs_config_dump\fP is part of the Cluster Configuration System (CCS).
-It is used to dump the current running configuration in XML format.
-The running configuration is, sometimes, different from the stored
-configuration on file because some subsystems store or set
-some default information into the configuration. Those values are
-generally not present on the on-disk version of the configuration
-but are required at runtime for the cluster to work properly.
-
-.SH "OPTIONS"
-.TP
-\fB\-h\fP
-Help. Print out the usage.
-.TP
-\fB\-V\fP
-Print the version information.
-.TP
-\fB\-r\fP
-Force config dump from running cluster. This option is only for expert users
-and debugging sessions. Don't use it for random purposes.
-ccs_config_dump can be configured to use different configuration sources via
-environment variables. This option will clear them to use the default and use
-only the runtime configuration.
-
-.SH "SEE ALSO"
-ccs_config_validate(8), cluster.conf(5)
diff --git a/config/tools/man/ccs_config_validate.8 b/config/tools/man/ccs_config_validate.8
deleted file mode 100644
index ac78178..0000000
--- a/config/tools/man/ccs_config_validate.8
+++ /dev/null
@@ -1,56 +0,0 @@
-.TH CCS_CONFIG_VALIDATE "8" "September 2009"
-.SH NAME
-ccs_config_validate
-.SH DESCRIPTION
-Usage:
-.PP
-ccs_config_validate [options]
-.SH OPTIONS
-.TP
-\fB\-h\fR
-Print this help, then exit
-.TP
-\fB\-V\fR
-Print program version information, then exit
-.TP
-\fB\-v\fR
-Produce verbose output
-.SS "Validating XML configuraton files:"
-.TP
-\fB\-f\fR configfile
-Validate an alternate config file without preloading it with default values.
-.TP
-\fB\-l\fR configfile
-Validate an alternate config file with preloading of default values (recommended option).
-.SS "Advanced options:"
-.TP
-\fB\-u\fR
-Do not update relaxng schema (see ccs_update_schema.8)
-.HP
-.TP
-\fB\-r\fR
-Force validation of runtime config
-.HP
-\fB\-C\fR config_loader
-Override config plugin loader
-.TP
-\fB\-t\fR tempfile
-Force temporay file to tempfile
-.TP
-\fB\-n\fR
-Do not remove temporary file
-.TP
-\fB\-o\fR
-Overwrite temporary file (dangerous)
-.SH "DEFAULT"
-Default operation for ccs_config_validate is to load the currently configured environment
-and verify the outcoming configuration.
-.TP
-Example 1: current environment uses a configuration file (/etc/cluster/cluster.conf).
-The user modifies cluser.conf and executes ccs_config_validate without options.
-The tool will validate the modified cluster.conf after including default values.
-.TP
-Example 2: current environment is set to load the configuration from LDAP. Users
-modifies LDAP databse and before pushing the change to the nodes, she/he can issue
-ccs_config_validate to verify the contents o the LDAP database automatically
-(as long as the correct LDAP environment is set in the cman/cluster sysconfig/defaults files).
diff --git a/config/tools/man/ccs_tool.8 b/config/tools/man/ccs_tool.8
deleted file mode 100644
index 056dcb3..0000000
--- a/config/tools/man/ccs_tool.8
+++ /dev/null
@@ -1,37 +0,0 @@
-.TH "ccs_tool" "8" "" "" ""
-.SH "NAME"
-ccs_tool \- The tool used to make online queries to the cluster configuration.
-
-.SH "SYNOPSIS"
-.B ccs_tool
-[\fIOPTION\fR].. <\fBcommand\fP>
-
-.SH "DESCRIPTION"
-
-\fBccs_tool\fP is part of the Cluster Configuration System (CCS). It used
-to peform different kind of queries to the cluster configuration.
-
-.SH "WARNING"
-
-All \fBccs_tool\fP editing capabilities are now obsoleted and unsupported.
-Please see also \fBccs\fP package and documentation for a more complete
-implementation of cluster.conf CLI editor.
-
-.SH "OPTIONS"
-.TP
-\fB\-h\fP
-Help. Print out the usage.
-.TP
-\fB\-V\fP
-Print the version information.
-
-sub\-commands have their own options, see below for more detail
-.SH "COMMANDS"
-
-.TP
-\fBquery\fP \fI<xpath query>\fP
-Perform an xpath query on running cluster configuration.
-
-.SH "SEE ALSO"
-.BR cluster.conf (5),
-.BR ccs (8)
diff --git a/config/tools/man/ccs_update_schema.8 b/config/tools/man/ccs_update_schema.8
deleted file mode 100644
index 3467c9c..0000000
--- a/config/tools/man/ccs_update_schema.8
+++ /dev/null
@@ -1,29 +0,0 @@
-.TH "ccs_update_schema" "8" "" "" ""
-.SH "NAME"
-ccs_update_schema \- Tool to generate cluster relaxng schema for cluster config validation.
-
-.SH "SYNOPSIS"
-.B ccs_update_schema
-[\fIOPTION\fR]..
-
-.SH "DESCRIPTION"
-
-\fBccs_update_schema\fP is part of the Cluster Configuration System (CCS).
-It is used to update the cluster relaxng schema that validates cluster.conf.
-
-.SH "OPTIONS"
-.TP
-\fB\-h\fP
-Help. Print out the usage.
-.TP
-\fB\-V\fP
-Print the version information.
-.TP
-\fB\-v\fP
-Be verbose. Mostly for debugging purposes.
-.TP
-\fB\-f\fP
-Ignore local stored cache and regenerate a fresh schema.
-
-.SH "SEE ALSO"
-ccs_config_validate(8), cluster.conf(5)
diff --git a/config/tools/man/confdb2ldif.8 b/config/tools/man/confdb2ldif.8
deleted file mode 100644
index 2964eec..0000000
--- a/config/tools/man/confdb2ldif.8
+++ /dev/null
@@ -1,64 +0,0 @@
-.TH confdb2ldif 8
-
-.SH NAME
-confdb2ldif - Create an LDIF file from a cluster configuration
-
-.SH SYNOPSIS
-.B confdb2ldap <basedn> [<config object base>]
-
-.SH DESCRIPTION
-\fBconfdb2ldif\fP reads the cluster configuration from the openais object database
-and generates an LDIF file suitable for importing into an LDAP database. The LDIF
-file is written to standard output.
-
-.SH OPTIONS
-.TP
-\fB<basedn>\fP
-This is the base DN of the LDAP server into which the configuration will be imported.
-confdb2ldif will create a "cn=cluster" object below this to contain the cluster configuration.
-The base DN is usually derived from the host's domain name. So if the host is ldapsrv.mycorp.com
-then the base DN could be dc=mycorp,dc=com.
-.TP
-\fB[<config object base>]\fP
-Configuration object in the objdb to start from. This defaults to "cluster" and
-there should rarely be any need to change it.
-
-.SH COMMENTS
-\fBconfdb2ldif\fP uses the openais libconfdb to read the configuration. The default way to
-do this is run against a running aisexec to read the live configuration.
-It is possible to generate an LDIF file from a non-running system by using the standalone feature of openais's libconfdb.
-.br
-eg to read the configuration from /etc/cluster/cluster.conf, use the following command:
-
-.nf
-OPENAIS_DEFAULT_CONFIG_IFACE=xmlconfig:cmanpreconfig confdb2ldif dc=mycompany,dc=com
-.fi
-
-or to do it from CCS
-
-.nf
-OPENAIS_DEFAULT_CONFIG_IFACE=ccsconfig:cmanpreconfig confdb2ldif dc=mycompany,dc=com
-.fi
-
-The LDIF file is written to stdout and so can be saved or piped straight into ldapmodify if required.
-.br
-.br
-It's important that the 99cluster.ldif schema file has been loaded into the LDAP server
-before adding the contents of this generated LDIF file.
-
-.SH EXAMPLE
-
-.nf
-confdb2ldif dc=mycorp,dc=com | ldapmodify -x -a -D"cn=Directory Manager" -c -v -W
-.fi
-
-.SH BUGS
-\fBconfdb2ldif\fP parses the cluster configuration without checking it against the loaded
-schema. So if there are attributes in the config file that are not known to the schema,
-parts of the load will fail. It is important to check the results of feeding the
-output into ldapmodify. In particular aisexec logging operations will not convert
-into LDIF because they rely on duplicate keys.
-
-
-.SH SEE ALSO
-libconfdb(3), openais(8), cluster.conf(5)
diff --git a/config/tools/xml/Makefile b/config/tools/xml/Makefile
deleted file mode 100644
index 3c9e97c..0000000
--- a/config/tools/xml/Makefile
+++ /dev/null
@@ -1,47 +0,0 @@
-include ../../../make/defines.mk
-
-TARGET1 = ccs_config_dump
-TARGET2 = ccs_config_validate
-TARGET3 = ccs_update_schema
-TARGET4 = cluster.rng
-
-SBINDIRT = $(TARGET1) $(TARGET2) $(TARGET3)
-SHAREDIRSYMT = $(TARGET4)
-RELAXNGDIRT = cluster.rng.in.head cluster.rng.in.tail
-
-all: $(TARGET1) $(TARGET2) $(TARGET3) $(TARGET4)
-
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-OBJS = ccs_config_dump.o
-
-CFLAGS += -I${corosyncincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${corosynclibdir} -lconfdb
-LDFLAGS += -L${libdir}
-
-${TARGET1}: ${OBJS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-${TARGET2}: $(S)/${TARGET2}.in
- cat $(S)/$(TARGET2).in | sed \
- -e 's#@SBINDIR@#${sbindir}#g' \
- -e 's#@SHAREDIR@#${sharedir}#g' \
- -e 's#@VERSION@#${RELEASE_VERSION}#g' \
- > $(TARGET2)
-
-${TARGET3}: $(S)/${TARGET3}.in
- cat $(S)/$(TARGET3).in | sed \
- -e 's#@SBINDIR@#${sbindir}#g' \
- -e 's#@SHAREDIR@#${sharedir}#g' \
- -e 's#@VERSION@#${RELEASE_VERSION}#g' \
- > $(TARGET3)
-
-${TARGET4}:
- ln -sf /var/lib/cluster/cluster.rng ${TARGET4}
-
-clean: generalclean
diff --git a/config/tools/xml/ccs_config_dump.c b/config/tools/xml/ccs_config_dump.c
deleted file mode 100644
index 1264aa3..0000000
--- a/config/tools/xml/ccs_config_dump.c
+++ /dev/null
@@ -1,187 +0,0 @@
-#include <stdio.h>
-#include <limits.h>
-#include <unistd.h>
-#include <corosync/corotypes.h>
-#include <corosync/confdb.h>
-
-#include "copyright.cf"
-
-#define OPTION_STRING "hVr"
-
-static confdb_callbacks_t callbacks = {};
-
-static int dump_objdb_buff(confdb_handle_t dump_handle, hdb_handle_t cluster_handle,
- hdb_handle_t parent_object_handle, int level)
-{
- hdb_handle_t object_handle;
- char object_name[PATH_MAX], key_name[PATH_MAX];
- char *key_value=NULL;
- size_t key_value_len = 0, object_name_len = 0;
- int current_level = level+1;
- int has_children = 0;
- confdb_value_types_t type;
-
- if (confdb_key_iter_start(dump_handle, parent_object_handle) != CS_OK)
- return -1;
-
- while (confdb_key_iter_typed2(dump_handle, parent_object_handle, key_name,
- (void**)&key_value,
- &key_value_len, &type) == CS_OK) {
- int char_pos = 0;
-
- key_value[key_value_len] = '\0';
- printf(" %s=\"", key_name);
- for (char_pos = 0; char_pos < key_value_len-1; char_pos++) {
- switch (key_value[char_pos]) {
-
- case '&':
- printf("&");
- break;
- case '<':
- printf("<");
- break;
- case '>':
- printf(">");
- break;
- case '"':
- printf(""");
- break;
- case '\'':
- printf("'");
- break;
- default:
- putchar(key_value[char_pos]);
- break;
- }
- }
- printf("\"");
- free(key_value);
- key_value = NULL;
- }
-
- if (confdb_object_iter_start(dump_handle, parent_object_handle) != CS_OK)
- return -1;
-
- while (confdb_object_iter(dump_handle, parent_object_handle,
- &object_handle, object_name,
- &object_name_len) == CS_OK) {
- hdb_handle_t parent;
- int i;
- int found_children;
-
- if ((!has_children) && (parent_object_handle > 0))
- printf(">\n");
-
- has_children = 1;
-
- if (confdb_object_parent_get(dump_handle, object_handle, &parent) != CS_OK)
- return -1;
-
- object_name[object_name_len] = '\0';
- for (i=0; i<current_level; i++) {
- printf("\t");
- }
- printf("<%s", object_name);
-
- found_children = dump_objdb_buff(dump_handle, cluster_handle, object_handle, current_level);
- if (found_children < 0)
- return -1;
-
- if ((object_handle != parent_object_handle) && (found_children)) {
- for (i=0; i<current_level; i++) {
- printf("\t");
- }
- printf("</%s>\n", object_name);
- }
- }
-
- if(!has_children)
- printf("/>\n");
-
- return has_children;
-}
-
-static void print_usage(void)
-{
- printf("Usage:\n");
- printf("\n");
- printf("ccs_config_dump [options]\n");
- printf("\n");
- printf("Options:\n");
- printf(" -r Force dump of runtime configuration (see man page)\n");
- printf(" -h Print this help, then exit\n");
- printf(" -V Print program version information, then exit\n");
- printf("\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 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case 'V':
- printf("ccs_config_dump %s (built %s %s)\n%s\n",
- RELEASE_VERSION, __DATE__, __TIME__,
- REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- break;
-
- case 'r':
- if(unsetenv("COROSYNC_DEFAULT_CONFIG_IFACE") < 0) {
- fprintf(stderr, "Unable to unset env vars\n");
- exit(EXIT_FAILURE);
- }
- break;
-
- case EOF:
- cont = 0;
- break;
-
- default:
- fprintf(stderr, "unknown option: %c\n", optchar);
- print_usage();
- exit(EXIT_FAILURE);
- break;
- }
- }
-}
-
-int main(int argc, char *argv[], char *envp[])
-{
- confdb_handle_t handle = 0;
- hdb_handle_t cluster_handle;
-
- read_arguments(argc, argv);
-
- if (confdb_initialize(&handle, &callbacks) != CS_OK)
- return -1;
-
- if (confdb_object_find_start(handle, OBJECT_PARENT_HANDLE) != CS_OK)
- return -1;
-
- if (confdb_object_find(handle, OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"), &cluster_handle) != CS_OK)
- return -1;
-
- printf("<?xml version=\"1.0\"?>\n<cluster");
-
- if (dump_objdb_buff(handle, cluster_handle, cluster_handle, 0) < 0)
- return -1;
-
- printf("</cluster>\n");
-
- if (confdb_finalize(handle) != CS_OK)
- return -1;
-
- return 0;
-}
diff --git a/config/tools/xml/ccs_config_validate.in b/config/tools/xml/ccs_config_validate.in
deleted file mode 100644
index 6573fef..0000000
--- a/config/tools/xml/ccs_config_validate.in
+++ /dev/null
@@ -1,242 +0,0 @@
-#!/bin/bash
-
-if [ -z "$COROSYNC_DEFAULT_CONFIG_IFACE" ]; then
- # rpm based distros
- if [ -d /etc/sysconfig ]; then
- [ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster
- [ -f /etc/sysconfig/cman ] && . /etc/sysconfig/cman
- fi
-
- # deb based distros
- if [ -d /etc/default ]; then
- [ -f /etc/default/cluster ] && . /etc/default/cluster
- [ -f /etc/default/cman ] && . /etc/default/cman
- fi
-
- [ -z "$CONFIG_LOADER" ] && CONFIG_LOADER=xmlconfig
- export COROSYNC_DEFAULT_CONFIG_IFACE=$CONFIG_LOADER:cmanpreconfig
-fi
-
-get_config_version() {
- local file=$1
-
- echo "xpath /cluster/@config_version" | \
- xmllint --shell "$file" | \
- grep content | \
- cut -f2 -d=
-}
-
-print_usage() {
- echo "Usage:"
- echo ""
- echo "ccs_config_validate [options]"
- echo ""
- echo "Options:"
- echo " -h Print this help, then exit"
- echo " -V Print program version information, then exit"
- echo " -v Produce verbose output"
- echo " -q Be very quiet"
- echo ""
- echo "Validating XML configuraton files:"
- echo " -f configfile Validate an alternate config file"
- echo " -l configfile Validate an alternate config file (load test)"
- echo ""
- echo "Advanced options:"
- echo " -u Do not update relaxng schema"
- echo " -r Force validation of runtime config"
- echo " -C config_loader Override config plugin loader"
- echo " -t tempfile Force temporay file to tempfile"
- echo " -n Do not remove temporary file"
- echo " -o Overwrite temporary file (dangerous)"
- echo " -R version When validating configuration update, ensure the"
- echo " new config is newer than the specified version."
-}
-
-check_opts() {
- while [ "$1" != "--" ]; do
- case $1 in
- -h)
- print_usage
- exit 0
- ;;
- -V)
- echo "ccs_config_validate version @VERSION@"
- exit 0
- ;;
- -t)
- shift
- tempfile="$1"
- ;;
- -n)
- notempfilerm=1
- ;;
- -o)
- overwritetempfile=1
- ;;
- -R)
- shift
- old_version=$1
- ;;
- -C)
- shift
- export COROSYNC_DEFAULT_CONFIG_IFACE=$1:cmanpreconfig
- loaderoverride=1
- if [ -n "$runtimetest" ] || \
- [ -n "$filetest" ] || \
- [ -n "$noloadtest" ]; then
- echo "Error: invalid options. -C can not be set together with -l or -r or -f" >&2
- exit 255
- fi
- ;;
- -l)
- shift
- export COROSYNC_CLUSTER_CONFIG_FILE=$1
- export COROSYNC_DEFAULT_CONFIG_IFACE=xmlconfig:cmanpreconfig
- filetest=1
- if [ -n "$loaderoverride" ] || \
- [ -n "$runtimetest" ] || \
- [ -n "$noloadtest" ]; then
- echo "Error: invalid options. -l can not be set together with -r or -C or -f" >&2
- exit 255
- fi
- ;;
- -f)
- shift
- export COROSYNC_CLUSTER_CONFIG_FILE=$1
- unset COROSYNC_DEFAULT_CONFIG_IFACE
- noloadtest=1
- if [ -n "$loaderoverride" ] || \
- [ -n "$runtimetest" ] || \
- [ -n "$filetest" ]; then
- echo "Error: invalid options. -f can not be set together with -r or -C or -l" >&2
- exit 255
- fi
- ;;
- -r)
- unset COROSYNC_DEFAULT_CONFIG_IFACE
- runtimetest=1
- if [ -n "$noloadtest" ] || \
- [ -n "$loaderoverride" ] || \
- [ -n "$filetest" ]; then
- echo "Error: invalid options. -r can not be set together with -l or -C or -f" >&2
- exit 255
- fi
- ;;
- -v)
- verbose=1
- if [ -n "$quiet" ]; then
- echo "Error: invalid options. -v can not be set together with -q" >&2
- exit 255
- fi
- ;;
- -q)
- quiet=1
- if [ -n "$verbose" ]; then
- echo "Error: invalid options. -q can not be set together with -v" >&2
- exit 255
- fi
- ;;
- -u)
- updaterelaxng=0
- ;;
- esac
- shift
- done
-}
-
-lecho()
-{
- [ -n "$verbose" ] && echo $@
- return 0
-}
-
-opts=$(getopt t:hVnC:f:l:rR:ovqu $@)
-if [ "$?" != 0 ]; then
- print_usage >&2
- exit 255
-fi
-check_opts $opts
-
-if [ -n "$tempfile" ]; then
- if [ -f "$tempfile" ] && [ -z "$overwritetempfile" ]; then
- echo "Selected temporary file $tempfile already exists" >&2
- echo "Use -o to force overwrite (dangerous)" >&2
- exit 255
- fi
-else
- tempfile=$(mktemp)
- if [ -z "$tempfile" ]; then
- echo "Unable to create temporary file" >&2
- exit 255
- fi
-fi
-lecho "Creating temporary file: $tempfile"
-lecho "Config interface set to: $COROSYNC_DEFAULT_CONFIG_IFACE"
-
-if [ -n "$noloadtest" ]; then
- cp $COROSYNC_CLUSTER_CONFIG_FILE $tempfile
-else
- export CMAN_PIPE=2
- if ! ccs_config_dump > $tempfile; then
- [ -z "$notempfilerm" ] && rm -f $tempfile
- echo
- echo "Unable to get the configuration" >&2
- exit 255
- fi
-fi
-lecho "Configuration stored in temporary file"
-
-lecho "Updating relaxng schema"
-if [ "$updaterelaxng" != 0 ]; then
- updateerr="$(ccs_update_schema 2>&1)"
- if [ $? != 0 ]; then
- echo "Unable to update relaxng schema: $updateerr" >&2
- exit 255
- fi
-fi
-
-if [ -f /var/lib/cluster/rng_update.lock ]; then
- echo "Relax-ng schema update in progress" >&2
- exit 255
-fi
-
-if [ ! -e @SHAREDIR@/cluster.rng ]; then
- echo "Unable to verify a configuration without relaxng schema" >&2
- exit 255
-fi
-
-lecho "Validating.."
-
-xmlout=$(xmllint --noout \
- --relaxng @SHAREDIR@/cluster.rng \
- $tempfile 2>&1)
-res=$?
-
-if [ -n "$old_version" ] && [ $old_version -ne 0 ] && [ $res -eq 0 ]; then
- new_version=$(get_config_version $tempfile)
- if [ -z "$new_version" ]; then
- [ -z "$quiet" ] && \
- echo "Error: Unable to determine new config version!" >&2
- [ -z "$notempfilerm" ] && rm -f $tempfile
- exit 253
- fi
- lecho "Old version: $old_version New version: $new_version"
- if [ $new_version -le $old_version ]; then
- [ -z "$quiet" ] && \
- echo "Error: Configuration version is older than running config!" >&2
- [ -z "$notempfilerm" ] && rm -f $tempfile
- exit 254
- fi
-fi
-
-if [ -z "$quiet" ] || [ "$res" != "0" ]; then
- echo "$xmlout" | sed \
- -e 's#.*validates$#Configuration validates#g' \
- -e 's#.*validate$#Configuration fails to validate#g' \
- -e 's#'$tempfile'#tempfile#g'
-fi
-
-lecho "Validation completed"
-
-[ -z "$notempfilerm" ] && rm -f $tempfile
-exit $res
diff --git a/config/tools/xml/ccs_update_schema.in b/config/tools/xml/ccs_update_schema.in
deleted file mode 100644
index d082ed3..0000000
--- a/config/tools/xml/ccs_update_schema.in
+++ /dev/null
@@ -1,377 +0,0 @@
-#!/bin/bash
-
-set +e
-export LC_ALL=C
-
-rngdir=@SHAREDIR@/relaxng
-rasdir=@SHAREDIR@
-fasdir=@SBINDIR@
-vardir=/var/lib/cluster
-force=""
-verbose=""
-
-print_usage() {
- echo "Usage:"
- echo ""
- echo "ccs_update_schema [options]"
- echo ""
- echo "Options:"
- echo " -h Print this help, then exit"
- echo " -V Print program version information, then exit"
- echo " -v Produce verbose output"
- echo " -f Force schema regeneration and ignore cache"
-}
-
-lecho() {
- [ -n "$verbose" ] && echo "$@"
- return 0
-}
-
-check_opts() {
- while [ "$1" != "--" ]; do
- case $1 in
- -h)
- print_usage
- exit 0
- ;;
- -V)
- echo "ccs_update_schema version @VERSION@"
- exit 0
- ;;
- -v)
- verbose=1
- ;;
- -f)
- force=1
- ;;
- esac
- shift
- done
-}
-
-opts=$(getopt hvVf $@)
-if [ "$?" != 0 ]; then
- print_usage >&2
- exit 1
-fi
-check_opts $opts
-
-tmpdir="$(mktemp -d -q)" || {
- echo "unable to create tempdir" >&2
- exit 1
-}
-export tmpdir
-
-# need to be careful (might have to mask traps on exit)
-cleanup() {
- [ "$1" != "0" ] && rm -f $vardir/*.cache $vardir/*.hash
- [ -n "$tmpdir" ] && [ -d "$tmpdir" ] && rm -rf "$tmpdir"
- rm -f $vardir/rng_update.lock
- exit $1
-}
-
-trap "cleanup 1" ABRT
-trap "cleanup 1" QUIT
-trap "cleanup 1" TERM
-trap "cleanup 1" INT
-trap "cleanup 1" ERR
-
-filter_file_list() {
- filelist="$@"
- for i in $filelist; do
- [ "${i%\~}" != "${i}" ] && continue
- [ "${i%,}" != "${i}" ] && continue
- [ "${i%.orig}" != "${i}" ] && continue
- [ "${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
- echo "$i"
- done
-}
-
-filter_fence_list() {
- filelist="$@"
- for i in $faslist; do
- [ "${i}" = "$fasdir/fence_legacy" ] && continue
- [ "${i}" = "$fasdir/fence_node" ] && continue
- [ "${i}" = "$fasdir/fence_nss_wrapper" ] && continue
- [ "${i}" = "$fasdir/fence_tool" ] && continue
- [ "${i}" = "$fasdir/fence_vmware_helper" ] && continue
- echo "$i"
- done
-}
-
-generate_hash() {
- outputfile="$1"
- shift
- filelist="$@"
-
- if [ -n "$filelist" ]; then
- md5sum $filelist > $outputfile
- return $?
- else
- echo -n > $outputfile
- return $?
- fi
-}
-
-create_ras_stubs() {
- lecho " ras: cannot find rng files. Creating stubs"
- touch "$outputdir/resources.rng.hash"
- cat > "$outputdir/resources.rng.cache" << EOF
-<!-- STUB resource-agents definitions -->
-<define name="SERVICE">
- <element name="service" rha:description="Stub service">
- <optional>
- <ref name="CHILDREN"/>
- </optional>
- </element>
-</define>
-<define name="VM" >
- <element name="vm" rha:description="Stub VM">
- <optional>
- <ref name="CHILDREN"/>
- </optional>
- </element>
-</define>
-<define name="CHILDREN">
- <zeroOrMore>
- <choice>
- <ref name="SERVICE"/>
- <ref name="VM"/>
- </choice>
- </zeroOrMore>
-</define>
-<!-- end STUB resource-agents definitions -->
-EOF
-}
-
-generate_ras() {
- outputdir="$1"
- raslist=""
-
- lecho " ras: checking required files"
-
- doras_stub=""
- for i in ra2rng.xsl ra2ref.xsl \
- resources.rng.head resources.rng.mid resources.rng.tail; do
- if [ ! -f "$rngdir/$i" ]; then
- doras_stub=yes
- fi
- done
-
- for i in service.sh vm.sh; do
- if [ ! -x "$rasdir/$i" ]; then
- doras_stub=yes
- fi
- done
-
- [ "$doras_stub" = yes ] && create_ras_stubs && return 0
-
- lecho " ras: looking for agents"
-
- if [ -d "$rasdir" ]; then
- raslist=$(find $rasdir \
- -mindepth 1 -maxdepth 1 -type f -executable | sort -u)
- raslist=$(filter_file_list $raslist)
- # ordering is important apparently
- [ -x $rasdir/service.sh ] && \
- raslist="$rasdir/service.sh \
- $(echo $raslist | sed -e 's#'$rasdir'/service.sh##g')"
- fi
-
- lecho " ras: generating hashes"
-
- if ! generate_hash \
- "$outputdir/resources.rng.hash" \
- "$raslist $rngdir/ra2*.xsl $rngdir/resources.rng.* $0"; then
- echo "Unable to generate resource agents hash" >&2
- return 1
- fi
-
- if [ -z "$force" ] && \
- [ -f $vardir/resources.rng.hash ] && \
- [ -f $vardir/resources.rng.cache ] && \
- [ "$(cat $vardir/resources.rng.hash | md5sum -)" = \
- "$(cat "$outputdir/resources.rng.hash" | md5sum -)" ]; then
- lecho " ras: using local cache"
- cp $vardir/resources.rng.cache $outputdir/resources.rng.cache
- return 0
- fi
-
- lecho " ras: generating rng data"
-
- cat $rngdir/resources.rng.head > "$outputdir/resources.rng.cache"
- lecho " ras: generating rng data"
- for i in $raslist; do
- lecho " ras: processing $(basename $i)"
- $i meta-data 2>/dev/null | xsltproc $rngdir/ra2rng.xsl - >> \
- "$outputdir/resources.rng.cache" 2>/dev/null
- done
- cat $rngdir/resources.rng.mid >> "$outputdir/resources.rng.cache"
- lecho " ras: generating ref data"
- for i in $raslist; do
- lecho " ras: processing $(basename $i)"
- $i meta-data 2>/dev/null | xsltproc $rngdir/ra2ref.xsl - >> \
- "$outputdir/resources.rng.cache" 2>/dev/null
- done
- cat $rngdir/resources.rng.tail >> "$outputdir/resources.rng.cache"
-}
-
-create_fas_stubs() {
- lecho " fas: cannot find rng files. Creating stubs"
- touch "$outputdir/fence_agents.rng.hash"
- cat > "$outputdir/fence_agents.rng.cache" << EOF
-<!-- STUB fence-agents definitions -->
-<define name="FENCEDEVICEOPTIONS">
- <element name="service" rha:description="Stub fence device options">
- <optional>
- <ref name="STUBFENCEDEVICEOPTIONS"/>
- </optional>
- </element>
-</define>
-<define name="STUBFENCEDEVICEOPTIONS">
- <zeroOrMore>
- <choice>
- <ref name="FENCEDEVICEOPTIONS"/>
- </choice>
- </zeroOrMore>
-</define>
-<!-- end STUB fence-agents definitions -->
-EOF
-}
-
-generate_fas() {
- outputdir="$1"
- faslist=""
-
- lecho " fas: checking required files"
-
- dofas_stub=""
- for i in fence2rng.xsl fence.rng.head fence.rng.tail; do
- if [ ! -f "$rngdir/$i" ]; then
- dofas_stub=yes
- fi
- done
-
- [ "$dofas_stub" = yes ] && create_fas_stubs && return 0
-
- lecho " fas: looking for agents"
-
- if [ -d "$fasdir" ]; then
- faslist=$(ls -1 $fasdir/fence_*)
- faslist=$(filter_file_list $faslist)
- faslist=$(filter_fence_list $faslist)
- fi
-
- lecho " fas: generating hashes"
-
- if ! generate_hash \
- "$outputdir/fence_agents.rng.hash" \
- "$faslist $rngdir/fence2*.xsl $rngdir/fence.rng.* $0"; then
- echo "Unable to generate fence agents hash" >&2
- return 1
- fi
-
- if [ -z "$force" ] && \
- [ -f $vardir/fence_agents.rng.hash ] && \
- [ -f $vardir/fence_agents.rng.cache ] && \
- [ "$(cat $vardir/fence_agents.rng.hash | md5sum -)" = \
- "$(cat "$outputdir/fence_agents.rng.hash" | md5sum -)" ]; then
- lecho " fas: using local cache"
- cp $vardir/fence_agents.rng.cache \
- $outputdir/fence_agents.rng.cache
- return 0
- fi
-
- lecho " fas: generating new cache"
-
- cat $rngdir/fence.rng.head > "$outputdir/fence_agents.rng.cache"
- for i in $faslist; do
- lecho " fas: processing $(basename $i)"
- $i -o metadata 2>/dev/null | \
- xsltproc $rngdir/fence2rng.xsl - >> \
- "$outputdir/fence_agents.rng.cache" 2>/dev/null
- [ "$?" != 0 ] && \
- echo " <!-- No metadata for $i -->" >> \
- "$outputdir/fence_agents.rng.cache"
- done
- cat $rngdir/fence.rng.tail >> "$outputdir/fence_agents.rng.cache"
-}
-
-build_schema() {
- cat $rngdir/cluster.rng.in.head \
- $outputdir/resources.rng.cache \
- $outputdir/fence_agents.rng.cache \
- $rngdir/cluster.rng.in.tail \
- > $outputdir/cluster.rng || {
- echo "generic error linking relaxng schema" >&2
- return 1
- }
-
- xmllint --noout $outputdir/cluster.rng || {
- echo "generated schema does not pass xmllint validation" >&2
- return 1
- }
-
- return 0
-}
-
-# NOTE
-# failure to delete cache and hash or failure to install them
-# is not fatal and will result in both being regenerated at the next run
-
-install_schema() {
- mkdir -p $outputdir/backup || {
- echo "Unable to create backup dir" >&2
- return 1
- }
- cp -a $vardir/*rng* $outputdir/backup/ || {
- echo "Unable to perform backup of current schema" >&2
- return 1
- }
- rm -f $vardir/*.cache $vardir/*.hash
- cp -f $outputdir/cluster.rng $vardir/ || {
- cp -a $outputdir/backup/* $vardir/
- echo "Failed to update relaxng ondisk data" >&2
- return 1
- }
- cp $outputdir/*.cache $outputdir/*.hash $vardir/
- return 0
-}
-
-(
- flock --exclusive 200
-
- lecho "Generating resource-agents cache"
-
- generate_ras "$tmpdir" || {
- echo "generic error creating resource agents relaxng schema" >&2
- cleanup 1
- }
-
- lecho "Generating fence-agents cache"
-
- generate_fas "$tmpdir" || {
- echo "generic error creating fence agents relaxng schema" >&2
- cleanup 1
- }
-
- lecho "Building final relaxng schema"
-
- build_schema || cleanup 1
-
- lecho "Installing schema in $vardir"
-
- install_schema || cleanup 1
-
- lecho "all done. have a nice day!"
-
- cleanup 0
-) 200>$vardir/rng_update.lock
diff --git a/config/tools/xml/cluster.rng.in.head b/config/tools/xml/cluster.rng.in.head
deleted file mode 100644
index 4e3d901..0000000
--- a/config/tools/xml/cluster.rng.in.head
+++ /dev/null
@@ -1,1125 +0,0 @@
-<grammar datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
-xmlns="http://relaxng.org/ns/structure/1.0"
-xmlns:rha="http://redhat.com/~pkennedy/annotation_namespace/cluster_conf_annot_namespa…">
-
-<!-- The cluster.conf schema follows this outline:
-
-cluster
-- cman
-- totem
-- uidgid
-- quorumd
-- fence_daemon
-- fence_xvmd
-- dlm
-- gfs_controld
-- group
-- logging
-- clusternodes
-- fencedevices
-- rm
-- clvmd
-
-Element definitions:
-- Resource
-- Fence
-
-To validate your cluster.conf against this schema, run:
-
- xmllint \-\-relaxng cluster.rng /path/to/cluster.conf
-
--->
-
-<start>
-<element name="cluster" rha:description="Defines cluster properties, and
- contains all other configuration. cluster.conf(5)">
- <attribute name="name" rha:description="Name of the cluster.
- cluster.conf(5)"/>
- <attribute name="config_version" rha:description="Revision level
- of cluster.conf file. cluster.conf(5)"/>
- <interleave>
-
-<!-- cman block -->
- <optional>
- <element name="cman" rha:description="The cman element contains
- attributes that define the following cluster-wide parameters and
- behaviors: whether the cluster is a two-node cluster, expected
- votes, user-specified multicast address, and logging.">
- <optional>
- <attribute name="two_node" rha:description="The two_node attribute
- allows you to configure a cluster with only two
- nodes. Ordinarily, the loss of quorum after one of two nodes
- fails prevents the remaining node from continuing (if both
- nodes have one vote.) To enable a two-node cluster, set the
- two_node value equal to 1. If the two_node value is enabled,
- the expected_votes value must be set to 1." rha:sample="1"/>
- </optional>
- <optional>
- <attribute name="expected_votes" rha:description="The expected
- votes value is used by cman to determine quorum. The cluster
- is quorate if the sum of votes of 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 overriden by setting an explicit
- expected_votes value." rha:sample="4">
- <data type="positiveInteger"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="upgrading" rha:description="Set this if you are
- performing a rolling upgrade of the cluster between major
- releases." rha:sample="no"/>
- </optional>
- <optional>
- <attribute name="disallowed" rha:description="Set this to 1 enable
- cman's Disallowed mode. This is usually only needed for
- backwards compatibility." rha:sample="1">
- <data type="nonNegativeInteger"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="quorum_dev_poll" rha:description="The amount of time
- after a qdisk poll, in milliseconds, before a quorum disk is
- considered dead. The quorum disk daemon, qdisk, periodically
- sends hello messages to cman and ais, indicating that qdisk
- is present. If qdisk takes more time to send a hello message
- to cman and ais than by quorum_dev_poll, then cman declares
- qdisk dead and prints a message indicating that connection to
- the quorum device has been lost." rha:sample="50000">
- <data type="nonNegativeInteger"/>
- </attribute>
- </optional>
- <!--FIXME: Clarify the following. What is meant by "service"? Also, is
- there a default value? What is a good sample value?-->
- <optional>
- <attribute name="shutdown_timeout" rha:description="Timeout period,
- in milliseconds, to allow a service to respond during a
- shutdown." rha:sample="5000">
- <data type="nonNegativeInteger"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="ccsd_poll" rha:description="" rha:sample=""
- rha:default="1000">
- <data type="nonNegativeInteger"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="debug_mask" rha:description="" rha:sample=""/>
- </optional>
- <optional>
- <attribute name="port">
- <data type="nonNegativeInteger"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="cluster_id">
- <data type="nonNegativeInteger"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="hash_cluster_id" rha:description="Enable stronger hashing of cluster ID to avoid collisions." />
- </optional>
- <optional>
- <attribute name="nodename" rha:description="Local node name; this is set internally by cman-preconfig and should never be set by a user."/>
- </optional>
- <optional>
- <attribute name="broadcast" rha:description="enable cman broadcast" rha:default="no"/>
- </optional>
- <optional>
- <attribute name="transport" rha:description="Specifies transport mechanism to use. Available values are udp (multicast default), udpb (broadcast), udpu (unicast) and rdma (Infiniband). corosync.conf(5)" rha:sample="">
- <choice>
- <value>udp</value>
- <value>udpb</value>
- <value>udpu</value>
- <value>rdma</value>
- </choice>
- </attribute>
- </optional>
- <optional>
- <attribute name="keyfile" rha:description=""/>
- </optional>
- <optional>
- <attribute name="disable_openais"/>
- </optional>
- <optional>
- <element name="multicast" rha:description="The multicast element
- provides the ability for a user to specify a multicast address,
- port and TTL (Time To Live) instead of using cman defaults. If
- a user does not specify a multicast address, cman creates one. It
- forms the upper 16 bits of the multicast address with 239.192 for
- IPv4 and ff15:: for IPv6 and forms the lower 16 bits based on
- the cluster ID.">
- <ref name="MULTICASTOPTS"/>
- </element>
- </optional>
- <optional>
- <element name="altmulticast" rha:description="The altmulticast element
- provides the ability for a user to specify a multicast address,
- port and TTL (Time To Live) instead of using cman defaults for
- the alternate communication channel (RRP). If a user does not
- specify an alternate multicast address, cman creates one. It
- forms the upper 16 bits of the multicast address with 239.192 for
- IPv4 and ff15:: for IPv6 and forms the lower 16 bits based on
- the cluster ID + 1.">
- <ref name="MULTICASTOPTS"/>
- </element>
- </optional>
- </element>
- </optional>
-<!-- end cman block -->
-
-<!-- uidgid block -->
- <optional>
- <zeroOrMore>
- <element name="uidgid" rha:description="Access control to corosync IPC">
- <optional>
- <attribute name="uid" rha:description="This is an unprivileged username,
- as globally available to the system via /etc/passwd, including nis/ldap,
- allowed to connect to corosync IPC. This value cannot be updated at runtime,
- a full cman restart is required." rha:default="" rha:samble="userfoo"/>
- </optional>
- <optional>
- <attribute name="gid" rha:description="This is an unprivileged group name,
- as globally available to the system via /etc/group, including nis/ldap,
- allowed to connect to corosync IPC. This value cannot be updated at runtime,
- a full cman restart is required." rha:default="" rha:samble="groupfoo"/>
- </optional>
- </element>
- </zeroOrMore>
- </optional>
-<!-- end uidgid block -->
-
-<!-- totem block -->
- <optional>
- <element name="totem" rha:description="OpenAIS msg transport
- protocol">
- <optional>
- <attribute name="consensus" rha:description="This is a timeout value
- that specifies how many milliseconds to wait for consensus
- to be achieved before starting a new round of membership
- configuration." rha:default="200" rha:sample="235"/>
- </optional>
- <optional>
- <attribute name="join" rha:description="This is a timeout value that
- specifies how many milliseconds to wait for join messages in
- the membership protocol." rha:default="100" rha:sample="95"/>
- </optional>
- <optional>
- <attribute name="token" rha:description="This is a timeout value
- that specifies how many milliseconds elapse before a
- token loss is declared after not receiving a token. This
- is the time spent detecting a failure of a processor in
- the current configuration. Reforming a new configuration
- takes about 50 milliseconds in addition to this
- timeout." rha:default="5000" rha:sample="5300"/>
- </optional>
- <optional>
- <attribute name="fail_recv_const" />
- </optional>
- <optional>
- <attribute name="seqno_unchanged_const"
- rha:description="Specifies how many rotations of the token without
- any multicast traffic should occur before the merge detection timeout
- is started." rha:default="30" rha:sample="5000"/>
- </optional>
- <optional>
- <attribute name="netmtu"
- rha:description="Specifies the network maximum transmit unit. To set
- this value beyond 1500, the regular frame MTU, requires ethernet
- devices that support large, or also called jumbo, frames. If any
- device in the network does not support large frames, the protocol will
- not operate properly. The hosts must also have their mtu size set
- from 1500 to whatever frame size is specified here."
- rha:default="1500" rha:sample="9174"/>
- </optional>
- <optional>
- <attribute name="window_size"
- rha:description="Specifies the maximum number of messages that may
- be sent on one token rotation. window_size should be no larger then
- 256000 / netmtu to avoid overflow of the kernel receive buffers."
- rha:default="50" rha:sample="300"/>
- </optional>
- <optional>
- <attribute name="max_messages"
- rha:description="Specifies the maximum number of messages that may
- be sent by one processor on receipt of the token. This parameter is
- limited to 256000 / netmtu to prevent overflow of the kernel
- transmit buffers" rha:default="17" rha:sample="25"/>
- </optional>
- <optional>
- <attribute name="token_retransmits_before_loss_const"
- rha:description="This value identifies how many token retransmits
- should be attempted before forming a new configuration. If
- this value is set, retransmit and hold will be automatically
- calculated from retransmits_before_loss and token." rha:default="4"
- rha:sample="5"/>
- </optional>
- <optional>
- <attribute name="miss_count_const"
- rha:description="This constant defines the maximum number of times
- on receipt of a token a message is checked for retransmission before
- retransmission occurs. This parameter is useful to modify for switches
- that delay multicast packets compared to unicast packets.
- The default setting works well for nearly all modern switches."
- rha:default="5" rha:sample="10"/>
- </optional>
- <!-- FIXME: The following description was adapted from the man page.
- It may be tool long for the schema document. Consider cutting text
- after the second sentence and referring the reader to the openais.conf
- man page. -->
- <optional>
- <attribute name="rrp_mode" rha:description="This attribute
- specifies the redundant ring protocol mode. Its value can be
- set to active, passive, or none. Active replication offers
- slightly lower latency from transmit to delivery in faulty
- network environments but with less performance. Passive
- replication may nearly double the speed of the totem protocol
- if the protocol doesn't become cpu bound. The final option is
- none, in which case only one network interface is used to
- operate the totem protocol. If only one interface directive is
- specified, none is automatically chosen. If multiple interface
- directives are specified, only active or passive may be
- chosen." rha:sample="active"/>
- </optional>
- <optional>
- <attribute name="rrp_problem_count_threshold"
- rha:description="This specifies the number of times a problem is detected
- with a link before setting the link faulty. Once a link is set faulty, no
- more data is transmitted upon it. Corosync default is 10, cman default is 3"
- rha:default="3" rha:sample="5"/>
- </optional>
- <optional>
- <attribute name="secauth" rha:description="This attribute specifies
- that HMAC/SHA1 authentication should be used to authenticate all
- messages. It further specifies that all data should be encrypted
- with the sober128 encryption algorithm to protect data from
- eavesdropping. For more information setting this value, refer
- the the openais.conf man page." rha:default="on" rha:sample=""/>
- </optional>
- <optional>
- <attribute name="keyfile" rha:description="" rha:sample=""/>
- </optional>
- <!-- multicast address -->
- <zeroOrMore>
- <element name="interface" rha:description="Defines Totem interface options. corosync.conf(5)" rha:sample="">
- <optional>
- <attribute name="ringnumber" rha:description="Sets the ring interface for the interface for RRP mode. corosync.conf(5)" rha:sample=""/>
- </optional>
- <optional>
- <attribute name="bindnetaddr" rha:description="Specifies the address to which the corosync executive should bind. corosync.conf(5)" rha:sample=""/>
- </optional>
- <optional>
- <attribute name="mcastaddr" rha:description="Defines the multicast address used by corosync for this interface. corosync.conf(5)" rha:sample=""/>
- </optional>
- <optional>
- <attribute name="mcastport" rha:description="Specifies the UDP port number when using multicast. corosync.conf(5)" rha:sample=""/>
- </optional>
- <optional>
- <attribute name="broadcast" rha:description="If set to yes, use broadcast instead of multicast for communication. corosync.conf(5)" rha:sample=""/>
- </optional>
- </element>
- </zeroOrMore>
- </element>
- </optional>
-<!-- end totem block -->
-
-<!-- quorumd block -->
- <optional>
- <element name="quorumd" rha:description="This element and its
- attributes define parameters for the quorum disk daemon,
- quorumd. qdisk(5).">
- <optional>
- <attribute name="interval" rha:description="The frequency of
- read/write cycles, in seconds. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="tko" rha:description="The number of cycles a node
- must miss to be declared dead. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="votes" rha:description="The number of votes the
- quorum daemon advertises to CMAN when it has a high enough
- score. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="min_score" rha:description="The minimum score for a
- node to be considered alive. If omitted or set to 0, the default
- function, floor((n+1)/2), is used, where n is the sum of the
- heuristics scores. The Minimum Score value must never exceed the
- sum of the heuristic scores; otherwise, the quorum disk cannot
- be available. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="device" rha:description="The storage device the
- quorum daemon uses. The device must be the same on all
- nodes. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="label" rha:description="Specifies the quorum disk
- label created by the mkqdisk utility. If this field contains an
- entry, the label overrides the Device field. If this field is
- used, the quorum daemon reads /proc/partitions and checks for
- qdisk signatures on every block device found, comparing the
- label against the specified label. This is useful in configurations
- where the quorum device name differs among nodes. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="cman_label" rha:description="This is the name used by CMAN for the quorum device instead of the device name. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="status_file" rha:description="Debugging file. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="scheduler" rha:description="Scheduler. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="reboot" rha:description="Reboot if our score drops too low. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="priority" rha:description="Scheduler priority. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="tko_up" rha:description="Amount of positive changes before a host is considered online. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="upgrade_wait" rha:description="Amount of cycles wait for conflicts for a bid for master status. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="use_uptime" rha:description="Use /proc/uptime instead of gettimeofday(). qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="stop_cman" rha:description="Stop cman if the quorum disk cannot be found during startup. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="paranoid" rha:description="Reboot if we are running too slowly. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="allow_kill" rha:description="Instruct cman to evict nodes which are not updating the quorum disk. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="max_error_cycles" rha:description="Die after this many cycles which receive I/O errors. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="io_timeout" rha:description="Die if we cannot get a write out to disk after interval*tko. qdisk(5)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="master_wins" rha:description="Enable master-wins mode (two node clusters). qdisk(5)." rha:sample=""/>
- </optional>
- <zeroOrMore>
- <element name="heuristic" rha:description="Defines a heuristic. qdisk(5).">
- <attribute name="program" rha:description="The program used to
- determine if this heuristic is alive. This can be anything that
- can be executed by /bin/sh -c. A return value of 0 indicates
- success; anything else indicates failure." rha:sample=""/>
- <optional>
- <attribute name="score" rha:description="The weight of this
- heuristic. Be careful when determining scores for
- heuristics." rha:default="1" rha:sample=""/>
- </optional>
- <optional>
- <attribute name="interval" rha:description="The frequency (in
- seconds) at which the heuristic is polled. qdisk(5)." rha:default="2"
- rha:sample=""/>
- </optional>
- <optional>
- <attribute name="tko" rha:description="The number of consecutive failures before a heuristic is discounted. qdisk(5)." rha:sample=""/>
- </optional>
- </element>
- </zeroOrMore>
- </element>
- </optional>
-<!-- end quorumd block -->
-
-<!-- fence_daemon block -->
- <optional>
- <element name="fence_daemon" rha:description="Configuration for fenced
- daemon. fenced(8)">
- <optional>
- <attribute name="post_join_delay" rha:description="Number of seconds
- the daemon will wait before fencing any victims after a node joins
- the fence domain. fenced(8)"/>
- </optional>
- <optional>
- <attribute name="post_fail_delay" rha:description="Number of seconds
- the daemon will wait before fencing any victims after a node
- fails. fenced(8)"/>
- </optional>
- <optional>
- <attribute name="override_path" rha:description="Location of a FIFO
- used for communication between fenced and fence_ack_manual.
- fenced(8)"/>
- </optional>
- <optional>
- <attribute name="override_time" rha:description="Number of seconds to
- wait for a manual override after a failed fencing attempt before
- the next attempt. fenced(8)"/>
- </optional>
- <optional>
- <attribute name="clean_start" rha:description="Set to 1 to disable
- startup fencing. fenced(8)"/>
- </optional>
-
- <optional>
- <attribute name="skip_undefined" rha:description="Set to 1 to disable
- startup fencing of nodes with no fence methods defined.
- fenced(8)"/>
- </optional>
- </element>
- </optional>
-<!-- end fence_daemon block -->
-
-<!-- fence_xvmd block -->
- <optional>
- <element name="fence_xvmd" rha:description="Fence_xvm daemon. The
- fence_xvmd fence device is an I/O fencing host that resides
- on dom0 and is used in conjunction with the fence_xvm fencing
- agent. Together, these two programs fence Xen virtual machines
- that are in a cluster. There is a requirement that the parent
- dom0s are also a part of their own CMAN/OpenAIS based cluster,
- and that the dom0 cluster does not share any members with the domU
- cluster. Furthermore, the dom0 cluster is required to have fencing
- if domU recovery is expected to be automatic.">
- <optional>
- <attribute name="debug" rha:description="" >
- <data type="integer"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="port" rha:description="" >
- <data type="integer"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="use_uuid" rha:description="" />
- </optional>
- <optional>
- <attribute name="multicast_address" rha:description="" />
- </optional>
- <optional>
- <attribute name="auth" rha:description="" />
- </optional>
- <optional>
- <attribute name="hash" rha:description="" />
- </optional>
- <optional>
- <attribute name="uri" rha:description="" />
- </optional>
- <optional>
- <attribute name="key_file" rha:description="" />
- </optional>
- <optional>
- <attribute name="multicast_interface" rha:description="" />
- </optional>
- </element>
- </optional>
-<!-- end fence_xvmd block -->
-
-<!-- dlm block -->
- <optional>
- <element name="dlm" rha:description="Configuration for dlm and
- dlm_controld daemon. dlm_controld(8)">
-
- <optional>
- <attribute name="log_debug" rha:description="Set to 1 to enable
- dlm kernel debugging messages. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="timewarn" rha:description="Number of centiseconds
- a lock is blocked before notifying dlm_controld deadlock code.
- dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="protocol" rha:description="The dlm lowcomms protocol.
- dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="enable_fencing" rha:description="Fencing recovery
- dependency. dlm_controld(8)" />
- </optional>
-
- <optional>
- <attribute name="enable_quorum" rha:description="Quorum recovery
- dependency. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="enable_deadlk" rha:description="Deadlock detection
- capability. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="enable_plock" rha:description="Cluster fs posix
- lock capability. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="plock_debug" rha:description="Set to 1 to enable
- posix lock debugging. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="plock_rate_limit" rha:description="Limit the rate of
- plock operations. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="plock_ownership" rha:description="Set to 1/0 to
- enable/disable plock ownership. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="drop_resources_time" rha:description="Plock ownership
- drop resources time. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="drop_resources_count" rha:description="Plock ownership
- drop resources count. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="drop_resources_age" rha:description="Plock ownership
- drop resources age. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <zeroOrMore>
- <element name="lockspace" rha:description="Individual lockspace
- configuration. dlm_controld(8)">
- <attribute name="name" rha:description="Name of the lockspace.
- dlm_controld(8)"/>
-
- <optional>
- <attribute name="nodir" rha:description="Set to 1 to disable the
- internal resource directory. dlm_controld(8)"/>
- </optional>
-
- <optional>
- <zeroOrMore>
- <element name="master" rha:description="Defines a master node.
- dlm_controld(8)">
-
- <attribute name="name" rha:description="The name of a node that
- should be master resources/locks. dlm_controld(8)"/>
-
- <optional>
- <attribute name="weight" rha:description="The proportion of
- resources this node should master. dlm_controld(8)"/>
- </optional>
- </element>
- </zeroOrMore>
- </optional>
-
- </element>
- </zeroOrMore>
- </optional>
- </element>
- </optional>
-<!-- end dlm block -->
-
-<!-- gfs_controld block -->
- <optional>
- <element name="gfs_controld" rha:description="Configuration for
- gfs_controld daemon. gfs_controld(8)">
-
- <optional>
- <attribute name="enable_withdraw" rha:description="Set to 1/0 to
- enable/disable a response to a withdraw. gfs_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="enable_plock" rha:description="Cluster fs posix
- lock capability. gfs_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="plock_debug" rha:description="Set to 1 to enable
- posix lock debugging. gfs_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="plock_rate_limit" rha:description="Limit the rate of
- plock operations. gfs_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="plock_ownership" rha:description="Set to 1/0 to
- enable/disable plock ownership. gfs_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="drop_resources_time" rha:description="Plock ownership
- drop resources time. gfs_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="drop_resources_count" rha:description="Plock ownership
- drop resources count. gfs_controld(8)"/>
- </optional>
-
- <optional>
- <attribute name="drop_resources_age" rha:description="Plock ownership
- drop resources age. gfs_controld(8)"/>
- </optional>
-
- </element>
- </optional>
-<!-- end gfs_controld block -->
-
-<!-- group block -->
- <optional>
- <element name="group" rha:description="Defines groupd configuration.
- groupd(8)">
- <optional>
- <attribute name="groupd_compat" rha:description="Enable compatibility with
- cluster2 nodes. groupd(8)"/>
- </optional>
- </element>
- </optional>
-<!-- end group block -->
-
-<!-- logging block -->
- <optional>
- <element name="logging" rha:description="Defines global logging
- configuration, and contains daemon-specific configuration.
- cluster.conf(5)">
-
- <optional>
- <attribute name="to_syslog" rha:description="Set to yes/no to
- enable/disable messages to syslog. cluster.conf(5)"/>
- </optional>
-
- <optional>
- <attribute name="to_logfile" rha:description="Set to yes/no to
- enable/disable messages to log file. cluster.conf(5)"/>
- </optional>
-
- <optional>
- <attribute name="syslog_facility" rha:description="The facility
- used for syslog messages. cluster.conf(5)"/>
- </optional>
-
- <optional>
- <attribute name="syslog_priority" rha:description="Messages at this
- level and higher are sent to syslog. cluster.conf(5)"/>
- </optional>
-
- <optional>
- <attribute name="logfile_priority" rha:description="Messages at this
- level and higher are written to log file. cluster.conf(5)"/>
- </optional>
-
- <optional>
- <attribute name="logfile" rha:description="The log file path name.
- cluster.conf(5)"/>
- </optional>
-
- <optional>
- <attribute name="debug" rha:description="Set to on to enable debugging
- messages in log file. cluster.conf(5)"/>
- </optional>
-
- <zeroOrMore>
- <element name="logging_daemon" rha:description="Defines
- daemon-specific logging configuration. cluster.conf(5)">
-
- <attribute name="name" rha:description="The daemon name.
- cluster.conf(5)"/>
-
- <optional>
- <attribute name="subsys" rha:description="A corosync subsystem name.
- cluster.conf(5)"/>
- </optional>
-
- <optional>
- <attribute name="to_syslog" rha:description="Same as global."/>
- </optional>
- <optional>
- <attribute name="to_logfile" rha:description="Same as global."/>
- </optional>
- <optional>
- <attribute name="syslog_facility" rha:description="Same as global."/>
- </optional>
- <optional>
- <attribute name="syslog_priority" rha:description="Same as global."/>
- </optional>
- <optional>
- <attribute name="logfile_priority" rha:description="Same as global."/>
- </optional>
- <optional>
- <attribute name="logfile" rha:description="Same as global."/>
- </optional>
- <optional>
- <attribute name="debug" rha:description="Same as global."/>
- </optional>
-
- </element>
- </zeroOrMore>
-
- </element>
- </optional>
-<!-- end logging block -->
-
-<!-- clusternodes block -->
- <element name="clusternodes" rha:description="Contains all cluster
- node definitions. cluster.conf(5)">
-
- <zeroOrMore>
- <element name="clusternode" rha:description="Defines cluster node
- properties, and contains other node specific configuration.
- cluster.conf(5)">
-
- <attribute name="name" rha:description="The hostname or IP address
- of the node. cluster.conf(5)"/>
-
- <attribute name="nodeid" rha:description="A unique integer to use
- as a node identifier. cluster.conf(5)">
- <data type="positiveInteger"/>
- </attribute>
-
- <optional>
- <attribute name="votes" rha:description="The number of votes the
- node contributes to quorum. cman(5)">
- <data type="positiveInteger"/>
- </attribute>
- </optional>
-
- <optional>
- <attribute name="weight" rha:description="The dlm locking weight.
- dlm_controld(8)"/>
- </optional>
-
- <interleave>
- <optional>
- <ref name="ALTNAME"/>
- </optional>
- <optional>
- <ref name="FENCE"/>
- </optional>
- <optional>
- <ref name="UNFENCE"/>
- </optional>
- </interleave>
-
- </element>
- </zeroOrMore>
- </element>
-<!-- end clusternode block -->
-
-<!-- fencedevices block -->
- <optional>
- <element name="fencedevices" rha:description="Contains all fence
- device definitions. fenced(8)">
- <zeroOrMore>
- <element name="fencedevice" rha:description="Defines fence device
- properties. fenced(8)">
-
- <attribute name="name" rha:description="A name that is used to
- reference this fence device from clusternode fence section.
- fenced(8)">
- <data type="ID"/>
- </attribute>
-
- <attribute name="agent" rha:description="The fence agent to be
- used. fenced(8)"/>
-
- <ref name="FENCEDEVICEOPTIONS"/>
-
- </element>
- </zeroOrMore>
- </element>
- </optional>
-<!-- end fencedevices block -->
-
-<!-- rm block -->
- <optional>
- <element name="rm" rha:description="This element and its attributes
- define resources (for example an IP address) required to create HA
- cluster services, the HA cluster services themselves, and failover
- domains for the HA cluster services.">
- <optional>
- <!-- FIXME: The following text needs clarifying. What is meant by
- "...for all levels less than the selected."? -->
- <attribute name="log_level" rha:description="An integer 0-7,
- inclusive, for all levels less than the selected.
- 0, system is unusable, emergency;
- 1, action must be taken immediately;
- 2, critical conditions;
- 3, error conditions;
- 4, warning conditions;
- 5, normal but significant condition;
- 6, informational;
- 7, debug-level messages." rha:sample="6">
- <data type="integer"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="status_child_max" rha:description="Maximum number of status child threads." rha:sample="">
- <data type="integer"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="status_poll_interval" rha:description="Scan the resource tree every X seconds for resources which need to be checked."
- rha:sample="">
- <data type="integer"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="transition_throttling" rha:description="During transitions, keep the event processor alive for this many seconds."
- rha:sample="">
- <data type="integer"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="central_processing" rha:description="Enable central processing mode (requires cluster-wide shut down and restart of rgmanager.)."
- rha:sample="">
- <data type="integer"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="log_facility" rha:description="The facility is one
- of the following keywords: auth, authpriv, cron, daemon, kern,
- lpr, mail, news, syslog, user, uucp and local0 through local7"/>
- </optional>
- <optional>
- <attribute name="disabled" rha:description="Disables rgmanager entirely if set to 1. Do not set unless you really mean it." rha:sample="">
- <data type="integer"/>
- </attribute>
- </optional>
- <interleave>
- <optional>
- <element name="failoverdomains" rha:description="Failover domain definitions.">
- <zeroOrMore>
- <element name="failoverdomain" rha:description="Specifies
- properties of a specific failover domain">
- <attribute name="name" rha:description="The name of the failover
- domain." rha:sample="foo"/>
- <optional>
- <attribute name="ordered" rha:description="Set value to 1 if
- the failover domain is ordered; set value to 0 if
- unordered." rha:default="0" rha:sample="1"/>
- </optional>
- <optional>
- <attribute name="restricted" rha:description="Set value to 1 if
- the failover domain is restricted; set value to 0 if
- unrestricted." rha:default="0" rha:sample="1"/>
- </optional>
- <optional>
- <attribute name="nofailback" rha:description="Do not move service to a more preferred node if it is currently running." rha:sample=""/>
- </optional>
- <zeroOrMore>
- <element name="failoverdomainnode" rha:description="A node in
- a failover domain">
- <optional>
- <attribute name="priority" rha:description="A number
- specifying the priority; lower numbers having higher
- priority"
- rha:sample="1"/>
- </optional>
- <attribute name="name" rha:description="Name of the node."
- rha:sample="member2"/>
- </element>
- </zeroOrMore>
- </element>
- </zeroOrMore>
- </element>
- </optional> <!-- End of failoverdomains block -->
- <optional>
- <element name="events" rha:description="Event definitions (central_processing only).">
- <zeroOrMore>
- <element name="event" rha:description="Defines an event.">
- <attribute name="name" rha:description="Symbolic name for an event." rha:sample=""/>
- <optional>
- <text/>
- </optional>
- <optional>
- <attribute name="file" rha:description="Path to S/Lang script to execute." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="priority" rha:description="Order (1..99) of event." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="class" rha:description="Event class (service, node)." rha:sample=""/>
- </optional>
- <!-- Service event class attributes -->
- <optional>
- <attribute name="service" rha:description="(Service) The service name (service:foo) must match the specified value in order for the event script to be run." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="service_state" rha:description="(Service) The service's state must match the specified value in order for the script to be run (started, stopped, disabled, failed)." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="service_owner" rha:description="(Service) The service owner must match the specified value in order for the event script to be run." rha:sample=""/>
- </optional>
- <!-- Node event -->
- <optional>
- <attribute name="node" rha:description="(Node) The node name must match the specified value in order for the script to be run." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="node_id" rha:description="(Node) The node ID must match the specified value in order for the script to be run." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="node_state" rha:description="(Node) The node state must match the specified value (0 or 1) in order for the script to be run." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="node_clean" rha:description="(Node) The node must have been fenced in order for the script to be run." rha:sample=""/>
- </optional>
- <optional>
- <attribute name="node_local" rha:description="(Node) This script may only run on the current central processing node." rha:sample=""/>
- </optional>
- <!-- Config event attributes -->
- <!-- NOT USED -->
- </element>
- </zeroOrMore>
- </element>
- </optional> <!-- End of events block -->
- <optional>
- <element name="resources" rha:description="Defines global resources which may be referenced in services. You may redefine actions for resources here, but child resource definitions are ignored in this section.">
- <zeroOrMore>
- <ref name="CHILDREN"/>
- </zeroOrMore>
- </element>
- </optional>
- <optional>
- <element name="resource-defaults" rha:description="This section allows the administrator to change defaults for resource agents. Overriding parameters which must be unique is not allowed. Overriding a value which, by default, inherits a value from a parent resource will disable inheritance for that resource type.">
- <zeroOrMore>
- <ref name="CHILDREN"/>
- </zeroOrMore>
- </element>
- </optional>
- <zeroOrMore>
- <ref name="SERVICE"/>
- </zeroOrMore>
- <zeroOrMore>
- <ref name="VM"/>
- </zeroOrMore>
- </interleave>
- </element>
- </optional>
-
-<!-- clvmd block -->
- <optional>
- <element name="clvmd" rha:description="The clvmd element contains
- attributes that define parameters for the cluster LVM daemon.">
- <optional>
- <attribute name="interface" rha:description="The interface attribute
- tells clvmd which cluster interface it should use for internode
- communications and locking. Valid values for this depend on
- how the daemon is configured at compile-time, but are typically
- cman, corosync or openais." rha:sample="cman"/>
- </optional>
- </element>
- </optional>
-
- </interleave>
-
-
-</element> <!-- cluster end -->
-</start>
-
-<!-- begin mcast definitions -->
-
- <define name="MULTICASTOPTS">
- <optional>
- <attribute name="addr" rha:description="A multicast address specified
- by a user. If you do specify a multicast address, you should
- use the 239.192.x.x series that cman uses. Otherwise, using a
- multicast address outside that range may cause unpredictable
- results. For example, using 224.0.0.x (All hosts on the network)
- may not be routed correctly, or even routed at all by some
- hardware." rha:sample="239.192.0.1"/>
- </optional>
- <optional>
- <attribute name="ttl" rha:description="Define the TTL (time to live) of
- a multicast packets. Useful only if nodes are on different subnets and
- a multicast router is available in between." rha:default="1"
- rha:sample="24"/>
- </optional>
- <optional>
- <attribute name="port">
- <data type="nonNegativeInteger"/>
- </attribute>
- </optional>
- </define>
-
-<!-- end mcast definitions -->
-
-<!-- begin node altname definitions -->
-
- <define name="ALTNAME">
- <element name="altname" rha:description="Defines a second network
- interface to use for corosync redundant ring mode. cman(5)">
-
- <attribute name="name" rha:description="A second hostname or IP
- address of the node. cman(5)"/>
-
- <optional>
- <attribute name="port" rha:description="The network port to use
- on the second interface. cman(5)"/>
- </optional>
-
- <optional>
- <attribute name="mcast" rha:description="The multicast address
- to use on the second interface. cman(5)"/>
- </optional>
-
- <optional>
- <attribute name="ttl" rha:description="The multicast TTL
- to use on the second interface. cman(5)"/>
- </optional>
- </element>
- </define>
-
-<!-- end node altname definitions -->
-
-<!-- begin node fence definitions -->
-
- <define name="FENCE">
- <element name="fence" rha:description="Contains methods for fencing
- the node in different ways. fenced(8)">
-
- <zeroOrMore>
-
- <element name="method" rha:description="Contains one or more devices
- for fencing the node a single way. fenced(8)">
-
- <attribute name="name" rha:description="A name used to distinguish
- multiple methods from each other. fenced(8)"/>
-
- <zeroOrMore>
- <ref name="DEVICE"/>
- </zeroOrMore>
-
- </element>
-
- </zeroOrMore>
- </element>
- </define>
-
- <define name="UNFENCE">
- <element name="unfence" rha:description="Contains devices for unfencing
- the node. fence_node(8)">
- <zeroOrMore>
- <ref name="DEVICE"/>
- </zeroOrMore>
- </element>
- </define>
-
- <define name="DEVICE">
- <element name="device" rha:description="Defines the properties of a
- device used for fencing or unfencing a node. fenced(8)">
-
- <attribute name="name" rha:description="The name of a fencedevice
- defined in the fencedevices section. fenced(8)">
- <data type="IDREF"/>
- </attribute>
-
- <ref name="FENCEDEVICEOPTIONS"/>
-
- </element>
- </define>
-<!-- end node fence definitions -->
diff --git a/config/tools/xml/cluster.rng.in.tail b/config/tools/xml/cluster.rng.in.tail
deleted file mode 100644
index d4e2278..0000000
--- a/config/tools/xml/cluster.rng.in.tail
+++ /dev/null
@@ -1 +0,0 @@
-</grammar>
diff --git a/configure b/configure
deleted file mode 100755
index 2e521a0..0000000
--- a/configure
+++ /dev/null
@@ -1,688 +0,0 @@
-#!/usr/bin/perl -w
-
-use warnings;
-use Getopt::Long;
-use POSIX qw(uname);
-use Cwd 'abs_path';
-use File::Basename;
-use File::Spec;
-
-print "\nConfiguring Makefiles for your system...\n";
-
-# Set a bunch of variables
-
-my @invoke = @ARGV;
-
-my $ret = 0;
-
-# this should be only the major version without the extra version
-# eg. only the first 3 digits
-my $required_kernelversion = '2.6.31';
-
-my %options = (
- help => \$help,
- cc => \$cc,
- debug => \$debug,
- cflags => \$cflags,
- extracflags => \$extracflags,
- enable_paranoia_cflags => \$enable_paranoia_cflags,
- ldflags => \$ldflags,
- extraldflags => \$extraldflags,
- objdir => \$objdir,
- kernel_src => \$kernel_src,
- incdir => \$incdir,
- libdir => \$libdir,
- ccsincdir => \$ccsincdir,
- ccslibdir => \$ccslibdir,
- cmanincdir => \$cmanincdir,
- cmanlibdir => \$cmanlibdir,
- dlmincdir => \$dlmincdir,
- dlmlibdir => \$dlmlibdir,
- dlmcontrolincdir => \$dlmcontrolincdir,
- dlmcontrollibdir => \$dlmcontrollibdir,
- fenceincdir => \$fenceincdir,
- fencelibdir => \$fencelibdir,
- fencedincdir => \$fencedincdir,
- fencedlibdir => \$fencedlibdir,
- logtincdir => \$logtincdir,
- logtlibdir => \$logtlibdir,
- ncursesincdir => \$ncursesincdir,
- ncurseslibdir => \$ncurseslibdir,
- slangincdir => \$slangincdir,
- slanglibdir => \$slanglibdir,
- corosyncincdir => \$corosyncincdir,
- corosynclibdir => \$corosynclibdir,
- openaisincdir => \$openaisincdir,
- openaislibdir => \$openaislibdir,
- corosyncbin => \$corosyncbin,
- zlibincdir => \$zlibincdir,
- zliblibdir => \$zliblibdir,
- ldapincdir => \$ldapincdir,
- ldaplibdir => \$ldaplibdir,
- libexecdir => \$libexecdir,
- mandir => \$mandir,
- prefix => \$prefix,
- sbindir => \$sbindir,
- initddir => \$initddir,
- sharedir => \$sharedir,
- docdir => \$docdir,
- logdir => \$logdir,
- logrotatedir => \$logrotatedir,
- syslogfacility => \$syslogfacility,
- sysloglevel => \$sysloglevel,
- confdir => \$confdir,
- conffile => \$conffile,
- enable_contrib => \$enable_contrib,
- disable_dbus => \$disable_dbus,
- somajor => \$somajor,
- sominor => \$sominor,
- release_version => \$release_version,
- without_common => \$without_common,
- without_config => \$without_config,
- without_cman => \$without_cman,
- without_dlm => \$without_dlm,
- without_group => \$without_group,
- without_fence => \$without_fence,
- without_gfs2 => \$without_gfs2,
- without_rgmanager => \$without_rgmanager,
- without_bindings => \$without_bindings,
- disable_kernel_check => \$disable_kernel_check,
-);
-
-my $err = &GetOptions (\%options,
- 'help',
- 'cc=s',
- 'debug',
- 'cflags=s',
- 'extracflags=s',
- 'enable_paranoia_cflags',
- 'ldflags=s',
- 'extraldflags=s',
- 'objdir=s',
- 'kernel_src=s',
- 'incdir=s',
- 'libdir=s',
- 'ccsincdir=s',
- 'ccslibdir=s',
- 'cmanincdir=s',
- 'cmanlibdir=s',
- 'dlmincdir=s',
- 'dlmlibdir=s',
- 'dlmcontrolincdir=s',
- 'dlmcontrollibdir=s',
- 'fenceincdir=s',
- 'fencelibdir=s',
- 'fencedincdir=s',
- 'fencedlibdir=s',
- 'logtincdir=s',
- 'logtlibdir=s',
- 'ncursesincdir=s',
- 'ncurseslibdir=s',
- 'slangincdir=s',
- 'slanglibdir=s',
- 'corosyncincdir=s',
- 'corosynclibdir=s',
- 'openaisincdir=s',
- 'openaislibdir=s',
- 'corosyncbin=s',
- 'zlibincdir=s',
- 'zliblibdir=s',
- 'ldapincdir=s',
- 'ldaplibdir=s',
- 'libexecdir=s',
- 'mandir=s',
- 'prefix=s',
- 'sbindir=s',
- 'initddir=s',
- 'sharedir=s',
- 'docdir=s',
- 'logdir=s',
- 'logrotatedir=s',
- 'syslogfacility=s',
- 'sysloglevel=s',
- 'confdir=s',
- 'conffile=s',
- 'somajor=s',
- 'sominor=s',
- 'release_version=s',
- 'enable_contrib',
- 'disable_dbus',
- 'without_common',
- 'without_config',
- 'without_cman',
- 'without_dlm',
- 'without_group',
- 'without_fence',
- 'without_gfs2',
- 'without_rgmanager',
- 'without_bindings',
- 'disable_kernel_check');
-
-if(!$err) {
- $ret = 1;
- print "*** ERROR: Invalid option detected ***\n";
-}
-
-# Check for the --help flag
-if ($help || !$err) {
- $_ = $0;
- s/.*\.\/(.*)/$1/;
- print "Usage: $_ [flags]\n";
- print "--help\t\tPrints this usage information\n\n";
- print "install flags:\n";
- print "--prefix=\tthe base directory to install into. (Default: /usr)\n";
- print "--sbindir=\tthe base directory for system binaries. (Default: {prefix}/sbin)\n";
- print "--initddir=\tthe base directory for init.d scripts. (Default: /etc/init.d)\n";
- print "--libdir=\tthe base directory for libraries. (Default: {prefix}/lib)\n";
- print "--libexecdir=\tthe base directory for executable components. (Default: {prefix}/libexec)\n";
- print "--sharedir=\tthe base directory for misc cluster files. (Default: {prefix}/share/cluster)\n";
- print "--docdir=\tthe base directory for misc cluster documentation files. (Default: {prefix}/share/doc/cluster)\n";
- print "--logdir=\tthe base directory for cluster logging files. (Default: /var/log/cluster/)\n";
- print "--logrotatedir=\tthe base directory for logrorate.d files. (Default: /etc/logrotate.d/)\n";
- print "--syslogfacility=\tset the default syslog facility. (Default: LOG_LOCAL4)\n";
- print "--sysloglevel=\tset the default syslog level. (Default: LOG_INFO)\n";
- print "--confdir=\tthe cluster config directory. (Default: /etc/cluster)\n";
- print "--conffile=\tthe cluster config file. (Default: cluster.conf)\n";
- print "--mandir=\tthe base directory for man pages. (Default: {prefix}/share/man)\n";
- print "\nbuild flags:\n";
- print "--cc=\t\tcompiler to use. (Default: gcc)\n";
- print "--debug\t\tEnable debugging build. Changes default optimization CFLAGS to -O0 -DDEBUG -ggdb3\n";
- print "--cflags=\toverride default CFLAGS settings.\n";
- print "--extracflags=\tadd extra compiler options to default CFLAGS setting. (Default: none)\n";
- print "--enable_paranoia_cflags=\tadd paranoia compiler options to default CFLAGS setting. (Default: -Werror)\n";
- print "--ldflags=\toverride default LDFLAGS settings. (Default: none)\n";
- print "--extraldflags=\tadd extra linking options to default LDFLAGS settings. (Default: none)\n";
- print "--objdir=\tspecify directory where to store object files. (Defaults: current build dir)\n";
- print "--kernel_src=\tthe directory containing the kernel source you wish to\n\t\tcompile against. (Default: /lib/modules/`uname -r`/source\n\t\tif available or \$kernel_build as fallback)\n";
- print "--incdir=\tthe base directory for include files. (Default: {prefix}/include)\n";
- print "--ccsincdir=\tthe base directory for ccs include files. (Default: ./config/libs/libccsconfdb)\n";
- print "--ccslibdir=\tthe base directory for ccs libraries. (Default: ./config/libs/libccsconfdb)\n";
- print "--cmanincdir=\tthe base directory for cman include files. (Default: ./cman/lib)\n";
- print "--cmanlibdir=\tthe base directory for cman libraries. (Default: ./cman/lib)\n";
- print "--dlmincdir=\tthe base directory for dlm include files. (Default: ./dlm/libdlm)\n";
- print "--dlmlibdir=\tthe base directory for dlm libraries. (Default: ./dlm/libdlm)\n";
- print "--dlmcontrolincdir=\tthe base directory for dlmcontrol include files. (Default: ./dlm/libdlmcontrol)\n";
- print "--dlmcontrollibdir=\tthe base directory for dlmcontrol libraries. (Default: ./dlm/libdlmcontrol)\n";
- print "--fenceincdir=\tthe base directory for fence include files. (Default: ./fence/libfence)\n";
- print "--fencelibdir=\tthe base directory for fence libraries. (Default: ./fence/libfence)\n";
- print "--fencedincdir=\tthe base directory for fence include files. (Default: ./fence/libfenced)\n";
- print "--fencedlibdir=\tthe base directory for fence libraries. (Default: ./fence/libfenced)\n";
- print "--logtincdir=\tthe base directory for logthread include files. (Default: ./common/liblogthread)\n";
- print "--logtlibdir=\tthe base directory for logthread libraries. (Default: ./common/liblogthread)\n";
- print "--ncursesincdir=\tthe base directory for ncurses include files. (Default: {incdir})\n";
- print "--ncurseslibdir=\tthe base directory for ncurses libraries. (Default: {libdir})\n";
- print "--slangincdir=\tthe base directory for S-Lang include files. (Default: {incdir})\n";
- print "--slanglibdir=\tthe base directory for S-Lang libraries. (Default: {libdir})\n";
- print "--corosyncincdir=\tthe base directory for corosync include files. (Default: {incdir})\n";
- print "--corosynclibdir=\tthe base directory for corosync libraries. (Default: {libdir}/corosync)\n";
- print "--openaisincdir=\tthe base directory for openais include files. (Default: {incdir})\n";
- print "--openaislibdir=\tthe base directory for openais libraries. (Default: {libdir}/openais)\n";
- print "--corosyncbin=\tlocation of corosync executable file. (Default: /usr/sbin/corosync)\n";
- print "--zlibincdir=\tthe base directory for libz include files. (Default: {incdir})\n";
- print "--zliblibdir=\tthe base directory for libz libraries. (Default: {libdir})\n";
- print "--ldapincdir=\tthe base directory for ldap include files. (Default: {incdir})\n";
- print "--ldaplibdir=\tthe base directory for ldap libraries. (Default: {libdir})\n";
- print "--enable_contrib\tEnable build of community contributed code/tools. (Default: no)\n";
- print "--disable_dbus\tDisable built-in support for dbus notifications. (Default: no)\n";
- print "--without_common\tDisable common building (Default: enabled)\n";
- print "--without_config\tDisable config building (Default: enabled)\n";
- print "--without_cman\tDisable cman building (Default: enabled)\n";
- print "--without_dlm\tDisable dlm building (Default: enabled)\n";
- print "--without_group\tDisable group building (Default: enabled)\n";
- print "--without_fence\tDisable fence building (Default: enabled)\n";
- print "--without_gfs2\tDisable gfs2 building (Default: enabled)\n";
- print "--without_rgmanager\tDisable rgmanager building (Default: enabled)\n";
- print "--without_bindings\tDisable perl/python bindings building (Default: enabled)\n";
- print "--disable_kernel_check\tDisable kernel version check (Default: enabled)\n";
- exit $ret;
-}
-
-sub kernel_version {
- my $makefile_path = shift;
- my $required_version = shift;
-
- print "\nChecking kernel:\n";
-
- # add autoconf to the path
- $makefile_path .= '/Makefile';
- my @version = split /\./, $required_version;
- if ( -f $makefile_path ) {
- # open the toplevel Makefile to feth VERSION, PATCHLEVEL and SUBLEVEL
- open MAKEFILE, '<', $makefile_path;
- while (<MAKEFILE>) {
- $build_version = $1 if /^VERSION = (\d+)/;
- $build_patchlevel = $1 if /^PATCHLEVEL = (\d+)/;
- $build_sublevel = $1 if /^SUBLEVEL = (\d+)/;
- last if (defined $build_version && defined $build_patchlevel && defined $build_sublevel);
- }
- close MAKEFILE;
- # Warn and continue if kernel version was not found
- if (!$build_version || !$build_patchlevel || !$build_sublevel) {
- print " WARNING: Could not determine kernel version.\n";
- print " Build might fail!\n";
- return 1;
- }
- # checking VERSION, PATCHLEVEL and SUBLEVEL for the supplied kernel
- if ($build_version >= $version[0] &&
- $build_patchlevel >= $version[1] &&
- $build_sublevel >= $version[2]) {
- print " Current kernel version appears to be OK\n";
- return 1;
- } else {
- print " Current kernel version: ",$build_version, "." , $build_patchlevel, ".", $build_sublevel, "\n Minimum kernel version: ",$required_version,"\n";
- print " FAILED!\n";
- return 0;
- }
- } else {
- print " Unable to find ($makefile_path)!\n";
- print " Make sure that:\n - the above path is correct\n";
- print " - your kernel is properly configured and prepared.\n";
- print " - kernel_build and kernel_src options to configure are set properly.\n";
- return 0;
- }
-}
-
-sub symlinks {
- my $dir = shift;
- my $pattern = shift;
- @args = "find $dir -type f -name $pattern";
- open (IFILE, "@args |");
- while (<IFILE>) {
- chomp;
- s|\./||g;
- s|.*make\/defines.mk||g;
- $dirname = dirname($_);
- $filename = basename($_);
- system("mkdir -p $objdir/$dirname");
- symlink("${cdir}/$_","$objdir/$dirname/$filename");
- }
- close IFILE;
- return 0;
-}
-
-$pwd = `pwd`;
-chomp($pwd);
-
-if (!$cc) {
- $cc="gcc";
-}
-if (!$cflags) {
- $cflags="";
- $cflags="${cflags} -Wall -Wformat=2 -Wshadow -Wmissing-prototypes";
- $cflags="${cflags} -Wstrict-prototypes -Wdeclaration-after-statement";
- $cflags="${cflags} -Wpointer-arith -Wwrite-strings -Wcast-align";
- $cflags="${cflags} -Wbad-function-cast -Wmissing-format-attribute";
- $cflags="${cflags} -Wformat-security -Wformat-nonliteral -Wno-long-long";
- $cflags="${cflags} -Wno-strict-aliasing -Wmissing-declarations";
- if (!$debug) {
- $cflags="${cflags} -O2";
- } else {
- $cflags="${cflags} -O0 -DDEBUG";
- }
- $cflags="${cflags} -ggdb3 -MMD";
-}
-if ($extracflags) {
- $cflags="${cflags} ${extracflags}";
-}
-if ($enable_paranoia_cflags) {
- $cflags="-Werror ${cflags}";
-}
-if (!$ldflags) {
- $ldflags="";
-}
-if ($extraldflags) {
- $ldflags="${ldflags} ${extraldflags}";
-}
-if (!$prefix) {
- $prefix="/usr";
-}
-
-print "\nChecking tree: ";
-if (!$objdir) {
- $objdir="${pwd}";
-}
-$objdir = abs_path( $objdir );
-$cdir = dirname ( abs_path( $0 ) );
-unless ("$cdir" eq "$objdir") {
- chdir "$cdir";
-}
-
-if (! -d "$objdir/make") {
- print "setting up $objdir\n";
- mkdir "$objdir";
- symlinks(".","Makefile");
- symlinks(".","*.mk");
- symlinks("bindings","*.bindings");
- symlinks("bindings","*.pl");
- symlinks("bindings","*.xs");
- symlinks("bindings","*.PL");
- symlinks("bindings","MANIFEST");
- symlinks("bindings","typemap");
-} else {
- print "nothing to do\n";
-}
-
-my @un = POSIX::uname();
-if (!$kernel_build) {
- if (-d "/lib/modules/$un[2]/build") {
- $kernel_build="/lib/modules/$un[2]/build";
- } else {
- $kernel_build="/usr/src/linux";
- }
-}
-if (!$kernel_src) {
- if (-d "/lib/modules/$un[2]/source") {
- $kernel_src="/lib/modules/$un[2]/source";
- } else {
- $kernel_src=$kernel_build;
- }
-}
-if (not $disable_kernel_check and !kernel_version($kernel_src,$required_kernelversion)) {
- exit 1;
-}
-if (!$incdir) {
- $incdir="${prefix}/include";
-}
-if (!$libdir) {
- $libdir="${prefix}/lib";
-}
-if (!$ccsincdir) {
- $ccsincdir="${cdir}/config/libs/libccsconfdb";
-}
-if (!$ccslibdir) {
- $ccslibdir="${objdir}/config/libs/libccsconfdb";
-}
-if (!$cmanincdir) {
- $cmanincdir="${cdir}/cman/lib";
-}
-if (!$cmanlibdir) {
- $cmanlibdir="${objdir}/cman/lib";
-}
-if (!$dlmincdir) {
- $dlmincdir="${cdir}/dlm/libdlm";
-}
-if (!$dlmlibdir) {
- $dlmlibdir="${objdir}/dlm/libdlm";
-}
-if (!$dlmcontrolincdir) {
- $dlmcontrolincdir="${cdir}/dlm/libdlmcontrol";
-}
-if (!$dlmcontrollibdir) {
- $dlmcontrollibdir="${objdir}/dlm/libdlmcontrol";
-}
-if (!$fenceincdir) {
- $fenceincdir="${cdir}/fence/libfence";
-}
-if (!$fencelibdir) {
- $fencelibdir="${objdir}/fence/libfence";
-}
-if (!$fencedincdir) {
- $fencedincdir="${cdir}/fence/libfenced";
-}
-if (!$fencedlibdir) {
- $fencedlibdir="${objdir}/fence/libfenced";
-}
-if (!$logtincdir) {
- $logtincdir="${cdir}/common/liblogthread";
-}
-if (!$logtlibdir) {
- $logtlibdir="${objdir}/common/liblogthread";
-}
-if (!$ncursesincdir) {
- $ncursesincdir="${incdir}";
-}
-if (!$ncurseslibdir) {
- $ncurseslibdir="${libdir}";
-}
-if (!$slangincdir) {
- $slangincdir="${incdir}";
- if (! -f "$slangincdir/slang.h") {
- $slangincdir="${incdir}/slang";
- }
-}
-if (!$slanglibdir) {
- $slanglibdir="${libdir}";
-}
-if (!$corosyncincdir) {
- $corosyncincdir="${incdir}";
-}
-if (!$corosynclibdir) {
- $corosynclibdir="${libdir}/corosync";
-}
-if (!$openaisincdir) {
- $openaisincdir="${incdir}";
-}
-if (!$openaislibdir) {
- $openaislibdir="${libdir}/openais";
-}
-if (!$corosyncbin) {
- $corosyncbin="/usr/sbin/corosync";
-}
-if (!$zlibincdir) {
- $zlibincdir="${incdir}";
-}
-if (!$zliblibdir) {
- $zliblibdir="${libdir}";
-}
-if (!$ldapincdir) {
- $ldapincdir="${incdir}";
-}
-if (!$ldaplibdir) {
- $ldaplibdir="${libdir}";
-}
-if (!$libexecdir) {
- $libexecdir="${prefix}/libexec";
-}
-if (!$mandir) {
- $mandir="${prefix}/share/man";
-}
-if (!$sbindir) {
- $sbindir="${prefix}/sbin";
-}
-$relativesbin=File::Spec->abs2rel("/sbin", $sbindir);
-if (!$initddir) {
- $initddir="/etc/init.d";
-}
-if (!$sharedir) {
- $sharedir="${prefix}/share/cluster";
-}
-if (!$docdir) {
- $docdir="${prefix}/share/doc/cluster";
-}
-if (!$logdir) {
- $logdir="/var/log/cluster";
-}
-if (!$logrotatedir) {
- $logrotatedir="/etc/logrotate.d";
-}
-if (!$syslogfacility) {
- $syslogfacility="LOG_LOCAL4";
-}
-if (!$sysloglevel) {
- $sysloglevel="LOG_INFO";
-}
-if (!$confdir) {
- $confdir="/etc/cluster";
-}
-if (!$conffile) {
- $conffile="cluster.conf";
-}
-if (!$enable_contrib) {
- $enable_contrib="";
-}
-if (!$disable_dbus) {
- $disable_dbus="";
-}
-if (!$without_common) {
- $without_common="";
-}
-if (!$without_config) {
- $without_config="";
-}
-if (!$without_cman) {
- $without_cman="";
-}
-if (!$without_dlm) {
- $without_dlm="";
-}
-if (!$without_group) {
- $without_group="";
-}
-if (!$without_fence) {
- $without_fence="";
-}
-if (!$without_gfs2) {
- $without_gfs2="";
-}
-if (!$without_rgmanager) {
- $without_rgmanager="";
-}
-if (!$without_bindings) {
- $without_bindings="";
-}
-if (!$disable_kernel_check) {
- $disable_kernel_check=0;
-}
-if (defined($somajor) && not length $somajor) {
- $somajor="";
-}
-if (defined($sominor) && not length $sominor) {
- $sominor="";
-}
-if (defined($release_version) && not length $release_version) {
- $release_version="";
-}
-
-open IFILE, "<make/defines.mk.input" or die "Can't redirect stdin";
-open OFILE, ">${objdir}/make/defines.mk" or die "Can't redirect stdout";
-
-print OFILE "# This file was generated by configure from defines.mk.input\n";
-
-while (<IFILE>) {
- chomp;
- $_ =~ s/\@SRCDIR\@/$cdir/;
- $_ =~ s/\@CC\@/$cc/;
- $_ =~ s/\@CFLAGS\@/$cflags/;
- $_ =~ s/\@LDFLAGS\@/$ldflags/;
- $_ =~ s/\@OBJDIR\@/$objdir/;
- $_ =~ s/\@KERNEL_SRC\@/$kernel_src/;
- $_ =~ s/\@INCDIR\@/$incdir/;
- $_ =~ s/\@LIBDIR\@/$libdir/;
- $_ =~ s/\@CCSINCDIR\@/$ccsincdir/;
- $_ =~ s/\@CCSLIBDIR\@/$ccslibdir/;
- $_ =~ s/\@CMANINCDIR\@/$cmanincdir/;
- $_ =~ s/\@CMANLIBDIR\@/$cmanlibdir/;
- $_ =~ s/\@DLMINCDIR\@/$dlmincdir/;
- $_ =~ s/\@DLMLIBDIR\@/$dlmlibdir/;
- $_ =~ s/\@DLMCONTROLINCDIR\@/$dlmcontrolincdir/;
- $_ =~ s/\@DLMCONTROLLIBDIR\@/$dlmcontrollibdir/;
- $_ =~ s/\@FENCEINCDIR\@/$fenceincdir/;
- $_ =~ s/\@FENCELIBDIR\@/$fencelibdir/;
- $_ =~ s/\@FENCEDINCDIR\@/$fencedincdir/;
- $_ =~ s/\@FENCEDLIBDIR\@/$fencedlibdir/;
- $_ =~ s/\@LOGTINCDIR\@/$logtincdir/;
- $_ =~ s/\@LOGTLIBDIR\@/$logtlibdir/;
- $_ =~ s/\@NCURSESINCDIR\@/$ncursesincdir/;
- $_ =~ s/\@NCURSESLIBDIR\@/$ncurseslibdir/;
- $_ =~ s/\@SLANGINCDIR\@/$slangincdir/;
- $_ =~ s/\@SLANGLIBDIR\@/$slanglibdir/;
- $_ =~ s/\@COROSYNCINCDIR\@/$corosyncincdir/;
- $_ =~ s/\@COROSYNCLIBDIR\@/$corosynclibdir/;
- $_ =~ s/\@OPENAISINCDIR\@/$openaisincdir/;
- $_ =~ s/\@OPENAISLIBDIR\@/$openaislibdir/;
- $_ =~ s/\@COROSYNCBIN\@/$corosyncbin/;
- $_ =~ s/\@LDAPINCDIR\@/$ldapincdir/;
- $_ =~ s/\@LDAPLIBDIR\@/$ldaplibdir/;
- $_ =~ s/\@ZLIBINCDIR\@/$zlibincdir/;
- $_ =~ s/\@ZLIBLIBDIR\@/$zliblibdir/;
- $_ =~ s/\@LIBEXECDIR\@/$libexecdir/;
- $_ =~ s/\@MANDIR\@/$mandir/;
- $_ =~ s/\@SBINDIR\@/$sbindir/;
- $_ =~ s/\@RELATIVESBIN\@/$relativesbin/;
- $_ =~ s/\@PREFIX\@/$prefix/;
- $_ =~ s/\@INITDDIR\@/$initddir/;
- $_ =~ s/\@SHAREDIR\@/$sharedir/;
- $_ =~ s/\@DOCDIR\@/$docdir/;
- $_ =~ s/\@LOGDIR\@/$logdir/;
- $_ =~ s/\@LOGROTATEDIR\@/$logrotatedir/;
- $_ =~ s/\@SYSLOGFACILITY\@/$syslogfacility/;
- $_ =~ s/\@SYSLOGLEVEL\@/$sysloglevel/;
- $_ =~ s/\@CONFDIR\@/$confdir/;
- $_ =~ s/\@CONFFILE\@/$conffile/;
- $_ =~ s/\@ENABLE_CONTRIB\@/$enable_contrib/;
- $_ =~ s/\@DISABLE_DBUS\@/$disable_dbus/;
- $_ =~ s/\@DISABLE_COMMON\@/$without_common/;
- $_ =~ s/\@DISABLE_CONFIG\@/$without_config/;
- $_ =~ s/\@DISABLE_CMAN\@/$without_cman/;
- $_ =~ s/\@DISABLE_DLM\@/$without_dlm/;
- $_ =~ s/\@DISABLE_GROUP\@/$without_group/;
- $_ =~ s/\@DISABLE_FENCE\@/$without_fence/;
- $_ =~ s/\@DISABLE_GFS2\@/$without_gfs2/;
- $_ =~ s/\@DISABLE_RGMANAGER\@/$without_rgmanager/;
- $_ =~ s/\@DISABLE_BINDINGS\@/$without_bindings/;
-
- print OFILE "$_\n";
-}
-
-close IFILE;
-
-if ((not defined($somajor)) || (not defined($sominor)) || (not defined($release_version))) {
-
- my $current_soname;
- my $current_version;
- if ( -f 'make/official_release_version' ) {
- open OFFICIAL_VERSION, '<', "make/official_release_version";
- while (<OFFICIAL_VERSION>) {
- if ($_ =~ /SONAME/) {
- $current_soname = $_;
- }
- if ($_ =~ /VERSION/) {
- $current_version = $_;
- }
- }
- close OFFICIAL_VERSION;
- }
-
- if ((not defined($somajor)) || (not defined($sominor))) {
- if (not defined($current_soname)) {
- print "ERROR: SONAME not defined in make/official_release_version\n";
- exit 1;
- } else {
- $current_soname =~ s/.*"(.*)"\n/$1/;
- my @release_soname = split /\./, $current_soname;
- $somajor = $release_soname[0];
- $sominor = $release_soname[1];
- }
- }
-
- if (not defined($release_version)) {
- if (not defined($current_version)) {
- $release_version = `date +%s`;
- chomp $release_version;
- } else {
- $release_version = $current_version;
- $release_version =~ s/.*"(.*)"\n/$1/;
- }
- }
-}
-
-print OFILE "ifndef SOMAJOR\n";
-print OFILE "SOMAJOR = $somajor\n";
-print OFILE "endif\n";
-print OFILE "ifndef SOMINOR\n";
-print OFILE "SOMINOR = $sominor\n";
-print OFILE "endif\n";
-print OFILE "RELEASE_VERSION = $release_version\n";
-print OFILE "CFLAGS += -DRELEASE_VERSION=\\\"$release_version\\\"\n";
-
-close OFILE;
-
-open OFILE, ">${objdir}/.configure.sh.tmp" or die "Can't redirect stdout";
-print OFILE "#!/bin/bash\n";
-print OFILE "$0 @invoke \$@\n";
-print OFILE "exit \$?\n";
-close OFILE;
-
-system("mv ${objdir}/.configure.sh.tmp ${objdir}/.configure.sh");
-
-print "Completed Makefile configuration\n\n";
diff --git a/contrib/Makefile b/contrib/Makefile
deleted file mode 100644
index 368e035..0000000
--- a/contrib/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-include ../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-ifdef contrib_code
-SUBDIRS=libaislock
-endif
diff --git a/contrib/libaislock/Makefile b/contrib/libaislock/Makefile
deleted file mode 100644
index 269d845..0000000
--- a/contrib/libaislock/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-TARGET= libaislock
-
-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${dlmincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${dlmlibdir} -ldlm
-LDFLAGS += -lpthread
diff --git a/contrib/libaislock/libaislock.c b/contrib/libaislock/libaislock.c
deleted file mode 100644
index 4de90ba..0000000
--- a/contrib/libaislock/libaislock.c
+++ /dev/null
@@ -1,466 +0,0 @@
-#include <pthread.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-
-#include <linux/types.h>
-#include <linux/dlm.h>
-#define BUILDING_LIBDLM
-#include "libdlm.h"
-#include "libaislock.h"
-#include <linux/dlm_device.h>
-
-enum {
- SA_LCK_GRANT_CB = 1,
- SA_LCK_WAITER_CB = 2,
-};
-
-static struct dlm_ls_info *sa_default_ls = NULL;
-
-static inline int lkmode_ais2dlm(SaLckLockModeT mode)
-{
- switch(mode)
- {
- case SA_LCK_PR_LOCK_MODE:
- return DLM_LOCK_PR;
- case SA_LCK_EX_LOCK_MODE:
- return DLM_LOCK_EX;
- default:
- return -1;
- }
-}
-
-static inline SaLckLockModeT lkmode_dlm2ais(int mode)
-{
- switch(mode)
- {
- case DLM_LOCK_PR:
- return SA_LCK_PR_LOCK_MODE;
- case DLM_LOCK_EX:
- return SA_LCK_EX_LOCK_MODE;
- default:
- return -1;
- }
-}
-
-static inline unsigned long lkflag_ais2dlm(SaLckLockFlagsT flag)
-{
- unsigned long dlm_flag = 0;
-
- if(flag & SA_LCK_LOCK_NO_QUEUE)
- dlm_flag |= DLM_LKF_NOQUEUE;
- if(flag & SA_LCK_LOCK_ORPHAN)
- dlm_flag |= DLM_LKF_ORPHAN;
-
- return dlm_flag;
-}
-
-static inline SaLckLockStatusT lkstatus_dlm2ais(int status)
-{
- switch(status)
- {
- case -ENOMEM:
- return SA_LCK_LOCK_NO_MORE;
- case 0:
- return SA_LCK_LOCK_GRANTED;
- case -EAGAIN:
- return SA_LCK_LOCK_NOT_QUEUED;
- default:
- return -1;
- }
-}
-
-static inline SaErrorT lkerr_dlm2ais(int status)
-{
- switch(status)
- {
- case -EINVAL:
- return SA_ERR_INVALID_PARAM;
- case 0:
- return SA_OK;
- default:
- return -1;
- }
-}
-
-
-SaErrorT
-saLckInitialize(SaLckHandleT *lckHandle, const SaLckCallbacksT *lckCallbacks,
- const SaVersionT *version)
-{
- dlm_lshandle_t ls = NULL;
-
- if (NULL == lckHandle)
- return SA_ERR_INVALID_PARAM;
-
- if (lckCallbacks) {
- lckHandle->callback.saLckLockGrantCallback =
- lckCallbacks->saLckLockGrantCallback;
- lckHandle->callback.saLckLockWaiterCallback =
- lckCallbacks->saLckLockWaiterCallback;
- lckHandle->callback.saLckResourceUnlockCallback =
- lckCallbacks->saLckResourceUnlockCallback;
- } else {
- lckHandle->callback.saLckLockGrantCallback = NULL;
- lckHandle->callback.saLckLockWaiterCallback = NULL;
- lckHandle->callback.saLckResourceUnlockCallback = NULL;
- }
- lckHandle->version.releaseCode = version->releaseCode;
- lckHandle->version.major = version->major;
- lckHandle->version.minor = version->minor;
-
- ls = dlm_create_lockspace("sa_default", 0600);
- if (!ls)
- return SA_ERR_LIBRARY;
-
- sa_default_ls = (struct dlm_ls_info *)ls;
- return SA_OK;
-}
-
-
-SaErrorT
-saLckFinalize(SaLckHandleT *lckHandle)
-{
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- if(!dlm_release_lockspace("sa_default", sa_default_ls, 1)) {
- return SA_OK;
- } else {
- return SA_ERR_LIBRARY;
- }
-}
-
-SaErrorT
-saLckResourceOpen(const SaLckHandleT *lckHandle, const SaNameT *lockName,
- SaLckResourceIdT *resourceId)
-{
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- if (lockName->length <= 31 ) /* OpenDLM only support namelen <= 31*/
- {
- resourceId->name.length = lockName->length;
- strncpy((char *)resourceId->name.value, (char *)lockName->value, lockName->length);
- } else {
- return SA_ERR_NO_MEMORY;
- }
-
- return SA_OK;
-}
-
-
-SaErrorT
-saLckResourceClose(SaLckHandleT *lckHandle, SaLckResourceIdT *resourceId)
-{
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- return SA_OK;
-}
-
-
-SaErrorT
-saLckSelectionObjectGet(const SaLckHandleT *lckHandle,
- SaSelectionObjectT *selectionObject)
-{
- int fd = -1;
-
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- fd = dlm_ls_get_fd(sa_default_ls);
-
- if(!fd)
- return SA_ERR_LIBRARY;
-
- *selectionObject = fd;
-
- return SA_OK;
-}
-
-
-SaErrorT
-saLckDispatch(const SaLckHandleT *lckHandle,
- const SaDispatchFlagsT dispatchFlags)
-{
- int status;
- int fdflags;
- char resultbuf[sizeof(struct dlm_lock_result)];
- struct dlm_lock_result *result = (struct dlm_lock_result *)resultbuf;
- char *fullresult=NULL;
- SaLckLockIdT *lkid;
- SaLckLockModeT lock_mode;
- int fd = -1;
-
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- fd = dlm_ls_get_fd(sa_default_ls);
-
- if(!fd)
- return SA_ERR_LIBRARY;
-
- fdflags = fcntl(fd, F_GETFL, 0);
- fcntl(fd, F_SETFL, fdflags | O_NONBLOCK);
-
- do
- {
-
- /* Just read the header first */
- status = read(fd, result, sizeof(struct dlm_lock_result));
- if (status <= 0)
- break;
-
- if (result->length != status)
- {
- int newstat;
-
- fullresult = malloc(result->length);
- if (!fullresult)
- break;
-
- newstat = read(fd, fullresult, result->length);
-
- /* If it read OK then use the new data. otherwise we can
- still deliver the AST, it just might not have all the
- info in it...hmmm */
- if (newstat == result->length)
- result = (struct dlm_lock_result *)fullresult;
- }
-
- /* Copy lksb to user's buffer - except the LVB ptr */
- memcpy(result->user_lksb, &result->lksb,
- sizeof(struct dlm_lksb) - sizeof(char*));
-
- /* Flip the status. Kernel space likes negative return codes,
- userspace positive ones */
- result->user_lksb->sb_status = -result->user_lksb->sb_status;
-
- /* Need not to care LVB*/
-#ifdef QUERY
- /* Copy optional items */
- if (result->qinfo_offset)
- {
- /* Just need the lockcount written out here */
- struct dlm_queryinfo *qi = (struct dlm_queryinfo *)
- (fullresult+result->qinfo_offset);
- result->user_qinfo->gqi_lockcount = qi->gqi_lockcount;
- }
-
- if (result->qresinfo_offset)
- memcpy(result->user_qinfo->gqi_resinfo,
- fullresult+result->qresinfo_offset,
- sizeof(struct dlm_resinfo));
-
- if (result->qlockinfo_offset)
- memcpy(result->user_qinfo->gqi_lockinfo,
- fullresult+result->qlockinfo_offset,
- sizeof(struct dlm_lockinfo) *
- result->user_qinfo->gqi_lockcount);
-#endif
- /* Call AST */
- lkid = (SaLckLockIdT *)result->user_astparam;
- if (lkid->unlock) {
- /* dispatch unlock ast */
- lkid->unlock = 0;
- lkid->held_mode = 0;
- if(lckHandle->callback.saLckResourceUnlockCallback)
- lckHandle->callback.
- saLckResourceUnlockCallback(
- lkid->args, lkid->resource, lkid,
- SA_LCK_LOCK_RELEASED, SA_OK);
-
- } else if (SA_LCK_GRANT_CB == (int)result->user_astaddr) {
- /* dispatch lock ast */
- if (0 == lkid->lksb.sb_status) {
- lkid->held_mode = lkid->requested_mode;
- lock_mode = lkid->requested_mode;
- } else {
- lock_mode = lkid->held_mode;
- }
-
- if(lckHandle->callback.saLckLockGrantCallback)
- lckHandle->callback.
- saLckLockGrantCallback(
- lkid->args, lkid->resource,
- lkid, lock_mode,
- lkstatus_dlm2ais(
- lkid->lksb.sb_status),
- SA_OK);
- } else if (SA_LCK_WAITER_CB == (int)result->user_astaddr) {
- /* dispatch waiter ast */
- if(lckHandle->callback.saLckLockWaiterCallback)
- lckHandle->callback.
- saLckLockWaiterCallback(
- lkid->args, lkid->resource,
- lkid, lkid->held_mode, result->bast_mode);
- } else {
- return SA_ERR_LIBRARY;
- }
- } while (0 !=status && SA_DISPATCH_ONE != dispatchFlags);
-
- /* EAGAIN is not an error */
- if (status < 0 && errno == EAGAIN)
- status = 0;
-
- fcntl(fd, F_SETFL, fdflags);
- return SA_OK;
-}
-
-SaErrorT
-SaLckResourceLockAsync(const SaLckHandleT *lckHandle, SaInvocationT invocation,
- const SaLckResourceIdT *resourceId, SaLckLockIdT *lockId,
- SaLckLockModeT lockMode, SaLckLockFlagsT lockFlags,
- SaTimeT timeout)
-{
- int ret_val; /* value to be returned from function */
-
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- /*FIXME deal with timeout in lock/lockasync/unlock.
- */
- lockId->resource = (SaLckResourceIdT *)resourceId;
- lockId->requested_mode = lockMode;
- lockId->args = invocation;
-
- ret_val = dlm_ls_lock(sa_default_ls, lkmode_ais2dlm(lockMode),
- &(lockId->lksb), lkflag_ais2dlm(lockFlags),
- (void *)(resourceId->name.value),
- resourceId->name.length, 0, (void *)SA_LCK_GRANT_CB,
- lockId, (void *)SA_LCK_WAITER_CB, NULL);
-
- return lkerr_dlm2ais(ret_val);
-}
-
-SaErrorT
-saLckResourceLock(const SaLckHandleT *lckHandle, SaInvocationT invocation,
- const SaLckResourceIdT *resourceId, SaLckLockIdT *lockId,
- SaLckLockModeT lockMode, SaLckLockFlagsT lockFlags,
- SaTimeT timeout, SaLckLockStatusT *lockStatus)
-
-{
- int ret_val; /* value to be returned from function */
-
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- lockId->resource = (SaLckResourceIdT *)resourceId;
- lockId->requested_mode = lockMode;
- lockId->args = invocation;
-
- ret_val = dlm_ls_lock_wait(sa_default_ls, lkmode_ais2dlm(lockMode),
- &(lockId->lksb), lkflag_ais2dlm(lockFlags),
- (void *)(resourceId->name.value),
- resourceId->name.length, 0, lockId,
- (void *)SA_LCK_WAITER_CB, NULL);
-
- *lockStatus = lkstatus_dlm2ais(lockId->lksb.sb_status);
- lockId->held_mode = lockId->requested_mode;
-
- return lkerr_dlm2ais(ret_val);
-}
-
-SaErrorT
-saLckResourceUnlock(const SaLckHandleT *lckHandle, SaLckLockIdT *lockId,
- SaTimeT timeout)
-{
- int ret_val; /* value to be returned from function */
-
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- ret_val = dlm_ls_unlock_wait(sa_default_ls, lockId->lksb.sb_lkid, 0,
- &(lockId->lksb));
- lockId->held_mode = 0;
-
- return lkerr_dlm2ais(ret_val);
-}
-
-SaErrorT
-saLckResourceUnlockAsync(const SaLckHandleT *lckHandle,
- SaInvocationT invocation, SaLckLockIdT *lockId)
-{
- int ret_val; /* value to be returned from function */
-
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- lockId->unlock = 1;
- lockId->args = invocation;
-
-
- ret_val = dlm_ls_unlock(sa_default_ls, lockId->lksb.sb_lkid, 0, &(lockId->lksb),
- lockId);
-
- return lkerr_dlm2ais(ret_val);
-}
-
-
-SaErrorT
-saLckLockPurge(const SaLckHandleT *lckHandle,
- const SaLckResourceIdT *resourceId)
-{
-#ifdef QUERY
- int ret_val; /* value to be returned from function */
- SaLckLockIdT lockId;
- struct dlm_lksb lksb;
- struct dlm_resinfo resinfo;
- static struct dlm_queryinfo qinfo;
- struct dlm_lockinfo *p;
-
- qinfo.gqi_resinfo = &resinfo;
- qinfo.gqi_lockinfo = malloc(sizeof(struct dlm_lockinfo) * 10);
- qinfo.gqi_locksize = 10;
-
-
- if ( NULL == sa_default_ls ) {
- return SA_ERR_LIBRARY;
- }
-
- lockId.resource = (SaLckResourceIdT *)resourceId;
- lockId.requested_mode = DLM_LOCK_NL;
-
- ret_val = dlm_ls_lock_wait(sa_default_ls, DLM_LOCK_NL,
- &(lockId.lksb), DLM_LKF_EXPEDITE,
- (void *)(resourceId->name.value),
- resourceId->name.length, 0, &lockId,
- (void *)SA_LCK_WAITER_CB, NULL);
-
- dlm_ls_query_wait(sa_default_ls, &(lockId.lksb),
- DLM_QUERY_QUEUE_ALL|DLM_QUERY_LOCKS_ORPHAN, &qinfo);
-
- for ( p = qinfo.gqi_lockinfo; 0 != p->lki_lkid; p++ ) {
- lksb.sb_lkid = p->lki_lkid;
- ret_val = dlm_ls_unlock_wait(sa_default_ls, p->lki_lkid, 0,
- &lksb);
- }
-
- ret_val = dlm_ls_unlock_wait(sa_default_ls, lockId.lksb.sb_lkid, 0,
- &(lockId.lksb));
-
- return lkerr_dlm2ais(ret_val);
-#else
- return -1;
-#endif
-}
-
diff --git a/contrib/libaislock/libaislock.h b/contrib/libaislock/libaislock.h
deleted file mode 100644
index 3faeffd..0000000
--- a/contrib/libaislock/libaislock.h
+++ /dev/null
@@ -1,190 +0,0 @@
-typedef char SaInt8T;
-typedef short SaInt16T;
-typedef long SaInt32T;
-typedef long long SaInt64T;
-typedef unsigned char SaUint8T;
-typedef unsigned short SaUint16T;
-typedef unsigned long SaUint32T;
-typedef unsigned long long SaUint64T;
-typedef SaInt64T SaTimeT;
-
-#define SA_MAX_NAME_LENGTH 256
-
-typedef struct {
- SaUint16T length;
- unsigned char value[SA_MAX_NAME_LENGTH];
-} SaNameT;
-
-typedef struct {
- char releaseCode;
- unsigned char major;
- unsigned char minor;
-} SaVersionT;
-
-typedef int SaSelectionObjectT;
-
-typedef void *SaInvocationT;
-
-typedef enum {
- SA_DISPATCH_ONE = 1,
- SA_DISPATCH_ALL = 2,
- SA_DISPATCH_BLOCKING = 3
-} SaDispatchFlagsT;
-
-typedef enum {
- SA_OK = 1,
- SA_ERR_LIBRARY = 2,
- SA_ERR_VERSION = 3,
- SA_ERR_INIT = 4,
- SA_ERR_TIMEOUT = 5,
- SA_ERR_TRY_AGAIN = 6,
- SA_ERR_INVALID_PARAM = 7,
- SA_ERR_NO_MEMORY = 8,
- SA_ERR_BAD_HANDLE = 9,
- SA_ERR_BUSY = 10,
- SA_ERR_ACCESS = 11,
- SA_ERR_NOT_EXIST = 12,
- SA_ERR_NAME_TOO_LONG = 13,
- SA_ERR_EXIST = 14,
- SA_ERR_NO_SPACE = 15,
- SA_ERR_INTERRUPT =16,
- SA_ERR_SYSTEM = 17,
- SA_ERR_NAME_NOT_FOUND = 18,
- SA_ERR_NO_RESOURCES = 19,
- SA_ERR_NOT_SUPPORTED = 20,
- SA_ERR_BAD_OPERATION = 21,
- SA_ERR_FAILED_OPERATION = 22,
- SA_ERR_MESSAGE_ERROR = 23,
- SA_ERR_NO_MESSAGE = 24,
- SA_ERR_QUEUE_FULL = 25,
- SA_ERR_QUEUE_NOT_AVAILABLE = 26,
- SA_ERR_BAD_CHECKPOINT = 27,
- SA_ERR_BAD_FLAGS = 28
-} SaErrorT;
-
-/* Chapter 10 */
-typedef enum {
- SA_LCK_PR_LOCK_MODE = 1,
- SA_LCK_EX_LOCK_MODE = 2
-} SaLckLockModeT;
-
-typedef struct{
- int site;
- int pid;
-} SaLckLockHolderT;
-
-typedef struct {
- SaLckLockHolderT orphan_holder;
- SaNameT name;
-} SaLckResourceIdT;
-
-typedef struct {
- struct dlm_lksb lksb;
- SaLckResourceIdT *resource;
- SaLckLockModeT held_mode;
- SaLckLockModeT requested_mode;
- int unlock;
- SaInvocationT args;
-} SaLckLockIdT;
-
-#define SA_LCK_LOCK_NO_QUEUE 0x1
-#define SA_LCK_LOCK_ORPHAN 0x2
-#define SA_LCK_LOCK_TIMEOUT 0X4
-typedef SaUint32T SaLckLockFlagsT;
-
-typedef enum {
- SA_LCK_LOCK_GRANTED = 1,
- SA_LCK_LOCK_RELEASED = 2,
- SA_LCK_LOCK_DEADLOCK = 3,
- SA_LCK_LOCK_NOT_QUEUED = 4,
- SA_LCK_LOCK_TIMED_OUT = 5,
- SA_LCK_LOCK_ORPHANED = 6,
- SA_LCK_LOCK_NO_MORE = 7
-} SaLckLockStatusT;
-
-typedef void
-(*SaLckLockGrantCallbackT)(SaInvocationT invocation,
- const SaLckResourceIdT *resourceId,
- const SaLckLockIdT *lockId,
- SaLckLockModeT lockMode,
- SaLckLockStatusT lockStatus,
- SaErrorT error);
-
-typedef void
-(*SaLckLockWaiterCallbackT)(SaInvocationT invocation,
- const SaLckResourceIdT *resourceId,
- const SaLckLockIdT *lockId,
- SaLckLockModeT modeHeld,
- SaLckLockModeT modeRequested);
-
-typedef void
-(*SaLckResourceUnlockCallbackT)(SaInvocationT invocation,
- const SaLckResourceIdT *resourceId,
- const SaLckLockIdT *lockId,
- SaLckLockStatusT lockStatus,
- SaErrorT error);
-typedef struct SaLckCallbacks {
- SaLckLockGrantCallbackT saLckLockGrantCallback;
- SaLckLockWaiterCallbackT saLckLockWaiterCallback;
- SaLckResourceUnlockCallbackT saLckResourceUnlockCallback;
-}SaLckCallbacksT;
-
-typedef struct {
- SaLckCallbacksT callback;
- SaVersionT version;
-} SaLckHandleT;
-
- SaErrorT
-saLckInitialize(SaLckHandleT *lckHandle, const SaLckCallbacksT *lckCallbacks,
- const SaVersionT *version);
-
- SaErrorT
-saLckSelectionObjectGet(const SaLckHandleT *lckHandle,
- SaSelectionObjectT *selectionObject);
-
- SaErrorT
-saLckDispatch(const SaLckHandleT *lckHandle,
- const SaDispatchFlagsT dispatchFlags);
-
- SaErrorT
-saLckFinalize(SaLckHandleT *lckHandle);
-
- SaErrorT
-saLckResourceOpen(const SaLckHandleT *lckHandle,
- const SaNameT *lockName,
- SaLckResourceIdT *resourceId);
-
- SaErrorT
-saLckResourceClose(SaLckHandleT *lckHandle, SaLckResourceIdT *resourceId);
-
- SaErrorT
-saLckResourceLock(const SaLckHandleT *lckHandle, SaInvocationT invocation,
- const SaLckResourceIdT *resourceId,
- SaLckLockIdT *lockId,
- SaLckLockModeT lockMode,
- SaLckLockFlagsT lockFlags,
- SaTimeT timeout,
- SaLckLockStatusT *lockStatus);
-
- SaErrorT
-SaLckResourceLockAsync(const SaLckHandleT *lckHandle,
- SaInvocationT invocation,
- const SaLckResourceIdT *resourceId,
- SaLckLockIdT *lockId,
- SaLckLockModeT lockMode,
- SaLckLockFlagsT lockFlags,
- SaTimeT timeout);
-
- SaErrorT
-saLckResourceUnlock(const SaLckHandleT *lckHandle,
- SaLckLockIdT *lockId,
- SaTimeT timeout);
-
- SaErrorT
-saLckResourceUnlockAsync(const SaLckHandleT *lckHandle,
- SaInvocationT invocation,
- SaLckLockIdT *lockId);
-
- SaErrorT
-saLckLockPurge(const SaLckHandleT *lckHandle,
- const SaLckResourceIdT *resourceId);
diff --git a/contrib/libaislock/libaislock.pc.in b/contrib/libaislock/libaislock.pc.in
deleted file mode 100644
index a4804a9..0000000
--- a/contrib/libaislock/libaislock.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: libaislock
-Version: @VERSION@
-Description: libaislock
-Requires:
-Libs: -L${libdir} -laislock
-Cflags: -I${includedir}
diff --git a/dlm/Makefile b/dlm/Makefile
deleted file mode 100644
index 7c8cc33..0000000
--- a/dlm/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS=libdlm libdlmcontrol tool man
diff --git a/dlm/doc/dlm_tool.txt b/dlm/doc/dlm_tool.txt
deleted file mode 100644
index d66cdb0..0000000
--- a/dlm/doc/dlm_tool.txt
+++ /dev/null
@@ -1,167 +0,0 @@
-
-The dlm is configured and controlled from user space through sysfs and a
-couple of ioctl's. A command line program, dlm_tool, can be used to do
-everything manually.
-
-Here are the dlm_tool config/control actions that will be used:
-
-set_local <nodeid> <ipaddr> [<weight>]
-set_node <nodeid> <ipaddr> [<weight>]
-stop <ls_name>
-terminate <ls_name>
-start <ls_name> <event_nr> <type> <nodeid>...
-get_done <ls_name>
-finish <ls_name> <event_nr>
-set_id <ls_name> <id>
-
-For testing and illustration, some actions have been added to dlm_tool to use
-the libdlm API.
-
-create <ls_name>
-release <ls_name>
-lock <ls_name> <res_name> <mode> [<flag>,...]
-unlock <ls_name> <lkid> [<flag>,...]
-convert <ls_name> <lkid> <mode> [<flag>,...]
-
-So, dlm_tool is standing in for what would usually be two different entities.
-The first set of config/control actions would usually be performed by a system
-daemon associated with a cluster membership manager. The second set of libdlm
-actions would usually be performed by an application that wants to use the dlm
-for synchronization.
-
-
-Example
-
-1. There are three machines that we want to use the dlm:
-
-nodea -- 10.0.0.1
-nodeb -- 10.0.0.2
-nodec -- 10.0.0.3
-
-
-2. We'll pick arbitrary integer node ID's for these machines:
-
-nodea -- 1
-nodeb -- 2
-nodec -- 3
-
-
-3. On each node we first need to tell the dlm what the local IP address
-and nodeid are:
-
-nodea> dlm_tool set_local 1 10.0.0.1
-nodeb> dlm_tool set_local 2 10.0.0.2
-nodec> dlm_tool set_local 3 10.0.0.3
-
-
-4. On all nodes we need to set up the nodeid to IP address mappings:
-
-all> dlm_tool set_node 1 10.0.0.1
-all> dlm_tool set_node 2 10.0.0.2
-all> dlm_tool set_node 3 10.0.0.3
-
-
-5. All dlm locking happens within a lockspace; we need to create a test
-lockspace for all the nodes to use. This step would usually be an application
-that wants to use the dlm and creates a lockspace to use.
-
-all> dlm_tool create test
-
-
-6. The lockspace needs to be "started" on all the nodes. The <event_nr>
-should begin at 1 and be incremented for each consecutive start that's done on
-the dlm. The <type> field isn't used by the dlm and can be 0. Finally, a
-list of nodeid's using the lockspace is given.
-
-all> dlm_tool start test 1 0 1 2 3
-
-
-7. The dlm will now start up on all three nodes. Whenever it starts it needs
-to do recovery. Once recovery is done, the event_nr used for the start (1
-above) will be shown as the dlm_tool get_done output. You need to wait for
-this on all nodes (i.e. for all nodes to complete recovery) before moving on
-to the next step.
-
-all> dlm_tool get_done test
-done event_nr 1
-
-
-8. The lockspace finally needs to know that recovery is finished on all nodes.
-The event_nr used for the start is used here.
-
-all> dlm_tool finish test 1
-
-
-9. The lockspace can now be used by the application for locking, or using
-dlm_tool using the libdlm actions above.
-
-all> dlm_tool lock/unlock/convert ...
-
-
-10. Say that nodea fails. Nodeb and nodec need to remove nodea from the
-lockspace and do recovery. The first step is to suspend the dlm operation on
-the remaining nodes:
-
-nodeb,nodec> dlm_tool stop test
-
-
-11. The lockspace then needs to be started again with the new set of lockspace
-members and an incremented event_nr.
-
-nodeb,nodec> dlm_tool start test 2 0 2 3
-
-
-12. We wait for recovery to complete on nodeb and nodec.
-
-nodeb,nodec> dlm_tool get_done test
-done event_nr 2
-
-
-13. Tell the lockspace that recovery is finished on both nodes.
-
-nodeb,nodec> dlm_tool finish test 2
-
-
-14. Nodea comes back and wants to use the dlm again.
-
-nodea> dlm_tool create test
-
-
-15. To add nodea back into the lockspace, first suspend lockspace operations
-on nodeb and nodec.
-
-nodeb,nodec> dlm_tool stop test
-
-
-16. Start the lockspace on all the nodes with an incremented event_nr
-(event_nr can go back to 1 again for nodea).
-
-nodeb,nodec> dlm_tool start test 3 0 1 2 3
-nodea> dlm_tool start test 1 0 1 2 3
-
-
-17. Wait for all nodes to complete recovery.
-
-nodeb,nodec> dlm_tool get_done test
-done event_nr 3
-
-nodea> dlm_tool get_done test
-done event_nr 1
-
-
-18. Tell the lockspace that recovery is finished everywhere.
-
-nodeb,nodec> dlm_tool finish test 3
-nodea> dlm_tool finish test 1
-
-
-
-Notes:
-
-- When you use more than one lockspace on the nodes, you need to use
- dlm_tool set_id on all nodes to assign each lockspace a unique
- integer id. This is done between the create and the first start.
-
-- A node can leave a lockspace using dlm_tool release (the opposite of
- dlm_tool create).
-
diff --git a/dlm/doc/example.c b/dlm/doc/example.c
deleted file mode 100644
index 9f3ea11..0000000
--- a/dlm/doc/example.c
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <signal.h>
-#include <libdlm.h>
-
-/*
- * Simple libdlm locking demo
- *
- * Daniel Phillips, phillips(a)redhat.com
- *
- */
-
-#define error(string, args...) do { printf(string, ##args); exit(1); } while (0)
-
-void my_ast(void *arg)
-{
- printf("ast got arg %p\n", arg);
-}
-
-int main(void)
-{
- int fd, child;
- struct dlm_lksb lksb;
-
- if ((fd = dlm_get_fd()) < 0)
- error("dlm error %i, %s\n", errno, strerror(errno));
-
- switch (child = fork()) {
- case -1:
- error("fork error %i, %s\n", errno, strerror(errno));
- case 0:
- while (1)
- dlm_dispatch(fd);
- }
-
- if (dlm_lock(LKM_PWMODE, &lksb, LKF_NOQUEUE, "foo", 3,
- 0, my_ast, (void *)&fd, NULL, NULL) < 0)
- error("dlm error %i, %s\n", errno, strerror(errno));
- sleep(1);
-
- if (dlm_unlock(lksb.sb_lkid, 0, &lksb, NULL) < 0)
- error("dlm error %i, %s\n", errno, strerror(errno));
- sleep(1);
-
- kill(child, SIGTERM);
- return 0;
-}
-
diff --git a/dlm/doc/libdlm.txt b/dlm/doc/libdlm.txt
deleted file mode 100644
index 18d44f9..0000000
--- a/dlm/doc/libdlm.txt
+++ /dev/null
@@ -1,533 +0,0 @@
-User-space interface to DLM
----------------------------
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdint.h>
-#include <libdlm.h>
-
-cc -D_REENTRANT prog.c -ldlm -lpthread
-
-cc prog.c -ldlm_lt
-
-
-There are basically two interfaces to libdlm. The first is the "dead simple"
-one that has limited functionality and assumes that the application is linked
-with pthreads. The second is the full-featured DLM interface that looks
-identical to the kernel interface.
-
-See CVS dlm/tests/usertest for examples of use of both these APIs.
-
-The simple one
---------------
-This provides two API calls, lock_resource() and unlock_resource(). Both of
-these calls block until the lock operation has completed - using a worker
-thread to deal with the callbacks that come from the kernel.
-
-int lock_resource(const char *resource, int mode, int flags, int *lockid);
-
- This function locks a named (NUL-terminated) resource and returns the
- lockid if successful. The mode may be any of
-
- LKM_NLMODE LKM_CRMODE LKM_CWMODE LKM_PRMODE LKM_PWMODE LKM_EXMODE
-
- Flags may be any combination of
-
- LKF_NOQUEUE - Don't wait if the lock cannot be granted immediately,
- will return EAGAIN if this is so.
-
- LKF_CONVERT - Convert lock to new mode. *lockid must be valid,
- resource name is ignored.
-
- LKF_QUECVT - Add conversion to the back of the convert queue - only
- valid for some convert operations
-
- LKF_PERSISTENT - Don't automatically unlock this lock when the process
- exits (must be root).
-
-
-int unlock_resource(int lockid);
-
- Unlocks the resource.
-
-
-
-The complicated one
--------------------
-This interface is identical to the kernel interface with the exception of
-the lockspace argument. All userland locks sit in the same lockspace by default.
-
-libdlm can be used in pthread or non-pthread applications. For pthread
-applications simply call the following function before doing any lock
-operations. If you're using pthreads, remember to define _REENTRANT at the
-top of the program or using -D_REENTRANT on the compile line.
-
-int dlm_pthread_init()
-
- Creates a thread to receive all lock ASTs. The AST callback function
- for lock operations will be called in the context of this thread.
- If there is a potential for local resource access conflicts you must
- provide your own pthread-based locking in the AST routine.
-
-
-int dlm_pthread_cleanup()
-
- Cleans up the default lockspace threads after use. Normally you
- don't need to call this, but if the locking code is in a
- dynamically loadable shared library this will probably be necessary.
-
-
-For non-pthread based applications the DLM provides a file descriptor
-that the program can feed into poll/select. If activity is detected
-on that FD then a dispatch function should be called:
-
-int dlm_get_fd()
-
- Returns a file-descriptor for the DLM suitable for passing in to
- poll() or select().
-
-int dlm_dispatch(int fd)
-
- Reads from the DLM and calls any AST routines that may be needed.
- This routine runs in the context of the caller so no extra locking
- is needed to protect local resources.
-
-
-int dlm_lock(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- struct dlm_range *range);
-
-
-mode lock mode:
- LKM_NLMODE NULL Lock
- LKM_CRMODE Concurrent read
- LKM_CWMODE Concurrent write
- LKM_PRMODE Protected read
- LKM_PWMODE Protected write
- LKM_EXMODE Exclusive
-
-flags LKF_NOQUEUE Don't queue the lock. If it cannot be
- granted return -EAGAIN
- LKF_CONVERT Convert an existing lock
- LKF_VALBLK Lock has a value block
- LKF_QUECVT Put conversion to the back of the queue
- LKF_EXPEDITE Grant a NL lock immediately regardless of
- other locks on the conversion queue
- LKF_PERSISTENT Specifies a lock that will
- not be unlocked when the process exits.
-
-lksb Lock status block.
- This structure contains the returned lock ID, the actual
- status of the lock operation (all lock ops are asynchronous)
- and the value block if LKF_VALBLK is set.
-
-name Name of the lock. Can be binary, max 64 bytes. Ignored for lock
- conversions.
-
-namelen Length of the above name. Ignored for lock conversions.
-
-parent ID of parent lock or NULL if this is a top-level lock
-
-ast Address of AST routine to be called when the lock operation
- completes. The final completion status of the lock will be
- in the lksb. the AST routine must not be NULL.
-
-astargs Argument to pass to the AST routine (most people pass the lksb
- in here but it can be anything you like.)
-
-bast Blocking AST routine. address of a function to call if this
- lock is blocking another. The function will be called with
- astargs.
-
-range an optional structure of two uint64_t that indicate the range
- of the lock. Locks with overlapping ranges will be granted only
- if the lock modes are compatible. locks with non-overlapping
- ranges (on the same resource) do not conflict. A lock with no
- range is assumed to have a range emcompassing the largest
- possible range. ie. 0-0xFFFFFFFFFFFFFFFF. Note that is is more
- efficient to specify no range than to specify the full range
- above.
-
-
-dlm_lock operations are asynchronous. If the call to dlm_lock returns an error
-then the operation has failed and the AST routine will not be called. If
-dlm_lock returns 0 it is still possible that the lock operation will fail. The
-AST routine will be called when the locking is complete or has failed and the
-status is returned in the lksb.
-
-For conversion operations the name and namelen are ignored and the lock ID in
-the LKSB is used to identify the lock.
-
-If a lock value block is specified then in general, a grant or a conversion to
-an equal-level or higher-level lock mode reads the lock value from the resource
-into the caller's lock value block. When a lock conversion from EX or PW
-to an equal-level or lower-level lock mode occurs, the contents of
-the caller's lock value block are written into the resource.
-
-If the AST routines or parameter are passed to a conversion operation then they
-will overwrite those values that were passed to a previous dlm_lock call.
-
-int dlm_lock_wait(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void *bastarg,
- void (*bastaddr) (void *bastarg),
- struct dlm_range *range);
-
-
-As above except that the call will block until the lock is
-granted or has failed. The return from the function is
-the final status of the lock request (ie that was returned
-in the lksb after the AST routine was called).
-
-
-
-int dlm_unlock(uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb,
- void *astarg)
-
-lkid Lock ID as returned in the lksb
-
-flags flags affecting the unlock operation:
- LKF_CANCEL CANCEL a pending lock or conversion.
- This returns the lock to it's
- previously granted mode (in case of a
- conversion) or unlocks it (in case of a
- waiting lock).
-
- LKF_IVVALBLK Invalidate value block
-
-lksb LKSB to return status and value block information.
-
-astarg New parameter to be passed to the completion AST.
- The completion AST routine is the
- last completion AST routine specified in a dlm_lock call.
- If dlm_lock_wait() was the last routine to issue a lock,
- dlm_unlock_wait() must be used to release the lock. If dlm_lock()
- was the last routine to issue a lock then either dlm_unlock()
- or dlm_unlock_wait() may be called.
-
-Unlocks are also asynchronous. The AST routine is called when the resource is
-successfully unlocked (see below).
-
-
-Extra status returns to the completion AST (apart from those already
-defined in errno.h)
-
-ECANCEL
- A lock conversion was successfully cancelled
-
-EUNLOCK
- An Unlock operation completed successfully
-
-EDEADLOCK
- The lock operation is causing a deadlock and has been cancelled. If this
- was a conversion then the lock is reverted to its previously granted state.
- If it was a new lock then it has not been granted.
- (NB Only conversion deadlocks are currently detected)
-
-int dlm_unlock_wait(uint32_t lkid,
- uint32 flags,
- struct dlm_lksb *lksb)
-
-As above but returns when the unlock operation is complete either because it
-finished or because an error was detected. In the case where
-the unlock operation was succesful no error is returned.
-
-The return value of the function call is the status of issuing
-the unlock operation. The status of the unlock operation itself
-is in the lock status block. Both of these must be checked to
-verify that the unlock has completed succesfully.
-
-Lock Query Operations
----------------------
-int dlm_query(struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo,
- void (*ast_routine(void *astarg)),
- void *astarg);
-
-The operation is asynchronous, the ultimate status and data will be returned into the
-dlm_query_info structure which should be checked when the ast_routine is
-called. The lksb must contain a valid lock ID in sb_lkid which is used to
-identify the resource to be queried, status will be returned in sb_status;
-As with the locking calls an AST woutine will be called when the query completes
-if the call itself returns 0.
-
-int dlm_query_wait(struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo)
-
-Same as dlm_query() except that it waits for the operation to complete.
-When the operation is complete the status of will be in the lksb. Both
-the return value from the function call and the condition code in the
-lksb must be evaluated.
-
-If the provided lock list is too short to hold all the locks, then sb_status
-in the lksb will contain -E2BIG but the list will be filled in as far as possible.
-Either gqi_lockinfo or gqi_resinfo may be NULL if that information is not required.
-
-/* Structures passed into and out of the query */
-
-struct gdlm_lockinfo
-{
- int lki_lkid; /* Lock ID on originating node */
- int lki_parent;
- int lki_node; /* Originating node (not master) */
- int lki_ownpid; /* Owner pid on the originating node */
- uint8 lki_state; /* Queue the lock is on */
- int8 lki_grmode /* Granted mode */
- int8 lki_rqmode; /* Requested mode */
- struct dlm_range lki_grrange /* Granted range, if applicable */
- struct dlm_range lki_rqrange /* Requested range, if applicable */
-};
-
-struct gdlm_resinfo
-{
- int rsi_length;
- int rsi_grantcount; /* No. of nodes on grant queue */
- int rsi_convcount; /* No. of nodes on convert queue */
- int rsi_waitcount; /* No. of nodes on wait queue */
- int rsi_masternode; /* Master for this resource */
- char rsi_name[DLM_RESNAME_MAXLEN]; /* Resource name */
- char rsi_valblk[DLM_LVB_LEN]; /* Master's LVB contents, if applicable */
-};
-
-struct dlm_queryinfo
-{
- struct dlm_resinfo *gqi_resinfo; /* Points to a single resinfo struct */
- struct dlm_lockinfo *gqi_lockinfo; /* This points to an array of structs */
- int gqi_locksize; /* input */
- int gqi_lockcount; /* output */
-};
-
-The query is made up of several blocks of bits as follows:
-
- 9 8 6 5 3 0
-+----------------+---+-------+---+-------+-----------+
-| reserved | Q | query | F | queue | lock mode |
-+----------------+---+-------+---+-------+-----------+
-
-lock mode is a normal DLM lock mode or DLM_LOCK_THIS
-to use the mode of the lock in sb_lkid.
-
-queue is a bitmap of
- DLM_QUERY_QUEUE_WAIT
- DLM_QUERY_QUEUE_CONVERT
- DLM_QUERY_QUEUE_GRANT
-
-or one of the two shorthands:
- DLM_QUERY_QUEUE_GRANTED (for WAIT+GRANT)
- DLM_QUERY_QUEUE_ALL (for all queues)
-
- F is a flag DLM_QUERY_LOCAL
-which specifies that a remote access should not
-happen. Only lock information that can
-be gleaned from the local node will be returned so
-be aware that it may not be complete.
-
-The query is one of the following:
- DLM_QUERY_LOCKS_HIGHER
- DLM_QUERY_LOCKS_LOWER
- DLM_QUERY_LOCKS_EQUAL
- DLM_QUERY_LOCKS_BLOCKING
- DLM_QUERY_LOCKS_NOTBLOCK
- DLM_QUERY_LOCKS_ALL
-
-which specifies which locks to look for by mode,
-either the lockmode is lower, equal or higher
-to the mode at the bottom of the query.
-DLM_QUERY_ALL will return all locks on the
-resource.
-
-DLM_QUERY_LOCKS_BLOCKING returns only locks
-that are blocking the current lock. The lock
-must not be waiting for grant or conversion
-for this to be a valid query, the other flags
-are ignored.
-
-DLM_QUERY_LOCKS_NOTBLOCKING returns only locks
-that are granted but NOT blocking the current lock.
-
-Q specifies which lock queue to compare. By default
-the granted queue is used. If the flags
-DLM_QUERY_RQMODE is set then the requested mode
-will be used instead.
-
-
-The "normal" way to call dlm_query is to put the
-address of the dlm_queryinfo struct into
-lksb.sb_lvbptr and pass the lksb as the AST param,
-that way all the information is available to you
-in the AST routine.
-
-Lockspace Operations
---------------------
-The DLM allows locks to be partitioned into "lockspaces", and these can be
-manipulated by userspace calls. It is possible (though not recommended) for
-an application to have multiple lockspaces open at one time.
-
-All the above calls work on the "default" lockspace, which should be
-fine for most users. The calls below allow you to isolate your
-application from all others running in the cluster. Remember, lockspaces
-are a cluster-wide resource, so if you create a lockspace called "myls" it
-will share locks with a lockspace called "myls" on all nodes.
-
-
-dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode);
-
- This creates a lockspace called <name> and the mode of the file
- user to access it wil be <mode> (subject to umask as usual).
- The lockspace must not already exist on this node, if it does -1
- will be returned and errno will be set to EEXIST. If you really
- want to use this lockspace you can then user dlm_open_lockspace()
- below. The name is the name of a misc device that will be created
- in /dev/misc.
-
- On success a handle to the lockspace is returned, which can be used
- to pass into subsequent dlm_ls_lock/unlock calls. Make no assumptions
- as to the content of this handle as it's content may change in future.
-
- The caller must have CAP_SYSADMIN privileges to do this operation.
-
-
-int dlm_release_lockspace(const char *name, dlm_lshandle_t lockspace, int force)
-
- Deletes a lockspace. If the lockspace still has active locks then -1 will be
- returned and errno set to EBUSY. Both the lockspace handle /and/ the name
- must be specified. This call also closes the lockspace and stops the thread
- associated with the lockspace, if any.
-
- Note that other nodes in the cluster may still have locks open on this
- lockspace.
- This call only removes the lockspace from the current node.
-
- If the force flag is set then the lockspace will be removed even if another
- user on this node has active locks in it. Existing users will NOT
- be notified if you do this, so be careful.
-
-
-dlm_lshandle_t dlm_open_lockspace(const char *name)
-
- Opens an already existing lockspace and returns a handle to it.
-
-
-int dlm_close_lockspace(dlm_lshandle_t lockspace)
-
- Close the lockspace. Any locks held by this process will be freed.
- If a thread is associated with this lockspace then it will be stopped.
-
-
-int dlm_ls_get_fd(dlm_lshandle_t lockspace)
-
- Returns the file descriptor associated with the lockspace so that the
- user call use it as input to poll/select.
-
-
-int dlm_ls_pthread_init(dlm_lshandle_t lockspace)
-
- Initialise threaded environment for this lockspace, similar
- to dlm_pthread_init() above.
-
-
-int dlm_ls_lock(dlm_lshandle_t lockspace,
- int mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*ast) (void *astarg),
- void *astarg,
- void (*bast) (void *astarg),
- struct dlm_range *range)
-
- Same as dlm_lock() above but takes a lockspace argument.
-
-int dlm_ls_lock_wait(dlm_lshandle_t lockspace,
- int mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- void *name,
- unsigned int namelen,
- uint32_t parent,
- void *bastarg,
- void (*bast) (void *bastarg),
- struct dlm_range *range)
-
- Same as dlm_lock_wait() above but takes a lockspace argument.
-
-
-int dlm_ls_unlock(dlm_lshandle_t lockspace,
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb,
- void *astarg)
-
-
- Same as dlm_unlock above but takes a lockspace argument.
-
-int dlm_ls_unlock_wait(dlm_lshandle_t lockspace,
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb)
-
-
- Same as dlm_unlock_wait above but takes a lockspace argument.
-
-
-int dlm_ls_query(dlm_lshandle_t lockspace,
- struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo,
- void (*ast_routine(void *astarg)),
- void *astarg);
-
- Same as dlm_query above but takes a lockspace argument.
-
-int dlm_ls_query_wait(dlm_lshandle_t lockspace,
- struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo)
-
- Same as dlm_query_wait above but takes a lockspace argument.
-
-
-One further point about lockspace operations is that there is no locking
-on the creating/destruction of lockspaces in the library so it is up to the
-application to only call dlm_*_lockspace when it is sure that
-no other locking operations are likely to be happening within that process.
-
-Libraries
----------
-There are two DLM libraries, one that uses pthreads (libdlm) to deliver ASTs
-and a light one one that doesn't (libdlm_lt).
-
-The "light" library contains only the following calls.
-
-- dlm_lock
-- dlm_unlock
-- dlm_query
-- dlm_get_fd
-- dlm_dispatch
-- dlm_ls_lock
-- dlm_ls_unlock
-- dlm_ls_query
-- dlm_ls_get_fd
-- dlm_create_lockspace
-- dlm_open_lockspace
-- dlm_release_lockspace
-- dlm_close_lockspace
-
-Note that libdlm (the pthreads one) also contains the non-threaded calls
-so you can choose at runtime if you need to.
diff --git a/dlm/doc/user-dlm-overview.txt b/dlm/doc/user-dlm-overview.txt
deleted file mode 100644
index bda3aea..0000000
--- a/dlm/doc/user-dlm-overview.txt
+++ /dev/null
@@ -1,325 +0,0 @@
-
-There are five ways to request a dlm lock (and five corresponding ways to
-unlock).
-
-- lock_resource
-- dlm_lock
-- dlm_ls_lock
-- dlm_lock_wait
-- dlm_ls_lock_wait
-
-- unlock_resource
-- dlm_unlock
-- dlm_ls_unlock
-- dlm_unlock_wait
-- dlm_ls_unlock_wait
-
-There is also a set of "administrative" functions that are used along with
-some of the lock/unlock requests. Which are used depends on which locking
-method is used or whether the application is threaded.
-
-- dlm_pthread_init
-- dlm_ls_pthread_init
-- dlm_pthread_cleanup
-- dlm_get_fd
-- dlm_ls_get_fd
-- dlm_dispatch
-- dlm_create_lockspace
-- dlm_open_lockspace
-- dlm_release_lockspace
-- dlm_close_lockspace
-
-
-Overview of lock request methods
---------------------------------
-
-- synchronous, default lockspace
- use dlm_pthread_init/dlm_pthread_cleanup if app is threaded
- use dlm_get_fd/dlm_dispatch if app is not threaded
- use unlock_resource to unlock
-
-int lock_resource(
- const char *resource,
- uint32_t mode,
- uint32_t flags,
- uint32_t *lkid);
-
-
-- asynchronous, default lockspace
- use dlm_pthread_init/dlm_pthread_cleanup if app is threaded
- use dlm_get_fd/dlm_dispatch if app is not threaded
- use dlm_unlock/dlm_unlock_wait to unlock
-
-int dlm_lock(
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*ast) (void *astarg),
- void *astarg,
- void (*bast) (void *astarg),
- struct dlm_range *range);
-
-
-- synchronous, default lockspace
- use dlm_pthread_init/dlm_pthread_cleanup if app is threaded
- use dlm_get_fd/dlm_dispatch if app is not threaded
- use dlm_unlock/dlm_unlock_wait to unlock
-
-int dlm_lock_wait(
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- void *name,
- unsigned int namelen,
- uint32_t parent,
- void *bastarg,
- void (*bast) (void *bastarg),
- struct dlm_range *range);
-
-
-- asynchronous, any lockspace
- use dlm_ls_pthread_init/dlm_pthread_cleanup if app is threaded
- use dlm_ls_get_fd/dlm_dispatch if app is not threaded
- use dlm_create_lockspace/dlm_open_lockspace to start
- use dlm_release_lockspace/dlm_close_lockspace to finish
- use dlm_ls_unlock/dlm_ls_unlock_wait to unlock
-
-int dlm_ls_lock(
- dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*ast) (void *astarg),
- void *astarg,
- void (*bast) (void *astarg),
- struct dlm_range *range);
-
-
-- synchronous, any lockspace
- use dlm_ls_pthread_init/dlm_pthread_cleanup if app is threaded
- use dlm_ls_get_fd/dlm_dispatch if app is not threaded
- use dlm_create_lockspace/dlm_open_lockspace to start
- use dlm_release_lockspace/dlm_close_lockspace to finish
- use dlm_ls_unlock/dlm_ls_unlock_wait to unlock
-
-int dlm_ls_lock_wait(
- dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- void *name,
- unsigned int namelen,
- uint32_t parent,
- void *bastarg,
- void (*bast) (void *bastarg),
- struct dlm_range *range);
-
-
-
-Corresponding unlock requests
------------------------------
-
-int unlock_resource(
- uint32_t lkid);
-
-int dlm_unlock(
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb,
- void *astarg);
-
-int dlm_unlock_wait(
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb);
-
-int dlm_ls_unlock(
- dlm_lshandle_t lockspace,
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb,
- void *astarg);
-
-int dlm_ls_unlock_wait(
- dlm_lshandle_t lockspace,
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb);
-
-
-
-Common to all of the above
---------------------------
-
-#define DLM_RESNAME_MAXLEN (64)
-#define DLM_LVB_LEN (32)
-
-#define LKM_NLMODE 0 /* null lock */
-#define LKM_CRMODE 1 /* concurrent read */
-#define LKM_CWMODE 2 /* concurrent write */
-#define LKM_PRMODE 3 /* protected read */
-#define LKM_PWMODE 4 /* protected write */
-#define LKM_EXMODE 5 /* exclusive */
-
-#define LKF_NOQUEUE (0x00000001)
-#define LKF_CANCEL (0x00000002)
-#define LKF_CONVERT (0x00000004)
-#define LKF_VALBLK (0x00000008)
-#define LKF_QUECVT (0x00000010)
-#define LKF_IVVALBLK (0x00000020)
-#define LKF_CONVDEADLK (0x00000040)
-#define LKF_PERSISTENT (0x00000080)
-#define LKF_NODLCKWT (0x00000100)
-#define LKF_NODLCKBLK (0x00000200)
-#define LKF_EXPEDITE (0x00000400)
-#define LKF_NOQUEUEBAST (0x00000800)
-#define LKF_HEADQUE (0x00001000)
-#define LKF_NOORDER (0x00002000)
-
-#define ECANCEL (0x10001)
-#define EUNLOCK (0x10002)
-#define EINPROG (0x10003)
-
-struct dlm_lksb {
- int sb_status;
- uint32_t sb_lkid;
- char sb_flags;
- char *sb_lvbptr;
-};
-
-struct dlm_range {
- uint64_t ra_start;
- uint64_t ra_end;
-};
-
-
-
-
-Overview of administrative functions
-------------------------------------
-
-- dlm_pthread_init
-- dlm_ls_pthread_init
-- dlm_pthread_cleanup
-- dlm_get_fd
-- dlm_ls_get_fd
-- dlm_dispatch
-- dlm_create_lockspace
-- dlm_open_lockspace
-- dlm_release_lockspace
-- dlm_close_lockspace
-
-
-typedef void * dlm_lshandle_t;
-
-dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode);
-
-int dlm_release_lockspace(const char *name, dlm_lshandle_t ls, int force);
-
-dlm_lshandle_t dlm_open_lockspace(const char *name);
-
-int dlm_close_lockspace(dlm_lshandle_t ls);
-
-int dlm_pthread_init();
-
-int dlm_ls_pthread_init(dlm_lshandle_t lockspace);
-
-int dlm_pthread_cleanup();
-
-int dlm_get_fd();
-
-int dlm_ls_get_fd(dlm_lshandle_t ls);
-
-int dlm_dispatch(int fd);
-
-
-
-Query functions
----------------
-
-Query functions follow the same pattern as the lock and unlock functions.
-
-int dlm_query(
- struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo,
- void (*astaddr) (void *astarg),
- void *astarg);
-
-int dlm_query_wait(
- struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo);
-
-int dlm_ls_query(
- dlm_lshandle_t lockspace,
- struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo,
- void (*astaddr) (void *astarg),
- void *astarg);
-
-int dlm_ls_query_wait(
- dlm_lshandle_t lockspace,
- struct dlm_lksb *lksb,
- int query,
- struct dlm_queryinfo *qinfo);
-
-#define DLM_LOCK_THIS 0x0007
-#define DLM_QUERY_MODE_MASK 0x0007
-
-#define DLM_QUERY_QUEUE_WAIT 0x0008
-#define DLM_QUERY_QUEUE_CONVERT 0x0010
-#define DLM_QUERY_QUEUE_GRANT 0x0020
-#define DLM_QUERY_QUEUE_GRANTED 0x0030
-#define DLM_QUERY_QUEUE_ALL 0x0038
-
-#define DLM_QUERY_LOCKS_HIGHER 0x0100
-#define DLM_QUERY_LOCKS_LOWER 0x0200
-#define DLM_QUERY_LOCKS_EQUAL 0x0300
-#define DLM_QUERY_LOCKS_BLOCKING 0x0400
-#define DLM_QUERY_LOCKS_NOTBLOCK 0x0500
-#define DLM_QUERY_LOCKS_ALL 0x0600
-#define DLM_QUERY_MASK 0x0F00
-
-#define DLM_QUERY_GRMODE 0x0000
-#define DLM_QUERY_RQMODE 0x1000
-
-struct dlm_lockinfo {
- int lki_lkid;
- int lki_mstlkid;
- int lki_parent;
- int lki_node;
- int lki_ownpid;
- uint8_t lki_state;
- uint8_t lki_grmode;
- uint8_t lki_rqmode;
- struct dlm_range lki_grrange;
- struct dlm_range lki_rqrange;
-};
-
-struct dlm_resinfo {
- int rsi_length;
- int rsi_grantcount;
- int rsi_convcount;
- int rsi_waitcount;
- int rsi_masternode;
- char rsi_name[DLM_RESNAME_MAXLEN];
- char rsi_valblk[DLM_LVB_LEN];
-};
-
-struct dlm_queryinfo {
- struct dlm_resinfo *gqi_resinfo;
- struct dlm_lockinfo *gqi_lockinfo;
- int gqi_locksize;
- int gqi_lockcount;
-};
-
-
-
diff --git a/dlm/libdlm/51-dlm.rules b/dlm/libdlm/51-dlm.rules
deleted file mode 100644
index f71e79d..0000000
--- a/dlm/libdlm/51-dlm.rules
+++ /dev/null
@@ -1,5 +0,0 @@
-KERNEL=="dlm-control", NAME="misc/dlm-control", MODE="0666"
-KERNEL=="dlm-monitor", NAME="misc/dlm-monitor", MODE="0666"
-KERNEL=="dlm_default", NAME="misc/dlm_default", MODE="0666"
-KERNEL=="dlm_*", NAME="misc/%k", MODE="0660"
-
diff --git a/dlm/libdlm/Makefile b/dlm/libdlm/Makefile
deleted file mode 100644
index dfbfaa5..0000000
--- a/dlm/libdlm/Makefile
+++ /dev/null
@@ -1,81 +0,0 @@
-TARGET= libdlm
-
-LIBDIRT=$(TARGET).a \
- $(TARGET)_lt.a \
- $(TARGET).so.${SOMAJOR}.${SOMINOR} \
- $(TARGET)_lt.so.${SOMAJOR}.${SOMINOR}
-
-LIBSYMT=$(TARGET).so \
- $(TARGET)_lt.so \
- $(TARGET).so.$(SOMAJOR) \
- $(TARGET)_lt.so.$(SOMAJOR)
-
-INCDIRT=$(TARGET).h
-
-UDEVT=51-dlm.rules
-
-PKGCONF=$(TARGET).pc $(TARGET)_lt.pc
-
-include ../../make/defines.mk
-
-SHAREDLIB=$(TARGET).so.${SOMAJOR}.${SOMINOR} $(TARGET)_lt.so.${SOMAJOR}.${SOMINOR}
-STATICLIB=$(TARGET).a $(TARGET)_lt.a
-
-all: $(STATICLIB) $(SHAREDLIB) $(PKGCONF)
-
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-CFLAGS += -fPIC
-CFLAGS += -I$(S)
-CFLAGS += -I${incdir}
-CFLAGS += -I$(KERNEL_SRC)/include
-
-REENT_CFLAGS += -D_REENTRANT
-
-LDFLAGS += -L${libdir}
-
-PTHREAD_LDFLAGS += -lpthread
-
-$(TARGET).a: $(TARGET).o
- ${AR} cru $@ $^
- ${RANLIB} $@
-
-$(TARGET)_lt.a: $(TARGET)_lt.o
- ${AR} cru $@ $^
- ${RANLIB} $@
-
-$(TARGET).so.${SOMAJOR}.${SOMINOR}: $(TARGET).o
- $(CC) -shared -o $@ -Wl,-soname=$(TARGET).so.$(SOMAJOR) $< $(PTHREAD_LDFLAGS) $(LDFLAGS)
- ln -sf $(TARGET).so.$(SOMAJOR).$(SOMINOR) $(TARGET).so
- ln -sf $(TARGET).so.$(SOMAJOR).$(SOMINOR) $(TARGET).so.$(SOMAJOR)
-
-$(TARGET)_lt.so.${SOMAJOR}.${SOMINOR}: $(TARGET)_lt.o
- $(CC) -shared -o $@ -Wl,-soname=$(TARGET)_lt.so.$(SOMAJOR) $< $(LDFLAGS)
- ln -sf $(TARGET)_lt.so.$(SOMAJOR).$(SOMINOR) $(TARGET)_lt.so
- ln -sf $(TARGET)_lt.so.$(SOMAJOR).$(SOMINOR) $(TARGET)_lt.so.$(SOMAJOR)
-
-$(TARGET).pc: $(S)/$(TARGET).pc.in
- cat $(S)/$(TARGET).pc.in | \
- sed \
- -e 's#@PREFIX@#${prefix}#g' \
- -e 's#@LIBDIR@#${libdir}#g' \
- -e 's#@INCDIR@#${incdir}#g' \
- -e 's#@VERSION@#${RELEASE_VERSION}#g' \
- > $@
-
-$(TARGET)_lt.pc: $(S)/$(TARGET)_lt.pc.in
- cat $(S)/$(TARGET)_lt.pc.in | \
- sed \
- -e 's#@PREFIX@#${prefix}#g' \
- -e 's#@LIBDIR@#${libdir}#g' \
- -e 's#@INCDIR@#${incdir}#g' \
- -e 's#@VERSION@#${RELEASE_VERSION}#g' \
- > $@
-
-clean: generalclean
-
--include $(TARGET).d
--include $(TARGET)_lt.d
diff --git a/dlm/libdlm/libdlm.c b/dlm/libdlm/libdlm.c
deleted file mode 100644
index dadf1d2..0000000
--- a/dlm/libdlm/libdlm.c
+++ /dev/null
@@ -1,1485 +0,0 @@
-#ifdef _REENTRANT
-#include <pthread.h>
-#endif
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <linux/major.h>
-#ifdef HAVE_SELINUX
-#include <selinux/selinux.h>
-#endif
-#include <linux/types.h>
-#include <linux/dlm.h>
-#define BUILDING_LIBDLM
-#include "libdlm.h"
-#include <linux/dlm_device.h>
-
-#define MISC_PREFIX "/dev/misc/"
-#define DLM_PREFIX "dlm_"
-#define DLM_MISC_PREFIX MISC_PREFIX DLM_PREFIX
-#define DLM_CONTROL_NAME "dlm-control"
-#define DLM_CONTROL_PATH MISC_PREFIX DLM_CONTROL_NAME
-#define DEFAULT_LOCKSPACE "default"
-
-/*
- * V5 of the dlm_device.h kernel/user interface structs
- */
-
-struct dlm_lock_params_v5 {
- __u8 mode;
- __u8 namelen;
- __u16 flags;
- __u32 lkid;
- __u32 parent;
- void *castparam;
- void *castaddr;
- void *bastparam;
- void *bastaddr;
- struct dlm_lksb *lksb;
- char lvb[DLM_USER_LVB_LEN];
- char name[0];
-};
-
-struct dlm_write_request_v5 {
- __u32 version[3];
- __u8 cmd;
- __u8 is64bit;
- __u8 unused[2];
-
- union {
- struct dlm_lock_params_v5 lock;
- struct dlm_lspace_params lspace;
- } i;
-};
-
-struct dlm_lock_result_v5 {
- __u32 length;
- void *user_astaddr;
- void *user_astparam;
- struct dlm_lksb *user_lksb;
- struct dlm_lksb lksb;
- __u8 bast_mode;
- __u8 unused[3];
- /* Offsets may be zero if no data is present */
- __u32 lvb_offset;
-};
-
-
-/*
- * One of these per lockspace in use by the application
- */
-
-struct dlm_ls_info {
- int fd;
-#ifdef _REENTRANT
- pthread_t tid;
-#else
- int tid;
-#endif
-};
-
-/*
- * The default lockspace.
- * I've resisted putting locking around this as the user should be
- * "sensible" and only do lockspace operations either in the
- * main thread or ... carefully...
- */
-
-static struct dlm_ls_info *default_ls = NULL;
-static int control_fd = -1;
-static struct dlm_device_version kernel_version;
-static int kernel_version_detected = 0;
-
-
-static int release_lockspace(uint32_t minor, uint32_t flags);
-
-
-static void ls_dev_name(const char *lsname, char *devname, int devlen)
-{
- snprintf(devname, devlen, DLM_MISC_PREFIX "%s", lsname);
-}
-
-static void dummy_ast_routine(void *arg)
-{
-}
-
-#ifdef _REENTRANT
-/* Used for the synchronous and "simplified, synchronous" API routines */
-struct lock_wait
-{
- pthread_cond_t cond;
- pthread_mutex_t mutex;
- struct dlm_lksb lksb;
-};
-
-static void sync_ast_routine(void *arg)
-{
- struct lock_wait *lwait = arg;
-
- pthread_mutex_lock(&lwait->mutex);
- pthread_cond_signal(&lwait->cond);
- pthread_mutex_unlock(&lwait->mutex);
-}
-
-/* lock_resource & unlock_resource
- * are the simplified, synchronous API.
- * Aways uses the default lockspace.
- */
-int lock_resource(const char *resource, int mode, int flags, int *lockid)
-{
- int status;
- struct lock_wait lwait;
-
- if (default_ls == NULL)
- {
- if (dlm_pthread_init())
- {
- return -1;
- }
- }
-
- if (!lockid)
- {
- errno = EINVAL;
- return -1;
- }
-
- /* Conversions need the lockid in the LKSB */
- if (flags & LKF_CONVERT)
- lwait.lksb.sb_lkid = *lockid;
-
- pthread_cond_init(&lwait.cond, NULL);
- pthread_mutex_init(&lwait.mutex, NULL);
- pthread_mutex_lock(&lwait.mutex);
-
- status = dlm_lock(mode,
- &lwait.lksb,
- flags,
- resource,
- strlen(resource),
- 0,
- sync_ast_routine,
- &lwait,
- NULL,
- NULL);
- if (status)
- return status;
-
- /* Wait for it to complete */
- pthread_cond_wait(&lwait.cond, &lwait.mutex);
- pthread_mutex_unlock(&lwait.mutex);
-
- *lockid = lwait.lksb.sb_lkid;
-
- errno = lwait.lksb.sb_status;
- if (lwait.lksb.sb_status)
- return -1;
- else
- return 0;
-}
-
-
-int unlock_resource(int lockid)
-{
- int status;
- struct lock_wait lwait;
-
- if (default_ls == NULL)
- {
- errno = -ENOTCONN;
- return -1;
- }
-
- pthread_cond_init(&lwait.cond, NULL);
- pthread_mutex_init(&lwait.mutex, NULL);
- pthread_mutex_lock(&lwait.mutex);
-
- status = dlm_unlock(lockid, 0, &lwait.lksb, &lwait);
-
- if (status)
- return status;
-
- /* Wait for it to complete */
- pthread_cond_wait(&lwait.cond, &lwait.mutex);
- pthread_mutex_unlock(&lwait.mutex);
-
- errno = lwait.lksb.sb_status;
- if (lwait.lksb.sb_status != DLM_EUNLOCK)
- return -1;
- else
- return 0;
-}
-
-/* Tidy up threads after a lockspace is closed */
-static int ls_pthread_cleanup(struct dlm_ls_info *lsinfo)
-{
- int status = 0;
- int fd;
-
- /* Must close the fd after the thread has finished */
- fd = lsinfo->fd;
- if (lsinfo->tid)
- {
- status = pthread_cancel(lsinfo->tid);
- if (!status)
- pthread_join(lsinfo->tid, NULL);
- }
- if (!status)
- {
- free(lsinfo);
- close(fd);
- }
-
- return status;
-}
-
-/* Cleanup default lockspace */
-int dlm_pthread_cleanup(void)
-{
- struct dlm_ls_info *lsinfo = default_ls;
-
- /* Protect users from their own stupidity */
- if (!lsinfo)
- return 0;
-
- default_ls = NULL;
-
- return ls_pthread_cleanup(lsinfo);
-}
-#else
-
-/* Non-pthread version of cleanup */
-static int ls_pthread_cleanup(struct dlm_ls_info *lsinfo)
-{
- close(lsinfo->fd);
- free(lsinfo);
- return 0;
-}
-#endif
-
-
-static void set_version_v5(struct dlm_write_request_v5 *req)
-{
- req->version[0] = kernel_version.version[0];
- req->version[1] = kernel_version.version[1];
- req->version[2] = kernel_version.version[2];
- if (sizeof(long) == sizeof(long long))
- req->is64bit = 1;
- else
- req->is64bit = 0;
-}
-
-static void set_version_v6(struct dlm_write_request *req)
-{
- req->version[0] = kernel_version.version[0];
- req->version[1] = kernel_version.version[1];
- req->version[2] = kernel_version.version[2];
- if (sizeof(long) == sizeof(long long))
- req->is64bit = 1;
- else
- req->is64bit = 0;
-}
-
-static int open_default_lockspace(void)
-{
- if (!default_ls) {
- dlm_lshandle_t ls;
-
- /* This isn't the race it looks, create_lockspace will
- * do the right thing if the lockspace has already been
- * created.
- */
-
- ls = dlm_open_lockspace(DEFAULT_LOCKSPACE);
- if (!ls)
- ls = dlm_create_lockspace(DEFAULT_LOCKSPACE, 0600);
- if (!ls)
- return -1;
-
- default_ls = (struct dlm_ls_info *)ls;
- }
- return 0;
-}
-
-static void detect_kernel_version(void)
-{
- struct dlm_device_version v;
- int rv;
-
- rv = read(control_fd, &v, sizeof(struct dlm_device_version));
- if (rv < 0) {
- kernel_version.version[0] = 5;
- kernel_version.version[1] = 0;
- kernel_version.version[2] = 0;
- } else {
- kernel_version.version[0] = v.version[0];
- kernel_version.version[1] = v.version[1];
- kernel_version.version[2] = v.version[2];
- }
-
- kernel_version_detected = 1;
-}
-
-static int find_control_minor(int *minor)
-{
- FILE *f;
- char name[256];
- int found = 0, m = 0;
-
- f = fopen("/proc/misc", "r");
- if (!f)
- return -1;
-
- while (!feof(f)) {
- if (fscanf(f, "%d %s", &m, name) != 2)
- continue;
- if (strcmp(name, DLM_CONTROL_NAME))
- continue;
- found = 1;
- break;
- }
- fclose(f);
-
- if (found) {
- *minor = m;
- return 0;
- }
- return -1;
-}
-
-static int open_control_device(void)
-{
- struct stat st;
- int i, rv, minor, found = 0;
-
- if (control_fd > -1)
- goto out;
-
- rv = find_control_minor(&minor);
- if (rv < 0)
- return -1;
-
- /* wait for udev to create the device */
-
- for (i = 0; i < 10; i++) {
- if (stat(DLM_CONTROL_PATH, &st) == 0 &&
- minor(st.st_rdev) == minor) {
- found = 1;
- break;
- }
- sleep(1);
- continue;
- }
-
- if (!found)
- return -1;
-
- control_fd = open(DLM_CONTROL_PATH, O_RDWR);
- if (control_fd == -1)
- return -1;
-
- out:
- fcntl(control_fd, F_SETFD, 1);
-
- if (!kernel_version_detected)
- detect_kernel_version();
- return 0;
-}
-
-/* the max number of characters in a sysfs device name, not including \0 */
-#define MAX_SYSFS_NAME 19
-
-static int find_udev_device(const char *lockspace, int minor, char *udev_path)
-{
- char basename[PATH_MAX];
- char tmp_path[PATH_MAX];
- DIR *d;
- struct dirent *de;
- struct stat st;
- size_t basename_len;
- int i;
-
- ls_dev_name(lockspace, udev_path, PATH_MAX);
- snprintf(basename, PATH_MAX, DLM_PREFIX "%s", lockspace);
- basename_len = strlen(basename);
-
- for (i = 0; i < 10; i++) {
-
- /* look for a device with the full name */
-
- if (stat(udev_path, &st) == 0 && minor(st.st_rdev) == minor)
- return 0;
-
- if (basename_len < MAX_SYSFS_NAME) {
- sleep(1);
- continue;
- }
-
- /* look for a device with a truncated name */
-
- d = opendir(MISC_PREFIX);
- while ((de = readdir(d))) {
- if (de->d_name[0] == '.')
- continue;
- if (strlen(de->d_name) < MAX_SYSFS_NAME)
- continue;
- if (strncmp(de->d_name, basename, MAX_SYSFS_NAME))
- continue;
- snprintf(tmp_path, PATH_MAX, MISC_PREFIX "%s",
- de->d_name);
- if (stat(tmp_path, &st))
- continue;
- if (minor(st.st_rdev) != minor)
- continue;
-
- /* truncated name */
- strncpy(udev_path, tmp_path, PATH_MAX);
- closedir(d);
- return 0;
- }
- closedir(d);
- sleep(1);
- }
-
- return -1;
-}
-
-/*
- * do_dlm_dispatch()
- * Read an ast from the kernel.
- */
-
-static int do_dlm_dispatch_v5(int fd)
-{
- char resultbuf[sizeof(struct dlm_lock_result_v5) + DLM_USER_LVB_LEN];
- struct dlm_lock_result_v5 *result = (struct dlm_lock_result_v5 *)resultbuf;
- char *fullresult = NULL;
- int status;
- void (*astaddr)(void *astarg);
-
- status = read(fd, result, sizeof(resultbuf));
- if (status <= 0)
- return -1;
-
- /* This shouldn't happen any more, can probably be removed */
-
- if (result->length != status) {
- int newstat;
-
- fullresult = malloc(result->length);
- if (!fullresult)
- return -1;
-
- newstat = read(fd, (struct dlm_lock_result_v5 *)fullresult,
- result->length);
-
- /* If it read OK then use the new data. otherwise we can
- still deliver the AST, it just might not have all the
- info in it...hmmm */
-
- if (newstat == result->length)
- result = (struct dlm_lock_result_v5 *)fullresult;
- } else {
- fullresult = resultbuf;
- }
-
-
- /* Copy lksb to user's buffer - except the LVB ptr */
- memcpy(result->user_lksb, &result->lksb,
- sizeof(struct dlm_lksb) - sizeof(char*));
-
- /* Flip the status. Kernel space likes negative return codes,
- userspace positive ones */
- result->user_lksb->sb_status = -result->user_lksb->sb_status;
-
- /* Copy optional items */
- if (result->lvb_offset)
- memcpy(result->user_lksb->sb_lvbptr,
- fullresult + result->lvb_offset, DLM_LVB_LEN);
-
- /* Call AST */
- if (result->user_astaddr) {
- astaddr = result->user_astaddr;
- astaddr(result->user_astparam);
- }
-
- if (fullresult != resultbuf)
- free(fullresult);
-
- return 0;
-}
-
-static int do_dlm_dispatch_v6(int fd)
-{
- char resultbuf[sizeof(struct dlm_lock_result) + DLM_USER_LVB_LEN];
- struct dlm_lock_result *result = (struct dlm_lock_result *)resultbuf;
- int status;
- void (*astaddr)(void *astarg);
-
- status = read(fd, result, sizeof(resultbuf));
- if (status <= 0)
- return -1;
-
- /* Copy lksb to user's buffer - except the LVB ptr */
- memcpy(result->user_lksb, &result->lksb,
- sizeof(struct dlm_lksb) - sizeof(char*));
-
- /* Copy lvb to user's buffer */
- if (result->lvb_offset)
- memcpy(result->user_lksb->sb_lvbptr,
- (char *)result + result->lvb_offset, DLM_LVB_LEN);
-
- result->user_lksb->sb_status = -result->user_lksb->sb_status;
-
- if (result->user_astaddr) {
- astaddr = result->user_astaddr;
- astaddr(result->user_astparam);
- }
-
- return 0;
-}
-
-static int do_dlm_dispatch(int fd)
-{
- if (kernel_version.version[0] == 5)
- return do_dlm_dispatch_v5(fd);
- else
- return do_dlm_dispatch_v6(fd);
-}
-
-
-/*
- * sync_write()
- * Helper routine which supports the synchronous DLM calls. This
- * writes a parameter block down to the DLM and waits for the
- * operation to complete. This hides the different completion mechanism
- * used when called from the main thread or the DLM 'AST' thread.
- */
-
-#ifdef _REENTRANT
-
-static int sync_write_v5(struct dlm_ls_info *lsinfo,
- struct dlm_write_request_v5 *req, int len)
-{
- struct lock_wait lwait;
- int status;
-
- if (pthread_self() == lsinfo->tid) {
- /* This is the DLM worker thread, don't use lwait to sync */
- req->i.lock.castaddr = dummy_ast_routine;
- req->i.lock.castparam = NULL;
-
- status = write(lsinfo->fd, req, len);
- if (status < 0)
- return -1;
-
- while (req->i.lock.lksb->sb_status == EINPROG) {
- do_dlm_dispatch_v5(lsinfo->fd);
- }
- } else {
- pthread_cond_init(&lwait.cond, NULL);
- pthread_mutex_init(&lwait.mutex, NULL);
- pthread_mutex_lock(&lwait.mutex);
-
- req->i.lock.castaddr = sync_ast_routine;
- req->i.lock.castparam = &lwait;
-
- status = write(lsinfo->fd, req, len);
- if (status < 0)
- return -1;
-
- pthread_cond_wait(&lwait.cond, &lwait.mutex);
- pthread_mutex_unlock(&lwait.mutex);
- }
-
- return status; /* lock status is in the lksb */
-}
-
-static int sync_write_v6(struct dlm_ls_info *lsinfo,
- struct dlm_write_request *req, int len)
-{
- struct lock_wait lwait;
- int status;
-
- if (pthread_self() == lsinfo->tid) {
- /* This is the DLM worker thread, don't use lwait to sync */
- req->i.lock.castaddr = dummy_ast_routine;
- req->i.lock.castparam = NULL;
-
- status = write(lsinfo->fd, req, len);
- if (status < 0)
- return -1;
-
- while (req->i.lock.lksb->sb_status == EINPROG) {
- do_dlm_dispatch_v6(lsinfo->fd);
- }
- } else {
- pthread_cond_init(&lwait.cond, NULL);
- pthread_mutex_init(&lwait.mutex, NULL);
- pthread_mutex_lock(&lwait.mutex);
-
- req->i.lock.castaddr = sync_ast_routine;
- req->i.lock.castparam = &lwait;
-
- status = write(lsinfo->fd, req, len);
- if (status < 0)
- return -1;
-
- pthread_cond_wait(&lwait.cond, &lwait.mutex);
- pthread_mutex_unlock(&lwait.mutex);
- }
-
- return status; /* lock status is in the lksb */
-}
-
-#else /* _REENTRANT */
-
-static int sync_write_v5(struct dlm_ls_info *lsinfo,
- struct dlm_write_request_v5 *req, int len)
-{
- int status;
-
- req->i.lock.castaddr = dummy_ast_routine;
- req->i.lock.castparam = NULL;
-
- status = write(lsinfo->fd, req, len);
- if (status < 0)
- return -1;
-
- while (req->i.lock.lksb->sb_status == EINPROG) {
- do_dlm_dispatch_v5(lsinfo->fd);
- }
-
- errno = req->i.lock.lksb->sb_status;
- if (errno && errno != EUNLOCK)
- return -1;
- return 0;
-}
-
-static int sync_write_v6(struct dlm_ls_info *lsinfo,
- struct dlm_write_request *req, int len)
-{
- int status;
-
- req->i.lock.castaddr = dummy_ast_routine;
- req->i.lock.castparam = NULL;
-
- status = write(lsinfo->fd, req, len);
- if (status < 0)
- return -1;
-
- while (req->i.lock.lksb->sb_status == EINPROG) {
- do_dlm_dispatch_v6(lsinfo->fd);
- }
-
- errno = req->i.lock.lksb->sb_status;
- if (errno && errno != EUNLOCK)
- return -1;
- return 0;
-}
-
-#endif /* _REENTRANT */
-
-
-/*
- * Lock
- * All the ways to request/convert a lock
- */
-
-static int ls_lock_v5(dlm_lshandle_t ls,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg))
-{
- char parambuf[sizeof(struct dlm_write_request_v5) + DLM_RESNAME_MAXLEN];
- struct dlm_write_request_v5 *req = (struct dlm_write_request_v5 *)parambuf;
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
- int status;
- int len;
-
- memset(req, 0, sizeof(*req));
- set_version_v5(req);
-
- req->cmd = DLM_USER_LOCK;
- req->i.lock.mode = mode;
- req->i.lock.flags = (flags & ~LKF_WAIT);
- req->i.lock.lkid = lksb->sb_lkid;
- req->i.lock.parent = parent;
- req->i.lock.lksb = lksb;
- req->i.lock.castaddr = astaddr;
- req->i.lock.bastaddr = bastaddr;
- req->i.lock.castparam = astarg; /* same comp and blocking ast arg */
- req->i.lock.bastparam = astarg;
-
- if (flags & LKF_CONVERT) {
- req->i.lock.namelen = 0;
- } else {
- if (namelen > DLM_RESNAME_MAXLEN) {
- errno = EINVAL;
- return -1;
- }
- req->i.lock.namelen = namelen;
- memcpy(req->i.lock.name, name, namelen);
- }
-
- if (flags & LKF_VALBLK) {
- memcpy(req->i.lock.lvb, lksb->sb_lvbptr, DLM_LVB_LEN);
- }
-
- len = sizeof(struct dlm_write_request_v5) + namelen;
- lksb->sb_status = EINPROG;
-
- if (flags & LKF_WAIT)
- status = sync_write_v5(lsinfo, req, len);
- else
- status = write(lsinfo->fd, req, len);
-
- if (status < 0)
- return -1;
-
- /*
- * the lock id is the return value from the write on the device
- */
-
- if (status > 0)
- lksb->sb_lkid = status;
- return 0;
-}
-
-static int ls_lock_v6(dlm_lshandle_t ls,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- uint64_t *xid,
- uint64_t *timeout)
-{
- char parambuf[sizeof(struct dlm_write_request) + DLM_RESNAME_MAXLEN];
- struct dlm_write_request *req = (struct dlm_write_request *)parambuf;
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
- int status;
- int len;
-
- memset(req, 0, sizeof(*req));
- set_version_v6(req);
-
- req->cmd = DLM_USER_LOCK;
- req->i.lock.mode = mode;
- req->i.lock.flags = (flags & ~LKF_WAIT);
- req->i.lock.lkid = lksb->sb_lkid;
- req->i.lock.parent = parent;
- req->i.lock.lksb = lksb;
- req->i.lock.castaddr = astaddr;
- req->i.lock.bastaddr = bastaddr;
- req->i.lock.castparam = astarg; /* same comp and blocking ast arg */
- req->i.lock.bastparam = astarg;
-
- if (xid)
- req->i.lock.xid = *xid;
- if (timeout)
- req->i.lock.timeout = *timeout;
-
- if (flags & LKF_CONVERT) {
- req->i.lock.namelen = 0;
- } else {
- if (namelen > DLM_RESNAME_MAXLEN) {
- errno = EINVAL;
- return -1;
- }
- req->i.lock.namelen = namelen;
- memcpy(req->i.lock.name, name, namelen);
- }
-
- if (flags & LKF_VALBLK) {
- memcpy(req->i.lock.lvb, lksb->sb_lvbptr, DLM_LVB_LEN);
- }
-
- len = sizeof(struct dlm_write_request) + namelen;
- lksb->sb_status = EINPROG;
-
- if (flags & LKF_WAIT)
- status = sync_write_v6(lsinfo, req, len);
- else
- status = write(lsinfo->fd, req, len);
-
- if (status < 0)
- return -1;
-
- /*
- * the lock id is the return value from the write on the device
- */
-
- if (status > 0)
- lksb->sb_lkid = status;
- return 0;
-}
-
-static int ls_lock(dlm_lshandle_t ls,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- void *range)
-{
- /* no support for range locks */
- if (range) {
- errno = ENOSYS;
- return -1;
- }
-
- if (flags & LKF_VALBLK && !lksb->sb_lvbptr) {
- errno = EINVAL;
- return -1;
- }
-
- if (kernel_version.version[0] == 5)
- return ls_lock_v5(ls, mode, lksb, flags, name, namelen, parent,
- astaddr, astarg, bastaddr);
- else
- return ls_lock_v6(ls, mode, lksb, flags, name, namelen, parent,
- astaddr, astarg, bastaddr, NULL, NULL);
-}
-
-/*
- * Extended async locking in own lockspace
- */
-int dlm_ls_lockx(dlm_lshandle_t ls,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- uint64_t *xid,
- uint64_t *timeout)
-{
- if (kernel_version.version[0] < 6) {
- errno = ENOSYS;
- return -1;
- }
-
- return ls_lock_v6(ls, mode, lksb, flags, name, namelen, parent,
- astaddr, astarg, bastaddr, xid, timeout);
-}
-
-/*
- * Async locking in own lockspace
- */
-int dlm_ls_lock(dlm_lshandle_t ls,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- void *range)
-{
- return ls_lock(ls, mode, lksb, flags, name, namelen, parent,
- astaddr, astarg, bastaddr, range);
-}
-
-/*
- * Sync locking in own lockspace
- */
-int dlm_ls_lock_wait(dlm_lshandle_t ls,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void *bastarg,
- void (*bastaddr) (void *bastarg),
- void *range)
-{
- return ls_lock(ls, mode, lksb, flags | LKF_WAIT, name, namelen, parent,
- NULL, bastarg, bastaddr, range);
-}
-
-/*
- * Async locking in the default lockspace
- */
-int dlm_lock(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- void *range)
-{
- if (open_default_lockspace())
- return -1;
-
- return ls_lock(default_ls, mode, lksb, flags, name, namelen, parent,
- astaddr, astarg, bastaddr, range);
-}
-
-/*
- * Sync locking in the default lockspace
- */
-int dlm_lock_wait(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent,
- void *bastarg,
- void (*bastaddr) (void *bastarg),
- void *range)
-{
- if (open_default_lockspace())
- return -1;
-
- return ls_lock(default_ls, mode, lksb, flags | LKF_WAIT, name, namelen,
- parent, NULL, bastarg, bastaddr, range);
-}
-
-
-/*
- * Unlock
- * All the ways to unlock/cancel a lock
- */
-
-static int ls_unlock_v5(struct dlm_ls_info *lsinfo, uint32_t lkid,
- uint32_t flags, struct dlm_lksb *lksb, void *astarg)
-{
- struct dlm_write_request_v5 req;
-
- set_version_v5(&req);
- req.cmd = DLM_USER_UNLOCK;
- req.i.lock.lkid = lkid;
- req.i.lock.flags = (flags & ~LKF_WAIT);
- req.i.lock.lksb = lksb;
- req.i.lock.castparam = astarg;
- /* DLM_USER_UNLOCK will default to existing completion AST */
- req.i.lock.castaddr = 0;
- lksb->sb_status = EINPROG;
-
- if (flags & LKF_WAIT)
- return sync_write_v5(lsinfo, &req, sizeof(req));
- else
- return write(lsinfo->fd, &req, sizeof(req));
-}
-
-static int ls_unlock_v6(struct dlm_ls_info *lsinfo, uint32_t lkid,
- uint32_t flags, struct dlm_lksb *lksb, void *astarg)
-{
- struct dlm_write_request req;
-
- set_version_v6(&req);
- req.cmd = DLM_USER_UNLOCK;
- req.i.lock.lkid = lkid;
- req.i.lock.flags = (flags & ~LKF_WAIT);
- req.i.lock.lksb = lksb;
- req.i.lock.namelen = 0;
- req.i.lock.castparam = astarg;
- /* DLM_USER_UNLOCK will default to existing completion AST */
- req.i.lock.castaddr = 0;
- lksb->sb_status = EINPROG;
-
- if (flags & LKF_WAIT)
- return sync_write_v6(lsinfo, &req, sizeof(req));
- else
- return write(lsinfo->fd, &req, sizeof(req));
-}
-
-int dlm_ls_unlock(dlm_lshandle_t ls, uint32_t lkid, uint32_t flags,
- struct dlm_lksb *lksb, void *astarg)
-{
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
- int status;
-
- if (ls == NULL) {
- errno = ENOTCONN;
- return -1;
- }
-
- if (!lkid) {
- errno = EINVAL;
- return -1;
- }
-
- if (kernel_version.version[0] == 5)
- status = ls_unlock_v5(lsinfo, lkid, flags, lksb, astarg);
- else
- status = ls_unlock_v6(lsinfo, lkid, flags, lksb, astarg);
-
- if (status < 0)
- return -1;
- return 0;
-}
-
-int dlm_ls_unlock_wait(dlm_lshandle_t ls, uint32_t lkid, uint32_t flags,
- struct dlm_lksb *lksb)
-{
- return dlm_ls_unlock(ls, lkid, flags | LKF_WAIT, lksb, NULL);
-}
-
-int dlm_unlock_wait(uint32_t lkid, uint32_t flags, struct dlm_lksb *lksb)
-{
- return dlm_ls_unlock_wait(default_ls, lkid, flags | LKF_WAIT, lksb);
-}
-
-int dlm_unlock(uint32_t lkid, uint32_t flags, struct dlm_lksb *lksb,
- void *astarg)
-{
- return dlm_ls_unlock(default_ls, lkid, flags, lksb, astarg);
-}
-
-int dlm_ls_deadlock_cancel(dlm_lshandle_t ls, uint32_t lkid, uint32_t flags)
-{
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
- struct dlm_write_request req;
-
- if (kernel_version.version[0] < 6) {
- errno = ENOSYS;
- return -1;
- }
-
- if (ls == NULL) {
- errno = ENOTCONN;
- return -1;
- }
-
- if (!lkid) {
- errno = EINVAL;
- return -1;
- }
-
- set_version_v6(&req);
- req.cmd = DLM_USER_DEADLOCK;
- req.i.lock.lkid = lkid;
- req.i.lock.flags = flags;
-
- return write(lsinfo->fd, &req, sizeof(req));
-}
-
-
-/*
- * Purge
- * Clear away orphan locks
- */
-
-int dlm_ls_purge(dlm_lshandle_t ls, int nodeid, int pid)
-{
- struct dlm_write_request req;
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
- int status;
-
- if (kernel_version.version[0] < 6) {
- errno = ENOSYS;
- return -1;
- }
-
- if (ls == NULL) {
- errno = ENOTCONN;
- return -1;
- }
-
- set_version_v6(&req);
- req.cmd = DLM_USER_PURGE;
- req.i.purge.nodeid = nodeid;
- req.i.purge.pid = pid;
-
- status = write(lsinfo->fd, &req, sizeof(req));
-
- if (status < 0)
- return -1;
- return 0;
-}
-
-
-/* These two routines for for users that want to
- * do their own fd handling.
- * This allows a non-threaded app to use the DLM.
- */
-int dlm_get_fd(void)
-{
- if (default_ls)
- {
- return default_ls->fd;
- }
- else
- {
- if (open_default_lockspace())
- return -1;
- else
- return default_ls->fd;
- }
-}
-
-int dlm_dispatch(int fd)
-{
- int status;
- int fdflags;
-
- fdflags = fcntl(fd, F_GETFL, 0);
- fcntl(fd, F_SETFL, fdflags | O_NONBLOCK);
- do
- {
- status = do_dlm_dispatch(fd);
- } while (status == 0);
-
- /* EAGAIN is not an error */
- if (status < 0 && errno == EAGAIN)
- status = 0;
-
- fcntl(fd, F_SETFL, fdflags);
- return status;
-}
-
-/* Converts a lockspace handle into a file descriptor */
-int dlm_ls_get_fd(dlm_lshandle_t lockspace)
-{
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)lockspace;
-
- return lsinfo->fd;
-}
-
-#ifdef _REENTRANT
-static void *dlm_recv_thread(void *lsinfo)
-{
- struct dlm_ls_info *lsi = lsinfo;
-
- for (;;)
- do_dlm_dispatch(lsi->fd);
-
- return NULL;
-}
-
-/* Multi-threaded callers normally use this */
-int dlm_pthread_init(void)
-{
- if (open_default_lockspace())
- return -1;
-
- if (default_ls->tid)
- {
- errno = EEXIST;
- return -1;
- }
-
- if (pthread_create(&default_ls->tid, NULL, dlm_recv_thread, default_ls))
- {
- int saved_errno = errno;
- close(default_ls->fd);
- free(default_ls);
- default_ls = NULL;
- errno = saved_errno;
- return -1;
- }
- return 0;
-}
-
-/* And same, for those with their own lockspace */
-int dlm_ls_pthread_init(dlm_lshandle_t ls)
-{
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
-
- if (lsinfo->tid)
- {
- errno = EEXIST;
- return -1;
- }
-
- return pthread_create(&lsinfo->tid, NULL, dlm_recv_thread, (void *)ls);
-}
-#endif
-
-/*
- * Lockspace manipulation functions
- * Privileged users (checked by the kernel) can create/release lockspaces
- */
-
-static int create_lockspace_v5(const char *name, uint32_t flags)
-{
- char reqbuf[sizeof(struct dlm_write_request_v5) + DLM_LOCKSPACE_LEN];
- struct dlm_write_request_v5 *req = (struct dlm_write_request_v5 *)reqbuf;
- int namelen = strlen(name);
- int minor;
-
- memset(reqbuf, 0, sizeof(reqbuf));
- set_version_v5(req);
-
- req->cmd = DLM_USER_CREATE_LOCKSPACE;
- req->i.lspace.flags = flags;
-
- if (namelen > DLM_LOCKSPACE_LEN) {
- errno = EINVAL;
- return -1;
- }
- memcpy(req->i.lspace.name, name, namelen);
-
- minor = write(control_fd, req, sizeof(*req) + namelen);
-
- return minor;
-}
-
-static int create_lockspace_v6(const char *name, uint32_t flags)
-{
- char reqbuf[sizeof(struct dlm_write_request) + DLM_LOCKSPACE_LEN];
- struct dlm_write_request *req = (struct dlm_write_request *)reqbuf;
- int namelen = strlen(name);
- int minor;
-
- memset(reqbuf, 0, sizeof(reqbuf));
- set_version_v6(req);
-
- req->cmd = DLM_USER_CREATE_LOCKSPACE;
- req->i.lspace.flags = flags;
-
- if (namelen > DLM_LOCKSPACE_LEN) {
- errno = EINVAL;
- return -1;
- }
- memcpy(req->i.lspace.name, name, namelen);
-
- minor = write(control_fd, req, sizeof(*req) + namelen);
-
- return minor;
-}
-
-static dlm_lshandle_t create_lockspace(const char *name, mode_t mode,
- uint32_t flags)
-{
- char dev_path[PATH_MAX];
- char udev_path[PATH_MAX];
- struct dlm_ls_info *newls;
- int error, saved_errno, minor;
-
- /* We use the control device for creating lockspaces. */
- if (open_control_device())
- return NULL;
-
- newls = malloc(sizeof(struct dlm_ls_info));
- if (!newls)
- return NULL;
-
- ls_dev_name(name, dev_path, sizeof(dev_path));
-
- if (kernel_version.version[0] == 5)
- minor = create_lockspace_v5(name, flags);
- else
- minor = create_lockspace_v6(name, flags);
-
- if (minor < 0)
- goto fail;
-
- /* Wait for udev to create the device; the device it creates may
- have a truncated name due to the sysfs device name limit. */
-
- error = find_udev_device(name, minor, udev_path);
- if (error)
- goto fail;
-
- /* If the symlink already exists, find_udev_device() will return
- it and we'll skip this. */
-
- if (strcmp(dev_path, udev_path)) {
- error = symlink(udev_path, dev_path);
- if (error)
- goto fail;
- }
-
- /* Open it and return the struct as a handle */
-
- newls->fd = open(dev_path, O_RDWR);
- if (newls->fd == -1)
- goto fail;
- if (mode)
- fchmod(newls->fd, mode);
- newls->tid = 0;
- fcntl(newls->fd, F_SETFD, 1);
- return (dlm_lshandle_t)newls;
-
- fail:
- saved_errno = errno;
- free(newls);
- errno = saved_errno;
- return NULL;
-}
-
-dlm_lshandle_t dlm_new_lockspace(const char *name, mode_t mode, uint32_t flags)
-{
- return create_lockspace(name, mode, flags);
-}
-
-dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode)
-{
- return create_lockspace(name, mode, 0);
-}
-
-static int release_lockspace_v5(uint32_t minor, uint32_t flags)
-{
- struct dlm_write_request_v5 req;
-
- set_version_v5(&req);
- req.cmd = DLM_USER_REMOVE_LOCKSPACE;
- req.i.lspace.minor = minor;
- req.i.lspace.flags = flags;
-
- return write(control_fd, &req, sizeof(req));
-}
-
-static int release_lockspace_v6(uint32_t minor, uint32_t flags)
-{
- struct dlm_write_request req;
-
- set_version_v6(&req);
- req.cmd = DLM_USER_REMOVE_LOCKSPACE;
- req.i.lspace.minor = minor;
- req.i.lspace.flags = flags;
-
- return write(control_fd, &req, sizeof(req));
-}
-
-static int release_lockspace(uint32_t minor, uint32_t flags)
-{
- if (kernel_version.version[0] == 5)
- return release_lockspace_v5(minor, flags);
- else
- return release_lockspace_v6(minor, flags);
-}
-
-int dlm_release_lockspace(const char *name, dlm_lshandle_t ls, int force)
-{
- char dev_path[PATH_MAX];
- struct stat st;
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
- uint32_t flags = 0;
- int fd, is_symlink = 0;
-
- ls_dev_name(name, dev_path, sizeof(dev_path));
- if (!lstat(dev_path, &st) && S_ISLNK(st.st_mode))
- is_symlink = 1;
-
- /* We need the minor number */
- if (fstat(lsinfo->fd, &st))
- return -1;
-
- /* Close the lockspace first if it's in use */
- ls_pthread_cleanup(lsinfo);
-
- if (open_control_device())
- return -1;
-
- if (force)
- flags = DLM_USER_LSFLG_FORCEFREE;
-
- release_lockspace(minor(st.st_rdev), flags);
-
- if (!is_symlink)
- return 0;
-
- /* The following open is used to detect if our release was the last.
- It will fail if our release was the last, because either:
- . udev has already removed the truncated sysfs device name (ENOENT)
- . the misc device has been deregistered in the kernel (ENODEV)
- (the deregister completes before release returns)
-
- So, if the open fails, we know that our release was the last,
- udev will be removing the device with the truncated name (if it
- hasn't already), and we should remove the symlink. */
-
- fd = open(dev_path, O_RDWR);
- if (fd < 0)
- unlink(dev_path);
- else
- close(fd); /* our release was not the last */
-
- return 0;
-}
-
-/*
- * Normal users just open/close lockspaces
- */
-
-dlm_lshandle_t dlm_open_lockspace(const char *name)
-{
- char dev_name[PATH_MAX];
- struct dlm_ls_info *newls;
- int saved_errno;
-
- /* Need to detect kernel version */
- if (open_control_device())
- return NULL;
-
- newls = malloc(sizeof(struct dlm_ls_info));
- if (!newls)
- return NULL;
-
- newls->tid = 0;
- ls_dev_name(name, dev_name, sizeof(dev_name));
-
- newls->fd = open(dev_name, O_RDWR);
- saved_errno = errno;
-
- if (newls->fd == -1) {
- free(newls);
- errno = saved_errno;
- return NULL;
- }
- fcntl(newls->fd, F_SETFD, 1);
- return (dlm_lshandle_t)newls;
-}
-
-int dlm_close_lockspace(dlm_lshandle_t ls)
-{
- struct dlm_ls_info *lsinfo = (struct dlm_ls_info *)ls;
-
- ls_pthread_cleanup(lsinfo);
- return 0;
-}
-
-int dlm_kernel_version(uint32_t *major, uint32_t *minor, uint32_t *patch)
-{
- if (open_control_device())
- return -1;
- *major = kernel_version.version[0];
- *minor = kernel_version.version[1];
- *patch = kernel_version.version[2];
- return 0;
-}
-
-void dlm_library_version(uint32_t *major, uint32_t *minor, uint32_t *patch)
-{
- *major = DLM_DEVICE_VERSION_MAJOR;
- *minor = DLM_DEVICE_VERSION_MINOR;
- *patch = DLM_DEVICE_VERSION_PATCH;
-}
-
diff --git a/dlm/libdlm/libdlm.h b/dlm/libdlm/libdlm.h
deleted file mode 100644
index 17a552c..0000000
--- a/dlm/libdlm/libdlm.h
+++ /dev/null
@@ -1,275 +0,0 @@
-#ifndef __LIBDLM_H
-#define __LIBDLM_H
-
-/*
- * Typedefs for things that are compatible with the kernel but replicated here
- * so that users only need the libdlm include file. libdlm itself needs the
- * full kernel file so shouldn't use these.
- */
-
-#define DLM_LVB_LEN 32
-
-#ifndef BUILDING_LIBDLM
-
-/*
- * These two lengths are copied from linux/dlmconstants.h
- * They are the max length of a lockspace name and the max length of a
- * resource name.
- */
-
-#define DLM_LOCKSPACE_LEN 64
-#define DLM_RESNAME_MAXLEN 64
-
-struct dlm_lksb {
- int sb_status;
- uint32_t sb_lkid;
- char sb_flags;
- char *sb_lvbptr;
-};
-
-/* lksb flags */
-#define DLM_SBF_DEMOTED 0x01
-#define DLM_SBF_VALNOTVALID 0x02
-#define DLM_SBF_ALTMODE 0x04
-
-/* dlm_new_lockspace flags */
-#define DLM_LSFL_NODIR 0x00000001
-#define DLM_LSFL_TIMEWARN 0x00000002
-#define DLM_LSFL_FS 0x00000004
-#define DLM_LSFL_NEWEXCL 0x00000008
-
-#endif
-
-
-#if 0
-/* Dummy definition to keep linkages */
-struct dlm_queryinfo;
-#endif
-
-extern int dlm_kernel_version(uint32_t *maj, uint32_t *min, uint32_t *patch);
-extern void dlm_library_version(uint32_t *maj, uint32_t *min, uint32_t *patch);
-
-
-/*
- * Using the default lockspace
- *
- * lock_resource() - simple sync request or convert (requires pthreads)
- * unlock_resource() - simple sync unlock (requires pthreads)
- * dlm_lock() - async request or convert
- * dlm_unlock() - async unlock or cancel
- * dlm_lock_wait() - sync request or convert
- * dlm_unlock_wait() - sync unlock or cancel
- */
-
-#ifdef _REENTRANT
-extern int lock_resource(const char *resource, int mode, int flags, int *lockid);
-extern int unlock_resource(int lockid);
-#endif
-
-extern int dlm_lock(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unusued */
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- void *range); /* unused */
-
-extern int dlm_unlock(uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb,
- void *astarg);
-
-extern int dlm_lock_wait(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- void *bastarg,
- void (*bastaddr) (void *bastarg),
- void *range); /* unused */
-
-extern int dlm_unlock_wait(uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb);
-
-
-/*
- * These two are for users that want to do their own FD handling
- *
- * dlm_get_fd() - returns fd for the default lockspace for polling and dispatch
- * dlm_dispatch() - dispatches pending asts and basts
- */
-
-extern int dlm_get_fd(void);
-extern int dlm_dispatch(int fd);
-
-
-/*
- * Creating your own lockspace
- *
- * dlm_create_lockspace() - create and open a lockspace and return a handle
- * to it. Privileges are required to create/release.
- * dlm_new_lockspace() - same as create but allows flags
- * dlm_open_lockspace() - simply returns a handle for an existing lockspace and
- * may be called by ordinary users.
- * dlm_release_lockspace()
- * dlm_close_lockspace()
- * dlm_ls_get_fd()
- *
- * NOTE: that if you dlm_create_lockspace() then dlm_open_lockspace() you will
- * have two open files on the same device. Hardly a major problem but I thought
- * it worth pointing out.
- */
-
-typedef void *dlm_lshandle_t;
-
-extern dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode);
-extern int dlm_release_lockspace(const char *name, dlm_lshandle_t ls,
- int force);
-extern dlm_lshandle_t dlm_open_lockspace(const char *name);
-extern int dlm_close_lockspace(dlm_lshandle_t ls);
-extern int dlm_ls_get_fd(dlm_lshandle_t ls);
-extern dlm_lshandle_t dlm_new_lockspace(const char *name, mode_t mode,
- uint32_t flags);
-
-
-/*
- * Using your own lockspace
- *
- * dlm_ls_lock()
- * dlm_ls_lockx()
- * dlm_ls_unlock()
- * dlm_ls_lock_wait()
- * dlm_ls_unlock_wait()
- * dlm_ls_deadlock_cancel()
- * dlm_ls_purge()
- */
-
-extern int dlm_ls_lock(dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- void *range); /* unused */
-
-extern int dlm_ls_lockx(dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- uint64_t *xid,
- uint64_t *timeout);
-
-extern int dlm_ls_unlock(dlm_lshandle_t lockspace,
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb,
- void *astarg);
-
-extern int dlm_ls_lock_wait(dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- void *bastarg,
- void (*bastaddr) (void *bastarg),
- void *range); /* unused */
-
-extern int dlm_ls_unlock_wait(dlm_lshandle_t lockspace,
- uint32_t lkid,
- uint32_t flags,
- struct dlm_lksb *lksb);
-
-extern int dlm_ls_deadlock_cancel(dlm_lshandle_t ls,
- uint32_t lkid,
- uint32_t flags);
-
-extern int dlm_ls_purge(dlm_lshandle_t lockspace,
- int nodeid,
- int pid);
-
-
-/*
- * For threaded applications
- *
- * dlm_pthread_init()
- * dlm_ls_pthread_init() - call this before any locking operations and the ASTs
- * will be delivered in their own thread.
- * dlm_pthread_cleanup() - call the cleanup routine at application exit
- * (optional) or, if the locking functions are in a
- * shared library that is to be unloaded.
- *
- * dlm_close/release_lockspace() will tidy the threads for a non-default
- * lockspace
- */
-
-#ifdef _REENTRANT
-extern int dlm_pthread_init(void);
-extern int dlm_ls_pthread_init(dlm_lshandle_t lockspace);
-extern int dlm_pthread_cleanup(void);
-#endif
-
-
-/*
- * Lock modes
- */
-
-#define LKM_NLMODE 0 /* null lock */
-#define LKM_CRMODE 1 /* concurrent read */
-#define LKM_CWMODE 2 /* concurrent write */
-#define LKM_PRMODE 3 /* protected read */
-#define LKM_PWMODE 4 /* protected write */
-#define LKM_EXMODE 5 /* exclusive */
-
-
-/*
- * Locking flags - these match the ones in dlm.h
- */
-
-#define LKF_NOQUEUE 0x00000001
-#define LKF_CANCEL 0x00000002
-#define LKF_CONVERT 0x00000004
-#define LKF_VALBLK 0x00000008
-#define LKF_QUECVT 0x00000010
-#define LKF_IVVALBLK 0x00000020
-#define LKF_CONVDEADLK 0x00000040
-#define LKF_PERSISTENT 0x00000080
-#define LKF_NODLCKWT 0x00000100
-#define LKF_NODLCKBLK 0x00000200
-#define LKF_EXPEDITE 0x00000400
-#define LKF_NOQUEUEBAST 0x00000800
-#define LKF_HEADQUE 0x00001000
-#define LKF_NOORDER 0x00002000
-#define LKF_ORPHAN 0x00004000
-#define LKF_ALTPR 0x00008000
-#define LKF_ALTCW 0x00010000
-#define LKF_FORCEUNLOCK 0x00020000
-#define LKF_TIMEOUT 0x00040000
-#define LKF_WAIT 0x80000000 /* Userspace only, for sync API calls */
-
-/*
- * Extra return codes used by the DLM
- */
-
-#define ECANCEL 0x10001
-#define EUNLOCK 0x10002
-#define EINPROG 0x10003 /* lock operation is in progress */
-
-#endif
-
diff --git a/dlm/libdlm/libdlm.pc.in b/dlm/libdlm/libdlm.pc.in
deleted file mode 100644
index afd3a34..0000000
--- a/dlm/libdlm/libdlm.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: libdlm
-Version: @VERSION@
-Description: Cluster Distributed Lock Manager library
-Requires:
-Libs: -L${libdir} -ldlm -lpthread
-Cflags: -I${includedir}
diff --git a/dlm/libdlm/libdlm_internal.h b/dlm/libdlm/libdlm_internal.h
deleted file mode 100644
index c8b270e..0000000
--- a/dlm/libdlm/libdlm_internal.h
+++ /dev/null
@@ -1,9 +0,0 @@
-
-/* Needed before we include the kernel libdlm header */
-#define __user
-typedef uint8_t __u8;
-typedef uint16_t __u16;
-typedef uint32_t __u32;
-#define BUILDING_LIBDLM
-
-
diff --git a/dlm/libdlm/libdlm_lt.pc.in b/dlm/libdlm/libdlm_lt.pc.in
deleted file mode 100644
index d116715..0000000
--- a/dlm/libdlm/libdlm_lt.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: libdlm_lt
-Version: @VERSION@
-Description: Cluster Distributed Lock Manager non-threaded library
-Requires:
-Libs: -L${libdir} -ldlm_lt
-Cflags: -I${includedir}
diff --git a/dlm/libdlmcontrol/Makefile b/dlm/libdlmcontrol/Makefile
deleted file mode 100644
index e2c320c..0000000
--- a/dlm/libdlmcontrol/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-TARGET= libdlmcontrol
-
-OBJS= main.o
-
-SOMINOR=1
-
-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$(S)/../../group/dlm_controld
-CFLAGS += -I${incdir}
-CFLAGS += -I$(KERNEL_SRC)/include
diff --git a/dlm/libdlmcontrol/libdlmcontrol.h b/dlm/libdlmcontrol/libdlmcontrol.h
deleted file mode 100644
index 64a3814..0000000
--- a/dlm/libdlmcontrol/libdlmcontrol.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef _LIBDLMCONTROL_H_
-#define _LIBDLMCONTROL_H_
-
-#define DLMC_DUMP_SIZE (1024 * 1024)
-
-#define DLMC_NF_MEMBER 0x00000001 /* node is member in cg */
-#define DLMC_NF_START 0x00000002 /* start message recvd for cg */
-#define DLMC_NF_DISALLOWED 0x00000004 /* node disallowed in cg */
-#define DLMC_NF_CHECK_FENCING 0x00000008
-#define DLMC_NF_CHECK_QUORUM 0x00000010
-#define DLMC_NF_CHECK_FS 0x00000020
-
-struct dlmc_node {
- int nodeid;
- uint32_t flags;
- uint32_t added_seq;
- uint32_t removed_seq;
- int failed_reason;
-};
-
-struct dlmc_change {
- int member_count;
- int joined_count;
- int remove_count;
- int failed_count;
- int wait_condition; /* 0 no, 1 fencing, 2 quorum, 3 fs */
- int wait_messages; /* 0 no, 1 yes */
- uint32_t seq;
- uint32_t combined_seq;
-};
-
-#define DLMC_LF_JOINING 0x00000001
-#define DLMC_LF_LEAVING 0x00000002
-#define DLMC_LF_KERNEL_STOPPED 0x00000004
-#define DLMC_LF_FS_REGISTERED 0x00000008
-#define DLMC_LF_NEED_PLOCKS 0x00000010
-#define DLMC_LF_SAVE_PLOCKS 0x00000020
-
-struct dlmc_lockspace {
- int group_mode;
- struct dlmc_change cg_prev; /* completed change (started_change) */
- struct dlmc_change cg_next; /* in-progress change (changes list) */
- uint32_t flags;
- uint32_t global_id;
- char name[DLM_LOCKSPACE_LEN+1];
-};
-
-/* dlmc_lockspace_nodes() types
-
- MEMBERS: members in completed (prev) change,
- zero if there's no completed (prev) change
- NEXT: members in in-progress (next) change,
- zero if there's no in-progress (next) change
- ALL: NEXT + nonmembers if there's an in-progress (next) change,
- MEMBERS + nonmembers if there's no in-progress (next) change, but
- there is a completed (prev) change
- nonmembers if there's no in-progress (next) or completed (prev)
- change (possible?)
-
- dlmc_node_info() returns info for in-progress (next) change, if one exists,
- otherwise it returns info for completed (prev) change.
-*/
-
-#define DLMC_NODES_ALL 1
-#define DLMC_NODES_MEMBERS 2
-#define DLMC_NODES_NEXT 3
-
-int dlmc_dump_debug(char *buf);
-int dlmc_dump_log_plock(char *buf);
-int dlmc_dump_plocks(char *name, char *buf);
-int dlmc_lockspace_info(char *lsname, struct dlmc_lockspace *ls);
-int dlmc_node_info(char *lsname, int nodeid, struct dlmc_node *node);
-int dlmc_lockspaces(int max, int *count, struct dlmc_lockspace *lss);
-int dlmc_lockspace_nodes(char *lsname, int type, int max, int *count,
- struct dlmc_node *nodes);
-
-#define DLMC_RESULT_REGISTER 1
-#define DLMC_RESULT_NOTIFIED 2
-
-int dlmc_fs_connect(void);
-void dlmc_fs_disconnect(int fd);
-int dlmc_fs_register(int fd, char *name);
-int dlmc_fs_unregister(int fd, char *name);
-int dlmc_fs_notified(int fd, char *name, int nodeid);
-int dlmc_fs_result(int fd, char *name, int *type, int *nodeid, int *result);
-
-int dlmc_deadlock_check(char *name);
-
-#endif
-
diff --git a/dlm/libdlmcontrol/libdlmcontrol.pc.in b/dlm/libdlmcontrol/libdlmcontrol.pc.in
deleted file mode 100644
index db7dfa9..0000000
--- a/dlm/libdlmcontrol/libdlmcontrol.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@PREFIX@
-exec_prefix=${prefix}
-libdir=@LIBDIR@
-includedir=@INCDIR@
-
-Name: libdlmcontrol
-Version: @VERSION@
-Description: DLM control library
-Requires:
-Libs: -L${libdir} -ldlmcontrol
-Cflags: -I${includedir}
diff --git a/dlm/libdlmcontrol/main.c b/dlm/libdlmcontrol/main.c
deleted file mode 100644
index 5a203a1..0000000
--- a/dlm/libdlmcontrol/main.c
+++ /dev/null
@@ -1,419 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <linux/dlmconstants.h>
-#include "dlm_controld.h"
-#include "libdlmcontrol.h"
-
-static int do_read(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- while (off < count) {
- rv = read(fd, (char *)buf + off, count - off);
- if (rv == 0)
- return -1;
- if (rv == -1 && errno == EINTR)
- continue;
- if (rv == -1)
- return -1;
- off += rv;
- }
- return 0;
-}
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, (char *)buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0) {
- return rv;
- }
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-static int do_connect(const char *sock_path)
-{
- struct sockaddr_un sun;
- socklen_t addrlen;
- int rv, fd;
-
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (fd < 0)
- goto out;
-
- memset(&sun, 0, sizeof(sun));
- sun.sun_family = AF_UNIX;
- strcpy(&sun.sun_path[1], sock_path);
- addrlen = sizeof(sa_family_t) + strlen(sun.sun_path+1) + 1;
-
- rv = connect(fd, (struct sockaddr *) &sun, addrlen);
- if (rv < 0) {
- close(fd);
- fd = rv;
- }
- out:
- return fd;
-}
-
-static void init_header(struct dlmc_header *h, int cmd, char *name,
- int extra_len)
-{
- memset(h, 0, sizeof(struct dlmc_header));
-
- h->magic = DLMC_MAGIC;
- h->version = DLMC_VERSION;
- h->len = sizeof(struct dlmc_header) + extra_len;
- h->command = cmd;
-
- if (name)
- strncpy(h->name, name, DLM_LOCKSPACE_LEN);
-}
-
-static int do_dump(int cmd, char *name, char *buf)
-{
- struct dlmc_header h, *rh;
- char *reply;
- int reply_len;
- int fd, rv;
-
- init_header(&h, cmd, name, 0);
-
- reply_len = sizeof(struct dlmc_header) + DLMC_DUMP_SIZE;
- reply = malloc(reply_len);
- if (!reply) {
- rv = -1;
- goto out;
- }
- memset(reply, 0, reply_len);
-
- fd = do_connect(DLMC_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- /* won't always get back the full reply_len */
- do_read(fd, reply, reply_len);
-
- rh = (struct dlmc_header *)reply;
- rv = rh->data;
- if (rv < 0)
- goto out_close;
-
- memcpy(buf, (char *)reply + sizeof(struct dlmc_header),
- DLMC_DUMP_SIZE);
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int dlmc_dump_debug(char *buf)
-{
- return do_dump(DLMC_CMD_DUMP_DEBUG, NULL, buf);
-}
-
-int dlmc_dump_log_plock(char *buf)
-{
- return do_dump(DLMC_CMD_DUMP_LOG_PLOCK, NULL, buf);
-}
-
-int dlmc_dump_plocks(char *name, char *buf)
-{
- return do_dump(DLMC_CMD_DUMP_PLOCKS, name, buf);
-}
-
-int dlmc_node_info(char *name, int nodeid, struct dlmc_node *node)
-{
- struct dlmc_header h, *rh;
- char reply[sizeof(struct dlmc_header) + sizeof(struct dlmc_node)];
- int fd, rv;
-
- init_header(&h, DLMC_CMD_NODE_INFO, name, 0);
- h.data = nodeid;
-
- memset(reply, 0, sizeof(reply));
-
- fd = do_connect(DLMC_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- rv = do_read(fd, reply, sizeof(reply));
- if (rv < 0)
- goto out_close;
-
- rh = (struct dlmc_header *)reply;
- rv = rh->data;
- if (rv < 0)
- goto out_close;
-
- memcpy(node, (char *)reply + sizeof(struct dlmc_header),
- sizeof(struct dlmc_node));
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int dlmc_lockspace_info(char *name, struct dlmc_lockspace *lockspace)
-{
- struct dlmc_header h, *rh;
- char reply[sizeof(struct dlmc_header) + sizeof(struct dlmc_lockspace)];
- int fd, rv;
-
- init_header(&h, DLMC_CMD_LOCKSPACE_INFO, name, 0);
-
- memset(reply, 0, sizeof(reply));
-
- fd = do_connect(DLMC_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- rv = do_read(fd, reply, sizeof(reply));
- if (rv < 0)
- goto out_close;
-
- rh = (struct dlmc_header *)reply;
- rv = rh->data;
- if (rv < 0)
- goto out_close;
-
- memcpy(lockspace, (char *)reply + sizeof(struct dlmc_header),
- sizeof(struct dlmc_lockspace));
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int dlmc_lockspaces(int max, int *count, struct dlmc_lockspace *lss)
-{
- struct dlmc_header h, *rh;
- char *reply;
- int reply_len;
- int fd, rv, result, ls_count;
-
- init_header(&h, DLMC_CMD_LOCKSPACES, NULL, 0);
- h.data = max;
-
- reply_len = sizeof(struct dlmc_header) +
- (max * sizeof(struct dlmc_lockspace));
- reply = malloc(reply_len);
- if (!reply) {
- rv = -1;
- goto out;
- }
- memset(reply, 0, reply_len);
-
- fd = do_connect(DLMC_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- /* won't usually get back the full reply_len */
- do_read(fd, reply, reply_len);
-
- rh = (struct dlmc_header *)reply;
- result = rh->data;
- if (result < 0 && result != -E2BIG) {
- rv = result;
- goto out_close;
- }
-
- if (result == -E2BIG) {
- *count = -E2BIG;
- ls_count = max;
- } else {
- *count = result;
- ls_count = result;
- }
- rv = 0;
-
- memcpy(lss, (char *)reply + sizeof(struct dlmc_header),
- ls_count * sizeof(struct dlmc_lockspace));
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int dlmc_lockspace_nodes(char *name, int type, int max, int *count,
- struct dlmc_node *nodes)
-{
- struct dlmc_header h, *rh;
- char *reply;
- int reply_len;
- int fd, rv, result, node_count;
-
- init_header(&h, DLMC_CMD_LOCKSPACE_NODES, name, 0);
- h.option = type;
- h.data = max;
-
- reply_len = sizeof(struct dlmc_header) +
- (max * sizeof(struct dlmc_node));
- reply = malloc(reply_len);
- if (!reply) {
- rv = -1;
- goto out;
- }
- memset(reply, 0, reply_len);
-
- fd = do_connect(DLMC_QUERY_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- if (rv < 0)
- goto out_close;
-
- /* won't usually get back the full reply_len */
- do_read(fd, reply, reply_len);
-
- rh = (struct dlmc_header *)reply;
- result = rh->data;
- if (result < 0 && result != -E2BIG) {
- rv = result;
- goto out_close;
- }
-
- if (result == -E2BIG) {
- *count = -E2BIG;
- node_count = max;
- } else {
- *count = result;
- node_count = result;
- }
- rv = 0;
-
- memcpy(nodes, (char *)reply + sizeof(struct dlmc_header),
- node_count * sizeof(struct dlmc_node));
- out_close:
- close(fd);
- out:
- return rv;
-}
-
-int dlmc_fs_connect(void)
-{
- return do_connect(DLMC_SOCK_PATH);
-}
-
-void dlmc_fs_disconnect(int fd)
-{
- close(fd);
-}
-
-int dlmc_fs_register(int fd, char *name)
-{
- struct dlmc_header h;
-
- init_header(&h, DLMC_CMD_FS_REGISTER, name, 0);
-
- return do_write(fd, &h, sizeof(h));
-}
-
-int dlmc_fs_unregister(int fd, char *name)
-{
- struct dlmc_header h;
-
- init_header(&h, DLMC_CMD_FS_UNREGISTER, name, 0);
-
- return do_write(fd, &h, sizeof(h));
-}
-
-int dlmc_fs_notified(int fd, char *name, int nodeid)
-{
- struct dlmc_header h;
-
- init_header(&h, DLMC_CMD_FS_NOTIFIED, name, 0);
- h.data = nodeid;
-
- return do_write(fd, &h, sizeof(h));
-}
-
-int dlmc_fs_result(int fd, char *name, int *type, int *nodeid, int *result)
-{
- struct dlmc_header h;
- int rv;
-
- rv = do_read(fd, &h, sizeof(h));
- if (rv < 0)
- goto out;
-
- strncpy(name, h.name, DLM_LOCKSPACE_LEN);
- *nodeid = h.option;
- *result = h.data;
-
- switch (h.command) {
- case DLMC_CMD_FS_REGISTER:
- *type = DLMC_RESULT_REGISTER;
- break;
- case DLMC_CMD_FS_NOTIFIED:
- *type = DLMC_RESULT_NOTIFIED;
- break;
- default:
- *type = 0;
- }
- out:
- return rv;
-}
-
-int dlmc_deadlock_check(char *name)
-{
- struct dlmc_header h;
- int fd, rv;
-
- init_header(&h, DLMC_CMD_DEADLOCK_CHECK, name, 0);
-
- fd = do_connect(DLMC_SOCK_PATH);
- if (fd < 0) {
- rv = fd;
- goto out;
- }
-
- rv = do_write(fd, &h, sizeof(h));
- close(fd);
- out:
- return rv;
-}
-
diff --git a/dlm/man/Makefile b/dlm/man/Makefile
deleted file mode 100644
index 7cc2886..0000000
--- a/dlm/man/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-MANTARGET= \
- dlm_cleanup.3 \
- dlm_close_lockspace.3 \
- dlm_create_lockspace.3 \
- dlm_dispatch.3 \
- dlm_get_fd.3 \
- dlm_lock.3 \
- dlm_lock_wait.3 \
- dlm_ls_lock.3 \
- dlm_ls_lockx.3 \
- dlm_ls_lock_wait.3 \
- dlm_ls_pthread_init.3 \
- dlm_ls_unlock.3 \
- dlm_ls_unlock_wait.3 \
- dlm_new_lockspace.3 \
- dlm_open_lockspace.3 \
- dlm_pthread_init.3 \
- dlm_release_lockspace.3 \
- dlm_unlock.3 \
- dlm_unlock_wait.3 \
- libdlm.3 \
- dlm_tool.8
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-all:
-
-clean:
diff --git a/dlm/man/dlm_cleanup.3 b/dlm/man/dlm_cleanup.3
deleted file mode 100644
index db4a9cf..0000000
--- a/dlm/man/dlm_cleanup.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/libdlm.3
diff --git a/dlm/man/dlm_close_lockspace.3 b/dlm/man/dlm_close_lockspace.3
deleted file mode 100644
index e5db408..0000000
--- a/dlm/man/dlm_close_lockspace.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_create_lockspace.3
diff --git a/dlm/man/dlm_create_lockspace.3 b/dlm/man/dlm_create_lockspace.3
deleted file mode 100644
index 3879e85..0000000
--- a/dlm/man/dlm_create_lockspace.3
+++ /dev/null
@@ -1,94 +0,0 @@
-.TH DLM_CREATE_LOCKSPACE 3 "July 5, 2007" "libdlm functions"
-.SH NAME
-dlm_create_lockspace, dlm_open_lockspace, dlm_close_lockspace, dlm_release_lockspace \- manipulate DLM lockspaces
-.SH SYNOPSIS
-.nf
- #include <libdlm.h>
-
-dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode);
-dlm_lshandle_t dlm_new_lockspace(const char *name, mode_t mode,
- uint32_t flags);
-dlm_lshandle_t dlm_open_lockspace(const char *name);
-int dlm_close_lockspace(dlm_lshandle_t ls);
-int dlm_release_lockspace(const char *name, dlm_lshandle_t ls,
- int force);
-
-.fi
-.SH DESCRIPTION
-The DLM allows locks to be partitioned into "lockspaces", and these can be manipulated by userspace calls. It is possible (though not recommended) for an application to have multiple lockspaces open at one time.
-
-Many of the DLM calls work on the "default" lockspace, which should be fine for most users. The calls with _ls_ in them allow you to isolate your application from all others running in the cluster. Remember, lockspaces are a cluster-wide resource, so if you create a lockspace called "myls" it will share locks with a lockspace called "myls" on all nodes. These calls allow users to create & remove lockspaces, and users to connect to existing lockspace to store their locks there.
-.PP
-.SS
-dlm_lshandle_t dlm_create_lockspace(const char *name, mode_t mode);
-.br
-This creates a lockspace called <name> and the mode of the file user to access it will be <mode> (subject to umask as usual). The lockspace must not already exist on this node, if it does -1 will be returned and errno will be set to EEXIST. If you really want to use this lockspace you can then use dlm_open_lockspace() below. The name is the name of a misc device that will be created in /dev/misc.
-.br
-On success a handle to the lockspace is returned, which can be used to pass into subsequent dlm_ls_lock/unlock calls. Make no assumptions as to the content of this handle as it's content may change in future.
-.br
-The caller must have CAP_SYSADMIN privileges to do this operation.
-.PP
-Return codes:
-0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following:
-.nf
-EINVAL An invalid parameter was passed to the call
-ENOMEM A (kernel) memory allocation failed
-EEXIST The lockspace already exists
-EPERM Process does not have capability to create lockspaces
-ENOSYS A fatal error occurred initializing the DLM
-Any error returned by the open() system call
-.fi
-.SS
-int dlm_new_lockspace(const char *name, mode_t mode, uint32_t flags)
-.PP
-Performs the same function as
-.B dlm_create_lockspace()
-above, but passes some creation flags to the call that affect the lockspace being created. Currently supported flags are:
-.nf
-DLM_LSFL_NODIR the lockspace should not use a resource directory
-DLM_LSFL_TIMEWARN the dlm should emit warnings over netlink when locks
- have been waiting too long; required for deadlock
- detection
-.fi
-.SS
-int dlm_release_lockspace(const char *name, dlm_lshandle_t ls, int force)
-.PP
-Deletes a lockspace. If the lockspace still has active locks then -1 will be returned and errno set to EBUSY. Both the lockspace handle /and/ the name must be specified. This call also closes the lockspace and stops the thread associated with the lockspace, if any.
-.br
-Note that other nodes in the cluster may still have locks open on this lockspace. This call only removes the lockspace from the current node. If the force flag is set then the lockspace will be removed even if another user on this node has active locks in it. Existing users will NOT be notified if you do this, so be careful.
-.br
-The caller must have CAP_SYSADMIN privileges to do this operation.
-.PP
-Return codes:
-0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following:
-.nf
-EINVAL An invalid parameter was passed to the call
-EPERM Process does not have capability to release lockspaces
-EBUSY The lockspace could not be freed because it still
- contains locks and force was not set.
-.fi
-
-.SS
-dlm_lshandle_t dlm_open_lockspace(const char *name)
-.PP
-Opens an already existing lockspace and returns a handle to it.
-.PP
-Return codes:
-0 is returned if the call completed successfully. If not, -1 is returned and errno is set to an error returned by the open() system call
-.SS
-int dlm_close_lockspace(dlm_lshandle_t ls)
-.br
-Close the lockspace. Any locks held by this process will be freed. If a thread is associated with this lockspace then it will be stopped.
-.PP
-Return codes:
-0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following:
-.nf
-EINVAL lockspace was not a valid lockspace handle
-.fi
-
-
-.SH SEE ALSO
-
-.BR libdlm (3),
-.BR dlm_unlock (3),
-.BR dlm_lock (3),
diff --git a/dlm/man/dlm_dispatch.3 b/dlm/man/dlm_dispatch.3
deleted file mode 100644
index db4a9cf..0000000
--- a/dlm/man/dlm_dispatch.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/libdlm.3
diff --git a/dlm/man/dlm_get_fd.3 b/dlm/man/dlm_get_fd.3
deleted file mode 100644
index db4a9cf..0000000
--- a/dlm/man/dlm_get_fd.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/libdlm.3
diff --git a/dlm/man/dlm_lock.3 b/dlm/man/dlm_lock.3
deleted file mode 100644
index 3c5f8b5..0000000
--- a/dlm/man/dlm_lock.3
+++ /dev/null
@@ -1,239 +0,0 @@
-.TH DLM_LOCK 3 "July 5, 2007" "libdlm functions"
-.SH NAME
-dlm_lock \- acquire or convert a DLM lock
-.SH SYNOPSIS
-.nf
- #include <libdlm.h>
-
-int dlm_lock(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- void *range); /* unused */
-
-int dlm_lock_wait(uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- void *bastarg,
- void (*bastaddr) (void *bastarg),
- void *range); /* unused */
-
-int dlm_ls_lock(dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- void (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- void *range); /* unused */
-
-int dlm_ls_lock_wait(dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unusued */
- void *bastarg,
- void (*bastaddr) (void *bastarg),
- void *range); /* unused */
-
-int dlm_ls_lockx(dlm_lshandle_t lockspace,
- uint32_t mode,
- struct dlm_lksb *lksb,
- uint32_t flags,
- const void *name,
- unsigned int namelen,
- uint32_t parent, /* unused */
- (*astaddr) (void *astarg),
- void *astarg,
- void (*bastaddr) (void *astarg),
- uint64_t *xid,
- uint64_t *timeout);
-
-
-
-.fi
-.SH DESCRIPTION
-dlm_lock and its variants acquire and convert locks in the DLM.
-.PP
-dlm_lock() operations are asynchronous. If the call to dlm_lock returns an error then the operation has failed and the AST routine will not be called. If dlm_lock returns 0 it is still possible that the lock operation will fail. The AST routine will be called when the locking is complete or has failed and the status is returned in the lksb.
-.B dlm_lock_wait()
-will wait until the lock operation has completed and returns the final completion status.
-.B dlm_ls_lock()
-is the same as
-.B dlm_lock()
-but takes a lockspace argument. This lockspace must have been previously opened by
-.B dlm_lockspace_open() or
-.B dlm_lockspace_create().
-.PP
-For conversion operations the name and namelen are ignored and the lock ID in the LKSB is used to identify the lock to be converted.
-.PP
-If a lock value block is specified then in general, a grant or a conversion to an equal-level or higher-level lock mode reads the lock value from the resource into the caller's lock value block. When a lock conversion from EX or PW to an equal-level or lower-level lock mode occurs, the contents of the caller's lock value block are written into the resource. If the LVB is invalidated the lksb.sb_flags member will be set to DLM_SBF_VALNOTVALID. Lock values blocks are always 32 bytes long.
-.PP
-If the AST routines or parameter are passed to a conversion operation then they will overwrite those values that were passed to a previous dlm_lock call.
-.PP
-.B mode
-Lock mode to acquire or convert to.
-.nf
- LKM_NLMODE NULL Lock
- LKM_CRMODE Concurrent read
- LKM_CWMODE Concurrent write
- LKM_PRMODE Protected read
- LKM_PWMODE Protected write
- LKM_EXMODE Exclusive
-.fi
-.PP
-.B flags
-Affect the operation of the lock call:
-.nf
- LKF_NOQUEUE Don't queue the lock. If it cannot be granted return
- -EAGAIN
- LKF_CONVERT Convert an existing lock
- LKF_VALBLK Lock has a value block
- LKF_QUECVT Put conversion to the back of the queue
- LKF_EXPEDITE Grant a NL lock immediately regardless of other locks
- on the conversion queue
- LKF_PERSISTENT Specifies a lock that will not be unlocked when the
- process exits; it will become an orphan lock.
- LKF_CONVDEADLK Enable internal conversion deadlock resolution where
- the lock's granted mode may be set to NL and
- DLM_SBF_DEMOTED is returned in lksb.sb_flags.
- LKF_NODLCKWT Do not consider this lock when trying to detect
- deadlock conditions.
- LKF_NODLCKBLK Not implemented
- LKF_NOQUEUEBAST Send blocking ASTs even for NOQUEUE operations
- LKF_HEADQUE Add locks to the head of the convert or waiting queue
- LKF_NOORDER Avoid the VMS rules on grant order
- LKF_ALTPR If the requested mode can't be granted (generally CW),
- try to grant in PR and return DLM_SBF_ALTMODE.
- LKF_ALTCW If the requested mode can't be granted (generally PR),
- try to grant in CW and return DLM_SBF_ALTMODE.
- LKF_TIMEOUT The lock will time out per the timeout arg.
-
-.fi
-.PP
-.B lksb
-Lock Status block
-.br
-This structure contains the returned lock ID, the actual
-status of the lock operation (all lock ops are asynchronous)
-and the value block if LKF_VALBLK is set.
-.PP
-.B name
-.br
-Name of the lock. Can be binary, max 64 bytes. Ignored for lock
-conversions. (Should be a string to work with debugging tools.)
-.PP
-.B namelen
-.br
-Length of the above name. Ignored for lock conversions.
-.PP
-.B parent
-.br
-ID of parent lock or NULL if this is a top-level lock. This is currently unused.
-.PP
-.B ast
-.br
-Address of AST routine to be called when the lock operation
-completes. The final completion status of the lock will be
-in the lksb. the AST routine must not be NULL.
-.PP
-.B astargs
-.br
-Argument to pass to the AST routine (most people pass the lksb
-in here but it can be anything you like.)
-.PP
-.B bast
-.br
-Blocking AST routine. address of a function to call if this
-lock is blocking another. The function will be called with
-astargs.
-.PP
-.B range
-.br
-This is unused.
-.PP
-.B xid
-.br
-Optional transaction ID for deadlock detection.
-.PP
-.B timeout
-.br
-Timeout in centiseconds. If it takes longer than this to acquire the lock
-(usually because it is already blocked by another lock), then the AST
-will trigger with ETIMEDOUT as the status. If the lock operation is a conversion
-then the lock will remain at its current status. If this is a new lock then
-the lock will not exist and any LKB in the lksb will be invalid. This is
-ignored without the LKF_TIMEOUT flag.
-.PP
-.SS Return values
-0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following:
-.PP
-.nf
-EINVAL An invalid parameter was passed to the call (eg bad lock
- mode or flag)
-ENOMEM A (kernel) memory allocation failed
-EAGAIN LKF_NOQUEUE was requested and the lock could not be
- granted
-EBUSY The lock is currently being locked or converted
-EFAULT The userland buffer could not be read/written by the
- kernel (this indicates a library problem)
-EDEADLOCK The lock operation is causing a deadlock and has been
- cancelled. If this was a conversion then the lock is
- reverted to its previously granted state. If it was a
- new lock then it has not been granted. (NB Only
- conversion deadlocks are currently detected)
-.PP
-If an error is returned in the AST, then lksb.sb_status is set to the one of the above values instead of zero.
-.SS Structures
-.nf
-struct dlm_lksb {
- int sb_status; /* Final status of lock operation */
- uint32_t sb_lkid; /* ID of lock. Returned from dlm_lock()
- on first use. Used as input to
- dlm_lock() for a conversion operation */
- char sb_flags; /* Completion flags, see above */
- char sb_lvbptr; /* Optional pointer to lock value block */
-};
-
-.fi
-.SH EXAMPLE
-.nf
-int status;
-struct dlm_lksb lksb;
-
-status = dlm_lock_wait(LKM_EXMODE,
- &lksb,
- LKF_NOQUEUE,
- "MyLock",
- strlen("MyLock"),
- 0, // Parent,
- NULL, // bast arg
- NULL, // bast routine,
- NULL); // Range
-
-if (status == 0)
- dlm_unlock_wait(lksb.sb_lkid, 0, &lksb);
-
-.fi
-
-.SH SEE ALSO
-
-.BR libdlm (3),
-.BR dlm_unlock (3),
-.BR dlm_open_lockspace (3),
-.BR dlm_create_lockspace (3),
-.BR dlm_close_lockspace (3),
-.BR dlm_release_lockspace (3)
diff --git a/dlm/man/dlm_lock_wait.3 b/dlm/man/dlm_lock_wait.3
deleted file mode 100644
index a99225c..0000000
--- a/dlm/man/dlm_lock_wait.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_lock.3
diff --git a/dlm/man/dlm_ls_lock.3 b/dlm/man/dlm_ls_lock.3
deleted file mode 100644
index a99225c..0000000
--- a/dlm/man/dlm_ls_lock.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_lock.3
diff --git a/dlm/man/dlm_ls_lock_wait.3 b/dlm/man/dlm_ls_lock_wait.3
deleted file mode 100644
index a99225c..0000000
--- a/dlm/man/dlm_ls_lock_wait.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_lock.3
diff --git a/dlm/man/dlm_ls_lockx.3 b/dlm/man/dlm_ls_lockx.3
deleted file mode 100644
index a99225c..0000000
--- a/dlm/man/dlm_ls_lockx.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_lock.3
diff --git a/dlm/man/dlm_ls_pthread_init.3 b/dlm/man/dlm_ls_pthread_init.3
deleted file mode 100644
index db4a9cf..0000000
--- a/dlm/man/dlm_ls_pthread_init.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/libdlm.3
diff --git a/dlm/man/dlm_ls_unlock.3 b/dlm/man/dlm_ls_unlock.3
deleted file mode 100644
index 91babd2..0000000
--- a/dlm/man/dlm_ls_unlock.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_unlock.3
diff --git a/dlm/man/dlm_ls_unlock_wait.3 b/dlm/man/dlm_ls_unlock_wait.3
deleted file mode 100644
index 91babd2..0000000
--- a/dlm/man/dlm_ls_unlock_wait.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_unlock.3
diff --git a/dlm/man/dlm_new_lockspace.3 b/dlm/man/dlm_new_lockspace.3
deleted file mode 100644
index e5db408..0000000
--- a/dlm/man/dlm_new_lockspace.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_create_lockspace.3
diff --git a/dlm/man/dlm_open_lockspace.3 b/dlm/man/dlm_open_lockspace.3
deleted file mode 100644
index e5db408..0000000
--- a/dlm/man/dlm_open_lockspace.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_create_lockspace.3
diff --git a/dlm/man/dlm_pthread_init.3 b/dlm/man/dlm_pthread_init.3
deleted file mode 100644
index db4a9cf..0000000
--- a/dlm/man/dlm_pthread_init.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/libdlm.3
diff --git a/dlm/man/dlm_release_lockspace.3 b/dlm/man/dlm_release_lockspace.3
deleted file mode 100644
index e5db408..0000000
--- a/dlm/man/dlm_release_lockspace.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_create_lockspace.3
diff --git a/dlm/man/dlm_tool.8 b/dlm/man/dlm_tool.8
deleted file mode 100644
index df9aa64..0000000
--- a/dlm/man/dlm_tool.8
+++ /dev/null
@@ -1,98 +0,0 @@
-.TH DLM_TOOL 8 2009-01-20 cluster cluster
-
-.SH NAME
-dlm_tool \- a utility for the dlm and dlm_controld daemon
-
-.SH SYNOPSIS
-.B dlm_tool
-[COMMAND] [OPTIONS]
-[
-.I name
-]
-
-.SH DESCRIPTION
-.TP
-.B ls
-Display internal dlm_controld state about lockspaces.
-
-.TP
-.B dump
-Dump dlm_controld debug buffer.
-
-.TP
-.B log_plock
-Dump dlm_controld plock debug buffer.
-
-.TP
-.BI plocks " name"
-Dump posix locks from dlm_controld for the lockspace.
-
-.TP
-.BI lockdump " name"
-Minimal display of locks from the lockspace.
-
-.TP
-.BI lockdebug " name"
-Extended display of locks from the lockspace.
-
-.TP
-.BI join " name"
-Join a lockspace.
-
-.TP
-.BI leave " name"
-Leave a lockspace.
-
-.TP
-.BI deadlock_check " name"
-Start a deadlock detection cycle for the lockspace.
-
-.SH OPTIONS
-.TP
-.B \-n
-Show all node information in ls.
-
-.TP
-.BI \-d " num"
-Resource directory enabled (1) or disabled (0) during join. Default 0.
-
-.TP
-.BI \-e " num"
-Exclusive create off/on (0/1) in join. Default 0.
-
-.TP
-.BI \-f " num"
-FS memory allocation off/on (0/1) in join. Default 0.
-
-.TP
-.BI \-m " mode"
-The permission mode (in octal) of the lockspace device created by join.
-Default 0600.
-
-.TP
-.B \-M
-Dump MSTCPY locks in addition to locks held by local processes.
-
-.TP
-.B \-s
-Summary following lockdebug output (experimental, format may change).
-
-.TP
-.B \-v
-Verbose lockdebug output.
-
-.TP
-.B \-w
-Wide lockdebug output.
-
-.TP
-.B \-h
-Print a help message describing available options, then exit.
-
-.TP
-.B \-V
-Print program version information, then exit.
-
-.SH SEE ALSO
-.BR dlm_controld (8)
-
diff --git a/dlm/man/dlm_unlock.3 b/dlm/man/dlm_unlock.3
deleted file mode 100644
index 9023139..0000000
--- a/dlm/man/dlm_unlock.3
+++ /dev/null
@@ -1,94 +0,0 @@
-.TH DLM_UNLOCK 3 "July 5, 2007" "libdlm functions"
-.SH NAME
-dlm_unlock \- unlock a DLM lock
-.SH SYNOPSIS
-.nf
-#include <libdlm.h>
-
-int dlm_unlock(uint32_t lkid,
- uint32_t flags, struct dlm_lksb *lksb, void *astarg);
-
-int dlm_unlock_wait(uint32_t lkid,
- uint32_t flags, struct dlm_lksb *lksb);
-
-.fi
-.SH DESCRIPTION
-.B dlm_unlock()
-unlocks a lock previously acquired by dlm_lock and its variants.
-.PP
-Unless
-.B dlm_unlock_wait()
-is used unlocks are also asynchronous. The AST routine is called when the resource is successfully unlocked (see below).
-.PP
-.B lkid
-Lock ID as returned in the lksb
-.PP
-.B flags
-flags affecting the unlock operation:
-.nf
- LKF_CANCEL Cancel a pending lock or conversion.
- This returns the lock to it's previously
- granted mode (in case of a conversion) or
- unlocks it (in case of a waiting lock).
- LKF_IVVALBLK Invalidate value block
- LKF_FORCEUNLOCK Unlock the lock even if it's waiting.
-.fi
-.PP
-.B lksb
-LKSB to return status and value block information.
-.PP
-.B astarg
-New parameter to be passed to the completion AST.
-The completion AST routine is the
-last completion AST routine specified in a dlm_lock call.
-If dlm_lock_wait() was the last routine to issue a lock,
-dlm_unlock_wait() must be used to release the lock. If dlm_lock()
-was the last routine to issue a lock then either dlm_unlock()
-or dlm_unlock_wait() may be called.
-.PP
-
-.SS Return values
-0 is returned if the call completed successfully. If not, -1 is returned and errno is set to one of the following:
-.PP
-.nf
-EINVAL An invalid parameter was passed to the call (eg bad
- lock mode or flag)
-EINPROGRESS The lock is already being unlocked
-EBUSY The lock is currently being locked or converted
-ENOTEMPTY An attempt to made to unlock a parent lock that still has
- child locks.
-ECANCEL A lock conversion was successfully cancelled
-EUNLOCK An unlock operation completed successfully
- (sb_status only)
-EFAULT The userland buffer could not be read/written by the
- kernel
-.fi
-If an error is returned in the AST, then lksb.sb_status is set to the one of the above numbers instead of zero.
-.SH EXAMPLE
-.nf
-int status;
-struct dlm_lksb lksb;
-
-status = dlm_lock_wait(LKM_EXMODE,
- &lksb,
- LKF_NOQUEUE,
- "MyLock",
- strlen("MyLock"),
- 0, // Parent,
- NULL, // bast arg
- NULL, // bast routine,
- NULL); // Range
-
-if (status == 0)
- dlm_unlock_wait(lksb.sb_lkid, 0, &lksb);
-
-.fi
-
-.SH SEE ALSO
-
-.BR libdlm (3),
-.BR dlm_lock (3),
-.BR dlm_open_lockspace (3),
-.BR dlm_create_lockspace (3),
-.BR dlm_close_lockspace (3),
-.BR dlm_release_lockspace (3)
diff --git a/dlm/man/dlm_unlock_wait.3 b/dlm/man/dlm_unlock_wait.3
deleted file mode 100644
index 91babd2..0000000
--- a/dlm/man/dlm_unlock_wait.3
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/dlm_unlock.3
diff --git a/dlm/man/libdlm.3 b/dlm/man/libdlm.3
deleted file mode 100644
index a020560..0000000
--- a/dlm/man/libdlm.3
+++ /dev/null
@@ -1,105 +0,0 @@
-.TH LIBDLM 3 "July 5, 2007" "libdlm functions"
-.SH NAME
-libdlm \- dlm_get_fd, dlm_dispatch, dlm_pthread_init, dlm_ls_pthread_init, dlm_cleanup
-.SH SYNOPSIS
-.nf
-#include <libdlm.h>
-.nf
-int dlm_pthread_init();
-int dlm_ls_pthread_init(dlm_lshandle_t lockspace);
-int dlm_pthread_cleanup();
-int dlm_get_fd(void);
-int dlm_dispatch(int fd);
-
-link with -ldlm
-.fi
-.SH DESCRIPTION
-libdlm provides the programmatic userspace interface to the Distributed Lock manager. It provides all the calls you need to manipulate locks & lockspaces
-.br
-libdlm can be used in pthread or non-pthread applications. For pthread applications simply call the following function before doing any lock operations. If you're using pthreads, remember to define _REENTRANT at the top of the program or using -D_REENTRANT on the compile line.
-.br
-pthreads is the normal way of using the DLM. This way you simply initialize the DLM's thread and all the AST routines will be delivered in that thread. You just call the dlm_lock() etc routines in the main line of your program.
-.br
-If you don't want to use pthreads or you want to handle the dlm callback ASTs yourself then you can get an FD handle to the DLM device and call
-.B dlm_dispatch()
-on it whenever it becomes active. That was ASTs will be delivered in the context of the thread/process that called
-.B dlm_dispatch().
-
-
-.SS int dlm_pthread_init()
-.br
-Creates a thread to receive all lock ASTs. The AST callback function for lock operations will be called in the context of this thread. If there is a potential for local resource access conflicts you must provide your own pthread-based locking in the AST routine.
-.PP
-.SS int dlm_ls_pthread_init(dlm_lshandle_t lockspace)
-.br
-As dlm_pthread_init but initializes a thread for the specified lockspace.
-.PP
-.SS int dlm_pthread_cleanup()
-.br
-Cleans up the default lockspace threads after use. Normally you don't need to call this, but if the locking code is in a dynamically loadable shared library this will probably be necessary.
-.br
-For non-pthread based applications the DLM provides a file descriptor that the program can feed into poll/select. If activity is detected on that FD then a dispatch function should be called:
-.PP
-.SS int dlm_get_fd()
-Returns a file-descriptor for the DLM suitable for passing in to poll() or select().
-.PP
-.SS int dlm_dispatch(int fd)
-.br
-Reads from the DLM and calls any AST routines that may be needed. This routine runs in the context of the caller so no extra locking is needed to protect local resources.
-.PP
-
-
-.SH libdlm_lt
-There also exists a "light" version of the libdlm library called libdlm_lt. This is provided for those applications that do not want to use pthread functions. If you use this library it is important that your application is NOT compiled with -D_REENTRANT or linked with libpthread.
-
-.SH EXAMPLES
-
-Create a lockspace and start a thread to deliver its callbacks:
-.nf
-dlm_lshandle_t ls;
-
-ls = dlm_create_lockspace("myLS", 0660);
-dlm_ls_pthread_init(ls);
-
- ...
-
-status = dlm_ls_lock(ls,
- ... );
-
-
-.fi
-.PP
- Using poll(2) to wait for and dispatch ASTs
-.nf
-
-
-static int poll_for_ast(dlm_lshandle_t ls)
-{
- struct pollfd pfd;
-
- pfd.fd = dlm_ls_get_fd(ls);
- pfd.events = POLLIN;
- while (!ast_called)
- {
- if (poll(&pfd, 1, 0) < 0)
- {
- perror("poll");
- return -1;
- }
- dlm_dispatch(dlm_ls_get_fd(ls));
- }
- ast_called = 0;
- return 0;
-}
-.fi
-
-
-.SH SEE ALSO
-
-.BR libdlm (3),
-.BR dlm_lock (3),
-.BR dlm_unlock (3),
-.BR dlm_open_lockspace (3),
-.BR dlm_create_lockspace (3),
-.BR dlm_close_lockspace (3),
-.BR dlm_release_lockspace (3)
diff --git a/dlm/tests/Makefile b/dlm/tests/Makefile
deleted file mode 100644
index 28685d2..0000000
--- a/dlm/tests/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS=usertest
diff --git a/dlm/tests/usertest/Makefile b/dlm/tests/usertest/Makefile
deleted file mode 100644
index 5e070f7..0000000
--- a/dlm/tests/usertest/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-TARGETS= dlmtest asttest lstest pingtest lvb \
- dlmtest2 flood alternate-lvb joinleave threads
-
-all: depends ${TARGETS}
-
-include ../../../make/defines.mk
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-
-CFLAGS += -D_REENTRANT
-CFLAGS += -I${dlmincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${dlmlibdir} -ldlm -lpthread
-LDFLAGS += -L${libdir}
-
-depends:
- $(MAKE) -C ../../libdlm all
-
-%: %.o
- $(CC) -o $@ $^ $(LDFLAGS)
-
-clean: generalclean
diff --git a/dlm/tests/usertest/alternate-lvb.c b/dlm/tests/usertest/alternate-lvb.c
deleted file mode 100644
index 80c3ef6..0000000
--- a/dlm/tests/usertest/alternate-lvb.c
+++ /dev/null
@@ -1,165 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/time.h>
-#include <syslog.h>
-#include <asm/types.h>
-#include <sys/socket.h>
-#include <sys/poll.h>
-#include <sys/un.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/errno.h>
-
-#include "libdlm.h"
-
-#define die(fmt, args...) \
-do \
-{ \
- fprintf(stderr, "%s: ", prog_name); \
- fprintf(stderr, fmt, ##args); \
- exit(EXIT_FAILURE); \
-} \
-while (0)
-
-static char *prog_name;
-static dlm_lshandle_t *dh;
-static int verbose;
-
-static struct dlm_lksb lksb;
-static char lvb[32];
-
-int main(int argc, char *argv[])
-{
- unsigned long long offset;
- unsigned long long num, last_num = 0;
- unsigned int id, clients, sleeptime = 0;
- unsigned long long skip = 0;
- char *name;
- int rv;
-
- prog_name = argv[0];
- verbose = 0;
-
- if (argc < 5)
- die("name offset id clients [sleep]\n");
-
- name = argv[1];
- offset = atoll(argv[2]);
- id = atoi(argv[3]);
- clients = atoi(argv[4]);
-
- if (argc > 5)
- sleeptime = atoi(argv[5]);
-
- printf("Joining \"alternate\" lockspace...\n");
-
- dh = dlm_create_lockspace("alternate", 0600);
- if (!dh) {
- printf("dlm_create_lockspace error %p %d\n",dh, errno);
- return -ENOTCONN;
- }
-
- rv = dlm_ls_pthread_init(dh);
- if (rv < 0) {
- printf("dlm_ls_pthread_init error %d %d\n", rv, errno);
- dlm_release_lockspace("alternate", dh, 1);
- return rv;
- }
-
- memset(&lksb, 0, sizeof(lksb));
- memset(&lvb, 0, sizeof(lvb));
- lksb.sb_lvbptr = lvb;
-
- if (verbose)
- printf("request NL\n");
-
- rv = dlm_ls_lock_wait(dh, LKM_NLMODE, &lksb, LKF_VALBLK,
- name, strlen(name), 0, NULL, NULL, NULL);
-
- while (1) {
- if (verbose)
- printf("convert NL->PR\n");
-
- rv = dlm_ls_lock_wait(dh, LKM_PRMODE, &lksb,
- LKF_VALBLK | LKF_CONVERT,
- name, strlen(name),
- 0, NULL, NULL, NULL);
- if (rv)
- printf("lock1 error: %d %d\n", rv, lksb.sb_status);
-
- memcpy(&num, &lvb, sizeof(num));
-
- if (verbose)
- printf("read lvb %llu\n", num);
-
- /* it's our turn */
- if (num % clients == id) {
- if (last_num && last_num + clients != num + 1)
- die("bad: num %llu last_num %llu\n",
- num, last_num);
-
- if (verbose)
- printf("convert PR->EX\n");
-
- rv = dlm_ls_lock_wait(dh, LKM_EXMODE, &lksb,
- LKF_VALBLK | LKF_CONVERT,
- name, strlen(name),
- 0, NULL, NULL, NULL);
- if (rv)
- printf("lock2 error: %d %d\n", rv,
- lksb.sb_status);
-
- memcpy(&num, &lvb, sizeof(num));
- if (num % clients != id)
- die("bad2: num %llu\n", num);
-
- num++;
-
- memcpy(&lvb, &num, sizeof(num));
- printf("%llu %llu\n", num, skip);
-
- if (verbose)
- printf("convert EX->NL\n");
-
- rv = dlm_ls_lock_wait(dh, LKM_NLMODE, &lksb,
- LKF_VALBLK | LKF_CONVERT,
- name, strlen(name),
- 0, NULL, NULL, NULL);
- if (rv)
- printf("lock3 error: %d %d\n", rv,
- lksb.sb_status);
-
- last_num = num;
- skip = 0;
- } else {
- skip++;
-
- if (verbose)
- printf("convert PR->NL, skip %llu\n", skip);
-
- rv = dlm_ls_lock_wait(dh, LKM_NLMODE, &lksb,
- LKF_VALBLK | LKF_CONVERT,
- name, strlen(name),
- 0, NULL, NULL, NULL);
- if (rv)
- printf("lock4 error: %d %d\n", rv,
- lksb.sb_status);
- }
-
- if (sleeptime)
- usleep(sleeptime);
- }
-
- dlm_ls_unlock_wait(dh, lksb.sb_lkid, 0, &lksb);
- dlm_release_lockspace("alternate", dh, 1);
-
- exit(EXIT_SUCCESS);
-}
-
diff --git a/dlm/tests/usertest/asttest.c b/dlm/tests/usertest/asttest.c
deleted file mode 100644
index 224df4c..0000000
--- a/dlm/tests/usertest/asttest.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* Test program for userland DLM interface w/ AST */
-/* NOTE: This is not much of a program and it fails in all
- sorts of ways. But it /does/ illustrate the full dlm_lock
- call and ASTs. It doesn /not/ show how you should use the
- FD parts fo the API!
-*/
-
-#ifdef _REENTRANT
-#include <pthread.h>
-#endif
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/poll.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <unistd.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "libdlm.h"
-
-static struct dlm_lksb lksb;
-static int use_threads = 0;
-static int quiet = 0;
-
-/* Used by the pthread test */
-static pthread_cond_t cond;
-static pthread_mutex_t mutex;
-
-/* Used by the poll() test */
-static int ast_called = 0;
-
-static int modetonum(char *modestr)
-{
- int mode = LKM_EXMODE;
-
- if (strncasecmp(modestr, "NL", 2) == 0) mode = LKM_NLMODE;
- if (strncasecmp(modestr, "CR", 2) == 0) mode = LKM_CRMODE;
- if (strncasecmp(modestr, "CW", 2) == 0) mode = LKM_CWMODE;
- if (strncasecmp(modestr, "PR", 2) == 0) mode = LKM_PRMODE;
- if (strncasecmp(modestr, "PW", 2) == 0) mode = LKM_PWMODE;
- if (strncasecmp(modestr, "EX", 2) == 0) mode = LKM_EXMODE;
-
- return mode;
-}
-
-static const char *numtomode(int mode)
-{
- switch (mode)
- {
- case LKM_NLMODE: return "NL";
- case LKM_CRMODE: return "CR";
- case LKM_CWMODE: return "CW";
- case LKM_PRMODE: return "PR";
- case LKM_PWMODE: return "PW";
- case LKM_EXMODE: return "EX";
- default: return "??";
- }
-}
-
-static void usage(char *prog, FILE *file)
-{
- fprintf(file, "Usage:\n");
- fprintf(file, "%s [mcnpquhV] <lockname>\n", prog);
- fprintf(file, "\n");
- fprintf(file, " -V Show version of dlmtest\n");
- fprintf(file, " -h Show this help information\n");
- fprintf(file, " -m <mode> lock mode (default EX)\n");
- fprintf(file, " -c <mode> mode to convert to (default none)\n");
- fprintf(file, " -n don't block\n");
- fprintf(file, " -p Use pthreads\n");
- fprintf(file, " -u Don't unlock\n");
- fprintf(file, " -C Crash after lock\n");
- fprintf(file, " -q Quiet\n");
- fprintf(file, " -u Don't unlock explicitly\n");
- fprintf(file, "\n");
-
-}
-
-static void ast_routine(void *arg)
-{
- struct dlm_lksb *alksb = arg;
-
- if (!quiet)
- printf("ast called, status = %d, lkid=%x\n", alksb->sb_status, alksb->sb_lkid);
-
- /* Wake the main thread */
- if (use_threads)
- {
- pthread_mutex_lock(&mutex);
- pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
- }
- else
- {
- ast_called = 1;
- }
-}
-
-static void bast_routine(void *arg)
-{
- struct dlm_lksb *blksb = arg;
-
- if (!quiet)
- printf("\nblocking ast called, status = %d, lkid=%x\n", blksb->sb_status, blksb->sb_lkid);
-}
-
-/* Using poll(2) to wait for and dispatch ASTs */
-static int poll_for_ast(void)
-{
- struct pollfd pfd;
-
- pfd.fd = dlm_get_fd();
- pfd.events = POLLIN;
- while (!ast_called)
- {
- if (poll(&pfd, 1, 0) < 0)
- {
- perror("poll");
- return -1;
- }
- dlm_dispatch(pfd.fd);
- }
- ast_called = 0;
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- const char *resource = "LOCK-NAME";
- int flags = 0;
- int delay = 0;
- int status;
- int mode = LKM_EXMODE;
- int convmode = -1;
- int do_unlock = 1;
- int do_crash = 0;
- signed char opt;
-
- /* Deal with command-line arguments */
- opterr = 0;
- optind = 0;
- while ((opt=getopt(argc,argv,"?m:nqupc:d:CvV")) != EOF)
- {
- switch(opt)
- {
- case 'h':
- usage(argv[0], stdout);
- exit(0);
-
- case '?':
- usage(argv[0], stderr);
- exit(0);
-
- case 'm':
- mode = modetonum(optarg);
- break;
-
- case 'c':
- convmode = modetonum(optarg);
- break;
-
- case 'p':
- use_threads++;
- break;
-
- case 'n':
- flags |= LKF_NOQUEUE;
- break;
-
- case 'q':
- quiet = 1;
- break;
-
- case 'u':
- do_unlock = 0;
- break;
-
- case 'C':
- do_crash = 1;
- break;
-
- case 'd':
- delay = atoi(optarg);
- break;
-
- case 'V':
- printf("\nasttest version 0.1\n\n");
- exit(1);
- break;
- }
- }
-
- if (argv[optind])
- resource = argv[optind];
-
- if (!quiet)
- fprintf(stderr, "locking %s %s %s...", resource,
- numtomode(mode),
- (flags&LKF_NOQUEUE?"(NOQUEUE)":""));
-
- fflush(stderr);
-
- if (use_threads)
- {
- pthread_cond_init(&cond, NULL);
- pthread_mutex_init(&mutex, NULL);
- pthread_mutex_lock(&mutex);
-
- dlm_pthread_init();
- }
-
- status = dlm_lock(mode,
- &lksb,
- flags,
- resource,
- strlen(resource),
- 0, // Parent,
- ast_routine,
- &lksb,
- bast_routine,
- NULL); // Range
- if (status == -1)
- {
- if (!quiet) fprintf(stderr, "\n");
- perror("lock");
-
- return -1;
- }
- printf("(lkid=%x)", lksb.sb_lkid);
-
- if (do_crash)
- *(int *)0 = 0xdeadbeef;
-
- /* Wait */
- if (use_threads)
- pthread_cond_wait(&cond, &mutex);
- else
- poll_for_ast();
-
- if (delay)
- sleep(delay);
-
- if (!quiet)
- {
- fprintf(stderr, "unlocking %s...", resource);
- fflush(stderr);
- }
-
- if (do_unlock)
- {
- status = dlm_unlock(lksb.sb_lkid,
- 0, // flags
- &lksb,
- &lksb); // AST args
- if (status == -1)
- {
- if (!quiet) fprintf(stderr, "\n");
- perror("unlock");
- return -1;
- }
-
- /* Wait */
- if (use_threads)
- pthread_cond_wait(&cond, &mutex);
- else
- poll_for_ast();
- }
-
- return 0;
-}
-
diff --git a/dlm/tests/usertest/dlmtest.c b/dlm/tests/usertest/dlmtest.c
deleted file mode 100644
index dc54c2e..0000000
--- a/dlm/tests/usertest/dlmtest.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/* Test program for userland DLM interface */
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <unistd.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "libdlm.h"
-
-static int modetonum(char *modestr)
-{
- int mode = LKM_EXMODE;
-
- if (strncasecmp(modestr, "NL", 2) == 0) mode = LKM_NLMODE;
- if (strncasecmp(modestr, "CR", 2) == 0) mode = LKM_CRMODE;
- if (strncasecmp(modestr, "CW", 2) == 0) mode = LKM_CWMODE;
- if (strncasecmp(modestr, "PR", 2) == 0) mode = LKM_PRMODE;
- if (strncasecmp(modestr, "PW", 2) == 0) mode = LKM_PWMODE;
- if (strncasecmp(modestr, "EX", 2) == 0) mode = LKM_EXMODE;
-
- return mode;
-}
-
-static const char *numtomode(int mode)
-{
- switch (mode)
- {
- case LKM_NLMODE: return "NL";
- case LKM_CRMODE: return "CR";
- case LKM_CWMODE: return "CW";
- case LKM_PRMODE: return "PR";
- case LKM_PWMODE: return "PW";
- case LKM_EXMODE: return "EX";
- default: return "??";
- }
-}
-
-static void usage(char *prog, FILE *file)
-{
- fprintf(file, "Usage:\n");
- fprintf(file, "%s [hmcnQpequdV] <lockname>\n", prog);
- fprintf(file, "\n");
- fprintf(file, " -V Show version of dlmtest\n");
- fprintf(file, " -h Show this help information\n");
- fprintf(file, " -m <mode> lock mode (default EX)\n");
- fprintf(file, " -c <mode> mode to convert to (default none)\n");
- fprintf(file, " -n don't block\n");
- fprintf(file, " -Q query the lock\n");
- fprintf(file, " -p Persistent lock\n");
- fprintf(file, " -e Expedite conversion\n");
- fprintf(file, " -q Quiet\n");
- fprintf(file, " -u Don't unlock explicitly\n");
- fprintf(file, " -d <secs> Time to hold the lock for\n");
- fprintf(file, "\n");
-
-}
-
-#ifdef QUERY
-static void query_ast_routine(void *arg)
-{
- struct dlm_lksb *lksb = arg;
- struct dlm_queryinfo *qi = (struct dlm_queryinfo *)lksb->sb_lvbptr;
- int i;
-
- qi->gqi_resinfo->rsi_name[qi->gqi_resinfo->rsi_length] = '\0';
- /* Dump resource info */
- printf("lockinfo: status = %d\n", lksb->sb_status);
- printf("lockinfo: resource = '%s'\n", qi->gqi_resinfo->rsi_name);
- printf("lockinfo: grantcount = %d\n", qi->gqi_resinfo->rsi_grantcount);
- printf("lockinfo: convcount = %d\n", qi->gqi_resinfo->rsi_convcount);
- printf("lockinfo: waitcount = %d\n", qi->gqi_resinfo->rsi_waitcount);
- printf("lockinfo: masternode = %d\n", qi->gqi_resinfo->rsi_masternode);
-
- /* Dump all the locks */
- for (i = 0; i < qi->gqi_lockcount; i++)
- {
- struct dlm_lockinfo *li = &qi->gqi_lockinfo[i];
-
- printf("lockinfo: lock: lkid = %x\n", li->lki_lkid);
- printf("lockinfo: lock: master lkid = %x\n", li->lki_mstlkid);
- printf("lockinfo: lock: parent lkid = %x\n", li->lki_parent);
- printf("lockinfo: lock: node = %d\n", li->lki_node);
- printf("lockinfo: lock: pid = %d\n", li->lki_ownpid);
- printf("lockinfo: lock: state = %d\n", li->lki_state);
- printf("lockinfo: lock: grmode = %d\n", li->lki_grmode);
- printf("lockinfo: lock: rqmode = %d\n", li->lki_rqmode);
- printf("\n");
- }
-
- if (qi->gqi_lockinfo)
- free(qi->gqi_lockinfo);
-}
-
-static struct dlm_queryinfo qinfo;
-static struct dlm_resinfo resinfo;
-#define MAX_QUERY_LOCKS 10
-
-
-static int query_lock(int lockid)
-{
- int status;
-struct dlm_lksb tmplksb;
- lksb.sb_lkid = lockid;
- qinfo.gqi_resinfo = &resinfo;
- qinfo.gqi_lockinfo = malloc(sizeof(struct dlm_lockinfo) * MAX_QUERY_LOCKS);
- qinfo.gqi_locksize = MAX_QUERY_LOCKS;
- lksb.sb_lvbptr = (char *)&qinfo;
-
- status = dlm_query(&tmplksb,
- DLM_QUERY_QUEUE_ALL | DLM_QUERY_LOCKS_ALL,
- &qinfo,
- query_ast_routine,
- &tmplksb);
- if (status)
- perror("Query failed");
- else
- sleep(1); /* Just to allow the result to come back. There isn't
- a synchronous version of this call */
- return status;
-}
-#endif
-
-
-int main(int argc, char *argv[])
-{
- const char *resource = "LOCK-NAME";
- int flags = 0;
- int status;
- int delay = 5;
- int mode = LKM_EXMODE;
- int convmode = -1;
- int lockid;
- int quiet = 0;
- int do_unlock = 1;
- int do_query = 0;
- int do_expedite = 0;
- signed char opt;
-
- /* Deal with command-line arguments */
- opterr = 0;
- optind = 0;
- while ((opt=getopt(argc,argv,"?m:nquQepd:c:vV")) != EOF)
- {
- switch(opt)
- {
- case 'h':
- usage(argv[0], stdout);
- exit(0);
-
- case '?':
- usage(argv[0], stderr);
- exit(0);
-
- case 'm':
- mode = modetonum(optarg);
- break;
-
- case 'c':
- convmode = modetonum(optarg);
- break;
-
- case 'e':
- do_expedite = 1;
- break;
-
- case 'p':
- flags |= LKF_PERSISTENT;
- break;
-
- case 'n':
- flags |= LKF_NOQUEUE;
- break;
-
- case 'd':
- delay = atoi(optarg);
- break;
-
- case 'q':
- quiet = 1;
- break;
-
- case 'u':
- do_unlock = 0;
- break;
-
- case 'Q':
- do_query = 1;
- break;
-
- case 'V':
- printf("\ndlmtest version 0.3\n\n");
- exit(1);
- break;
- }
- }
-
- if (argv[optind])
- resource = argv[optind];
-
- if (!quiet)
- fprintf(stderr, "locking %s %s %s...", resource,
- numtomode(mode),
- (flags&LKF_NOQUEUE?"(NOQUEUE)":""));
-
- fflush(stderr);
-
- status = lock_resource(resource, mode, flags, &lockid);
- if (status == -1)
- {
- if (!quiet) fprintf(stderr, "\n");
- perror("lock");
-
- return -1;
- }
- if (lockid == 0)
- {
- fprintf(stderr, "error: got lockid of zero\n");
- return 0;
- }
-
- if (!quiet) fprintf(stderr, "done (lkid = %x)\n", lockid);
-
- if (!do_unlock) return 0;
-
-#ifdef QUERY
- if (do_query) query_lock(lockid);
-#endif
-
- sleep(delay);
-
- if (convmode != -1)
- {
- if (do_expedite)
- flags |= LKF_EXPEDITE;
-
- if (!quiet)
- {
- fprintf(stderr, "converting %s to %s...", resource, numtomode(convmode));
- fflush(stderr);
- }
-
- status = lock_resource(resource, convmode, flags | LKF_CONVERT, &lockid);
- if (status == -1)
- {
- if (!quiet) fprintf(stderr, "\n");
- perror("convert");
- return -1;
- }
- if (!quiet) fprintf(stderr, "done\n");
- }
-
- sleep(delay);
-
- if (!quiet)
- {
- fprintf(stderr, "unlocking %s...", resource);
- fflush(stderr);
- }
-
- status = unlock_resource(lockid);
- if (status == -1)
- {
- if (!quiet) fprintf(stderr, "\n");
- perror("unlock");
- return -1;
- }
-
- if (!quiet) fprintf(stderr, "done\n");
-
- /* For some reason, calling this IMMEDIATELY before
- exitting, causes a thread hang. either don't call it at
- all or do something in afterwards before calling exit
- */
- dlm_pthread_cleanup();
- return 0;
-}
-
diff --git a/dlm/tests/usertest/dlmtest2.c b/dlm/tests/usertest/dlmtest2.c
deleted file mode 100644
index 4444132..0000000
--- a/dlm/tests/usertest/dlmtest2.c
+++ /dev/null
@@ -1,1454 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-#include <signal.h>
-#include <syslog.h>
-#include <sys/time.h>
-#include <asm/types.h>
-#include <sys/socket.h>
-#include <sys/poll.h>
-#include <sys/un.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/errno.h>
-
-#include "libdlm.h"
-
-#define MAX_CLIENTS 4
-#define MAX_LOCKS 16
-#define MAX_RESOURCES 16
-
-static dlm_lshandle_t *dh;
-static int libdlm_fd;
-static int timewarn = 0;
-static uint64_t timeout = 0;
-static int noqueue = 1;
-static int persistent = 0;
-static int ignore_bast = 0;
-static int quiet = 1;
-static int verbose = 0;
-static int bast_cb;
-static int maxn = MAX_LOCKS;
-static int maxr = MAX_RESOURCES;
-static int iterations;
-static int minhold = 0;
-static int stress_stop = 0;
-static int stress_delay = 0;
-static int stress_lock_only = 0;
-static int openclose_ls = 0;
-static uint64_t our_xid;
-static char cmd[32];
-
-static unsigned int sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain, sts_other, sts_zero;
-static unsigned int bast_unlock, bast_skip;
-
-
-#define log_print(fmt, args...) \
-do { \
- if (!quiet) \
- printf(fmt , ##args); \
-} while (0)
-
-#define log_op(fmt, args...) \
-do { \
- if (!quiet) \
- printf(fmt , ##args); \
-} while (0)
-
-#define log_ast(fmt, args...) \
-do { \
- if (verbose) \
- printf(fmt , ##args); \
-} while (0)
-
-#define log_bast(fmt, args...) \
-do { \
- if (verbose > 1) \
- printf(fmt , ##args); \
-} while (0)
-
-#define log_verbose(fmt, args...) \
-do { \
- if (verbose > 2) \
- printf(fmt , ##args); \
-} while (0)
-
-struct client {
- int fd;
- char type[32];
-};
-
-static int client_size = MAX_CLIENTS;
-static struct client client[MAX_CLIENTS];
-static struct pollfd pollfd[MAX_CLIENTS];
-
-enum {
- Op_lock = 1,
- Op_unlock,
- Op_unlockf,
- Op_cancel,
-};
-
-struct lk {
- int id;
- int rqmode;
- int grmode;
- int wait_ast;
- int lastop;
- int last_status;
- int bast;
- int minhold;
- struct dlm_lksb lksb;
- struct timeval begin;
- struct timeval acquired;
-};
-
-struct lk *locks;
-
-static void unlock(int i);
-static void unlockf(int i);
-
-
-static int rand_int(int a, int b)
-{
- return a + (int) (((float)(b - a + 1)) * random() / (RAND_MAX+1.0));
-}
-
-static const char *status_str(int status)
-{
- static char sts_str[8];
-
- switch (status) {
- case 0:
- return "0 ";
- case EUNLOCK:
- return "EUNLOCK";
- case ECANCEL:
- return "ECANCEL";
- case EAGAIN:
- return "EAGAIN ";
- case EBUSY:
- return "EBUSY ";
- case ETIMEDOUT:
- return "ETIMEDO";
- case EDEADLK:
- return "EDEADLK";
- default:
- snprintf(sts_str, 8, "%8x", status);
- return sts_str;
- }
-}
-
-static const char *op_str(int op)
-{
- switch (op) {
- case Op_lock:
- return "lock";
- case Op_unlock:
- return "unlock";
- case Op_unlockf:
- return "unlockf";
- case Op_cancel:
- return "cancel";
- default:
- return "unknown";
- }
-}
-
-static struct lk *get_lock(int i)
-{
- if (i < 0)
- return NULL;
- if (i >= maxn)
- return NULL;
- return &locks[i];
-}
-
-static int all_unlocks_done(void)
-{
- struct lk *lk;
- int i;
-
- for (i = 0; i < maxn; i++) {
- lk = get_lock(i);
- if (lk->grmode == -1 && !lk->wait_ast)
- continue;
- return 0;
- }
- return 1;
-}
-
-static void dump(void)
-{
- struct timeval now;
- struct lk *lk;
- int i;
-
- gettimeofday(&now, NULL);
-
- for (i = 0; i < maxn; i++) {
- lk = get_lock(i);
- printf("x %2d lkid %08x gr %2d rq %2d wait_ast %d last op %s \t%s %us\n",
- i,
- lk->lksb.sb_lkid,
- lk->grmode,
- lk->rqmode,
- lk->wait_ast,
- op_str(lk->lastop),
- status_str(lk->last_status),
- lk->wait_ast ? (unsigned int)(now.tv_sec - lk->begin.tv_sec) : 0);
- }
-}
-
-static void bastfn(void *arg)
-{
- struct lk *lk = arg;
- lk->bast = 1;
- bast_cb = 1;
-}
-
-static void do_bast(struct lk *lk)
-{
- int skip = 0;
-
- if (lk->lastop == Op_unlock || lk->lastop == Op_unlockf) {
- skip = 1;
- }
- if (!lk->lksb.sb_lkid) {
- skip = 1;
- }
-
- if (skip) {
- bast_skip++;
- log_bast(" bast: skip %3d\t%x\n", lk->id, lk->lksb.sb_lkid);
- } else {
- bast_unlock++;
- log_bast(" bast: unlockf %3d\t%x\n", lk->id, lk->lksb.sb_lkid);
- unlockf(lk->id);
- }
- lk->bast = 0;
-}
-
-static void do_bast_unlocks(void)
-{
- struct lk *lk;
- int i;
-
- for (i = 0; i < maxn; i++) {
- lk = get_lock(i);
- if (lk->bast)
- do_bast(lk);
- }
- bast_cb = 0;
-}
-
-static void process_libdlm(void)
-{
- dlm_dispatch(libdlm_fd);
- if (bast_cb && !ignore_bast)
- do_bast_unlocks();
-}
-
-static void astfn(void *arg)
-{
- struct lk *lk = arg;
- int i = lk->id;
-
- if (!lk->wait_ast) {
- printf(" ast: %s %3d\t%x: !wait_ast gr %d rq %d last op %s %s\n",
- status_str(lk->lksb.sb_status), i, lk->lksb.sb_lkid,
- lk->grmode, lk->rqmode,
- op_str(lk->lastop), status_str(lk->last_status));
- }
-
- log_ast(" ast: %s %3d\t%x\n",
- status_str(lk->lksb.sb_status), i, lk->lksb.sb_lkid);
-
- lk->last_status = lk->lksb.sb_status;
-
- if (lk->lksb.sb_status == EUNLOCK) {
- sts_eunlock++;
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- lk->grmode = -1;
- lk->wait_ast = 0;
-
- } else if (lk->lksb.sb_status == ECANCEL) {
- sts_ecancel++;
- if (lk->grmode == -1) {
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- lk->wait_ast = 0;
- } else {
- if (lk->lastop != Op_unlock && lk->lastop != Op_unlockf)
- lk->wait_ast = 0;
- }
-
- } else if (lk->lksb.sb_status == ETIMEDOUT) {
- sts_etimedout++;
- if (lk->grmode == -1) {
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- lk->wait_ast = 0;
- } else {
- if (lk->lastop != Op_unlock && lk->lastop != Op_unlockf)
- lk->wait_ast = 0;
- }
-
- } else if (lk->lksb.sb_status == EDEADLK) {
- sts_edeadlk++;
- if (lk->grmode == -1) {
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- lk->wait_ast = 0;
- } else {
- if (lk->lastop != Op_unlock && lk->lastop != Op_unlockf)
- lk->wait_ast = 0;
- }
-
- } else if (lk->lksb.sb_status == EAGAIN) {
- sts_eagain++;
- if (lk->grmode == -1) {
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- lk->wait_ast = 0;
- } else {
- if (lk->lastop != Op_unlockf)
- lk->wait_ast = 0;
- }
-
- } else {
- if (lk->lksb.sb_status != 0) {
- sts_other++;
- printf("BAD ast: %d %3d\t%x: gr %d rq %d last op %s %s\n",
- lk->lksb.sb_status, i, lk->lksb.sb_lkid,
- lk->grmode, lk->rqmode, op_str(lk->lastop),
- status_str(lk->last_status));
- stress_stop = 1;
- return;
- }
-
- sts_zero++;
-
- if (lk->lastop != Op_unlockf)
- lk->wait_ast = 0;
-
- lk->grmode = lk->rqmode;
-
- if (minhold) {
- gettimeofday(&lk->acquired, NULL);
- lk->minhold = minhold;
- }
- }
-
- lk->rqmode = -1;
-}
-
-/* EBUSY from dlm_ls_lockx() is expected sometimes, e.g. lock, cancel, lock;
- the first lock is successful and the app gets the status back,
- and issues the second lock before the reply for the overlapping
- cancel (which did nothing) has been received in the dlm. */
-
-static void lock(int i, int mode)
-{
- char name[DLM_RESNAME_MAXLEN];
- struct lk *lk;
- int flags = 0;
- int rv;
- uint64_t *timeout_arg = NULL;
-
- lk = get_lock(i);
- if (!lk)
- return;
-
- if (noqueue)
- flags |= LKF_NOQUEUE;
- if (persistent)
- flags |= LKF_PERSISTENT;
- if (timeout) {
- flags |= LKF_TIMEOUT;
- timeout_arg = &timeout;
- }
-
- if (lk->lksb.sb_lkid)
- flags |= LKF_CONVERT;
-
- memset(name, 0, sizeof(name));
- snprintf(name, sizeof(name), "test%d", (i % maxr));
-
- log_verbose("lock: %d grmode %d rqmode %d flags %x lkid %x %s\n",
- i, lk->grmode, mode, flags, lk->lksb.sb_lkid, name);
-
-#if 0
- rv = dlm_ls_lock(dh, mode, &lk->lksb, flags, name, strlen(name), 0,
- astfn, (void *) lk, bastfn, NULL);
-#else
- rv = dlm_ls_lockx(dh, mode, &lk->lksb, flags, name, strlen(name), 0,
- astfn, (void *) lk, bastfn, &our_xid, timeout_arg);
-#endif
- if (!rv) {
- lk->wait_ast = 1;
- lk->rqmode = mode;
- gettimeofday(&lk->begin, NULL);
- } else if (rv == -1 && errno == EBUSY) {
- printf(" : lock %3d\t%x: EBUSY gr %d rq %d wait_ast %d\n",
- i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode, lk->wait_ast);
- } else {
- printf(" : lock %3d\t%x: errno %d rv %d gr %d rq %d wait_ast %d\n",
- i, lk->lksb.sb_lkid, errno, rv, lk->grmode, lk->rqmode, lk->wait_ast);
- stress_stop = 1;
- }
-
- log_verbose("lock: %d rv %d sb_lkid %x sb_status %x\n",
- i, rv, lk->lksb.sb_lkid, lk->lksb.sb_status);
-
- lk->lastop = Op_lock;
-}
-
-static void lock_sync(int i, int mode)
-{
- char name[DLM_RESNAME_MAXLEN];
- int flags = 0;
- int rv;
- struct lk *lk;
-
- lk = get_lock(i);
- if (!lk)
- return;
-
- if (noqueue)
- flags |= LKF_NOQUEUE;
- if (persistent)
- flags |= LKF_PERSISTENT;
-
- if (lk->lksb.sb_lkid)
- flags |= LKF_CONVERT;
-
- memset(name, 0, sizeof(name));
- snprintf(name, sizeof(name), "test%d", (i % maxr));
-
- log_verbose("lock_sync: %d rqmode %d flags %x lkid %x %s\n",
- i, mode, flags, lk->lksb.sb_lkid, name);
-
- rv = dlm_ls_lock_wait(dh, mode, &lk->lksb, flags,
- name, strlen(name), 0, (void *) lk,
- bastfn, NULL);
-
- log_verbose("lock_sync: %d rv %d sb_lkid %x sb_status %x\n",
- i, rv, lk->lksb.sb_lkid, lk->lksb.sb_status);
-
- if (!rv) {
- lk->grmode = mode;
- lk->rqmode = -1;
- } else if (rv == EAGAIN) {
- if (lk->grmode == -1)
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- } else {
- printf("unknown rv %d\n", rv);
- exit(-1);
- }
-}
-
-static void lock_all(int mode)
-{
- int i;
-
- for (i = 0; i < maxn; i++)
- lock(i, mode);
-}
-
-static const char *uflags(uint32_t flags)
-{
- if (flags == LKF_FORCEUNLOCK)
- return "FORCEUNLOCK";
- if (flags == LKF_CANCEL)
- return "CANCEL";
- return "0";
-}
-
-/* ENOENT is expected from dlm_ls_unlock() sometimes because we'll
- try to do an unlockf during an outstanding op that will free
- the lock itself */
-
-static void _unlock(int i, uint32_t flags)
-{
- struct lk *lk;
- uint32_t lkid;
- int rv;
-
- lk = get_lock(i);
- if (!lk)
- return;
-
- lkid = lk->lksb.sb_lkid;
- if (!lkid)
- return;
-
- log_verbose("unlock: %d lkid %x flags %x\n", i, lkid, flags);
-
- rv = dlm_ls_unlock(dh, lkid, flags, &lk->lksb, lk);
- if (!rv) {
- lk->wait_ast = 1;
- gettimeofday(&lk->begin, NULL);
- } else if (rv == -1 && errno == EBUSY) {
- printf(" : unlock %3d\t%x: EBUSY flags %s gr %d rq %d wait_ast %d\n",
- i, lk->lksb.sb_lkid, uflags(flags), lk->grmode, lk->rqmode, lk->wait_ast);
- } else if (rv == -1 && errno == ENOENT) {
- printf(" : unlock %3d\t%x: ENOENT flags %s gr %d rq %d wait_ast %d\n",
- i, lk->lksb.sb_lkid, uflags(flags), lk->grmode, lk->rqmode, lk->wait_ast);
- } else {
- printf(" : unlock %3d\t%x: errno %d flags %s rv %d gr %d rq %d wait_ast %d\n",
- i, lk->lksb.sb_lkid, errno, uflags(flags), rv, lk->grmode, lk->rqmode, lk->wait_ast);
- }
-}
-
-static void unlock(int i)
-{
- struct lk *lk = get_lock(i);
-
- if (minhold) {
- struct timeval now;
-
- if (lk->wait_ast)
- return;
-
- gettimeofday(&now, NULL);
- if (lk->acquired.tv_sec + lk->minhold > now.tv_sec) {
- printf(" : unlock %3d\t%x: gr %d rq %d held %u of %u s\n",
- i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode,
- (unsigned int)(now.tv_sec - lk->acquired.tv_sec), lk->minhold);
- return;
- }
- }
-
- _unlock(i, 0);
- lk->rqmode = -1;
- lk->lastop = Op_unlock;
-}
-
-static void unlockf(int i)
-{
- struct lk *lk = get_lock(i);
-
- if (minhold) {
- struct timeval now;
-
- if (lk->wait_ast)
- return;
-
- gettimeofday(&now, NULL);
- if (lk->acquired.tv_sec + lk->minhold > now.tv_sec) {
- printf(" : unlockf %3d\t%x: gr %d rq %d held %u of %u s\n",
- i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode,
- (unsigned int)(now.tv_sec - lk->acquired.tv_sec), lk->minhold);
- return;
- }
- }
-
- _unlock(i, LKF_FORCEUNLOCK);
- lk->rqmode = -1;
- lk->lastop = Op_unlockf;
-}
-
-static void cancel(int i)
-{
- struct lk *lk = get_lock(i);
- _unlock(i, LKF_CANCEL);
- lk->lastop = Op_cancel;
-}
-
-static void canceld(int i, uint32_t lkid)
-{
- int rv;
-
- rv = dlm_ls_deadlock_cancel(dh, lkid, 0);
-
- printf("canceld %x: %d %d\n", lkid, rv, errno);
-}
-
-static void unlock_sync(int i)
-{
- uint32_t lkid;
- int rv;
- struct lk *lk;
-
- lk = get_lock(i);
- if (!lk)
- return;
-
- lkid = lk->lksb.sb_lkid;
- if (!lkid) {
- log_print("unlock %d skip zero lkid\n", i);
- return;
- }
-
- log_verbose("unlock_sync: %d lkid %x\n", i, lkid);
-
- rv = dlm_ls_unlock_wait(dh, lkid, 0, &lk->lksb);
-
- log_verbose("unlock_sync: %d rv %d sb_status %x\n", i, rv,
- lk->lksb.sb_status);
-
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- lk->grmode = -1;
- lk->rqmode = -1;
-}
-
-static void unlock_all(void)
-{
- struct lk *lk;
- int i;
-
- for (i = 0; i < maxn; i++) {
- lk = get_lock(i);
- unlock(i);
- }
-}
-
-static void purge(int nodeid, int pid)
-{
- struct lk *lk;
- int i, rv;
-
- rv = dlm_ls_purge(dh, nodeid, pid);
- if (rv) {
- printf("dlm_ls_purge %d %d error %d\n", nodeid, pid, rv);
- return;
- }
-
- for (i = 0; i < maxn; i++) {
- lk = get_lock(i);
- memset(&lk->lksb, 0, sizeof(struct dlm_lksb));
- lk->grmode = -1;
- lk->wait_ast = 0;
- }
-}
-
-static void purgetest(int nodeid, int pid)
-{
- struct lk *lk;
- int i, mid = maxn / 2;
-
- printf("lock %d to %d\n", 0, mid-1);
- for (i = 0; i < mid; i++)
- lock(i, 3);
-
- while (1) {
- process_libdlm();
- for (i = 0; i < mid; i++) {
- lk = get_lock(i);
- if (!lk->wait_ast)
- continue;
- break;
- }
- if (i == mid)
- break;
- }
-
- for (i = mid; i < maxn; i++)
- lock(i, 3);
- for (i = 0; i < mid; i++)
- unlock(i);
- /* usleep(10000); */
- purge(nodeid, pid);
-}
-
-static void tstress_unlocks(void)
-{
- struct lk *lk;
- struct timeval now;
- int i;
-
- for (i = 0; i < maxn; i++) {
- lk = get_lock(i);
- if (!lk)
- continue;
- if (lk->wait_ast)
- continue;
- if (lk->grmode < 0)
- continue;
-
- /* if we've held the lock for minhold seconds, then unlock */
-
- gettimeofday(&now, NULL);
-
- if (now.tv_sec >= lk->acquired.tv_sec + minhold) {
- printf(" : unlock %3d\t%x: gr %d rq %d held %u of %u s\n",
- i, lk->lksb.sb_lkid, lk->grmode, lk->rqmode,
- (unsigned int)(now.tv_sec - lk->acquired.tv_sec), minhold);
-
- _unlock(i, 0);
- lk->rqmode = -1;
- lk->lastop = Op_unlock;
- }
-
- }
-}
-
-static void tstress(int num)
-{
- unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops;
- int i;
- struct lk *lk;
-
- n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0;
- sts_eunlock = sts_ecancel = sts_etimedout = sts_edeadlk = sts_eagain = sts_other = sts_zero = 0;
- bast_unlock = bast_skip = 0;
-
- noqueue = 0;
- ignore_bast = 1;
- quiet = 0;
-
- if (!timeout)
- timeout = 4;
- if (!minhold)
- minhold = 5;
-
- while (!stress_stop) {
- if (stress_delay)
- usleep(stress_delay);
-
- process_libdlm();
-
- tstress_unlocks();
-
- if (++n == num) {
- if (all_unlocks_done())
- break;
- else
- continue;
- }
-
- i = rand_int(0, maxn-1);
- lk = get_lock(i);
- if (!lk)
- continue;
-
- if (lk->wait_ast || lk->grmode > -1)
- continue;
-
- lock(i, rand_int(0, 5));
- lock_ops++;
- printf("%8x: lock %3d\t%x\n", n, i, lk->lksb.sb_lkid);
- }
-
- printf("ops: skip %d lock %d unlock %d unlockf %d cancel %d\n",
- skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops);
- printf("bast: unlock %u skip %u\n", bast_unlock, bast_skip);
- printf("ast status: eunlock %d ecancel %d etimedout %d edeadlk %d eagain %d\n",
- sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain);
- printf("ast status: zero %d other %d\n", sts_zero, sts_other);
-}
-
-static void dstress(int num)
-{
- unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops;
- int i;
- struct lk *lk;
-
- n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0;
- sts_eunlock = sts_ecancel = sts_etimedout = sts_edeadlk = sts_eagain = sts_other = sts_zero = 0;
- bast_unlock = bast_skip = 0;
-
- noqueue = 0;
- ignore_bast = 1;
- quiet = 0;
-
- while (!stress_stop && n < num) {
-
- sleep(1);
-
- process_libdlm();
-
- if (n && !(n % 60))
- unlock_all();
- n++;
-
- i = rand_int(0, maxn-1);
- lk = get_lock(i);
- if (!lk)
- continue;
-
- if (lk->wait_ast || lk->grmode > -1) {
- printf("%8x: lock %3d\t%x: skip gr %d wait_ast %d\n",
- n, i, lk->lksb.sb_lkid, lk->grmode, lk->wait_ast);
- continue;
- }
-
- lock(i, rand_int(0, 5));
- lock_ops++;
- printf("%8x: lock %3d\t%x\n", n, i, lk->lksb.sb_lkid);
- }
-
- printf("ops: skip %d lock %d unlock %d unlockf %d cancel %d\n",
- skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops);
- printf("bast: unlock %u skip %u\n", bast_unlock, bast_skip);
- printf("ast status: eunlock %d ecancel %d etimedout %d edeadlk %d eagain %d\n",
- sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain);
- printf("ast status: zero %d other %d\n", sts_zero, sts_other);
-}
-
-static void stress(int num)
-{
- int i, o, op, max_op, skip;
- unsigned int n, skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops;
- struct lk *lk;
-
- n = skips = lock_ops = unlock_ops = unlockf_ops = cancel_ops = 0;
- sts_eunlock = sts_ecancel = sts_etimedout = sts_edeadlk = sts_eagain = sts_other = sts_zero = 0;
- bast_unlock = bast_skip = 0;
-
- while (!stress_stop) {
- if (stress_delay)
- usleep(stress_delay);
-
- process_libdlm();
-
- if (++n == num)
- break;
-
- i = rand_int(0, maxn-1);
- lk = get_lock(i);
- if (!lk)
- continue;
-
- max_op = 5;
- if (stress_lock_only)
- max_op = 2;
-
- o = rand_int(0, max_op);
- switch (o) {
- case 0:
- case 1:
- case 2:
- op = Op_lock;
- break;
- case 3:
- op = Op_unlock;
- break;
- case 4:
- op = Op_unlockf;
- break;
- case 5:
- op = Op_cancel;
- break;
- default:
- op = 0;
- }
-
- skip = 0;
-
- switch (op) {
- case Op_lock:
- if (lk->wait_ast) {
- skip = 1;
- break;
- }
-
- noqueue = !!o;
- our_xid = n;
-
- lock(i, rand_int(0, 5));
- lock_ops++;
- log_op("%8x: lock %3d\t%x\n", n, i, lk->lksb.sb_lkid);
- break;
-
- case Op_unlock:
- if (lk->wait_ast) {
- skip = 1;
- break;
- }
- if (lk->lastop == Op_unlock || lk->lastop == Op_unlockf) {
- skip = 1;
- break;
- }
- if (!lk->lksb.sb_lkid) {
- skip = 1;
- break;
- }
-
- unlock(i);
- unlock_ops++;
- log_op("%8x: unlock %3d\t%x\n", n, i, lk->lksb.sb_lkid);
- break;
-
- case Op_unlockf:
- if (lk->lastop == Op_unlock || lk->lastop == Op_unlockf) {
- skip = 1;
- break;
- }
- if (!lk->lksb.sb_lkid) {
- skip = 1;
- break;
- }
-
- unlockf(i);
- unlockf_ops++;
- log_op("%8x: unlockf %3d\t%x\n", n, i, lk->lksb.sb_lkid);
- break;
-
- case Op_cancel:
- if (!lk->wait_ast) {
- skip = 1;
- break;
- }
- if (lk->lastop > Op_lock) {
- skip = 1;
- break;
- }
-
- cancel(i);
- cancel_ops++;
- log_op("%8x: cancel %3d\t%x\n", n, i, lk->lksb.sb_lkid);
- break;
- }
-
- if (skip)
- skips++;
- }
-
- printf("ops: skip %d lock %d unlock %d unlockf %d cancel %d\n",
- skips, lock_ops, unlock_ops, unlockf_ops, cancel_ops);
- printf("bast: unlock %u skip %u\n", bast_unlock, bast_skip);
- printf("ast status: eunlock %d ecancel %d etimedout %d edeadlk %d eagain %d\n",
- sts_eunlock, sts_ecancel, sts_etimedout, sts_edeadlk, sts_eagain);
- printf("ast status: zero %d other %d\n", sts_zero, sts_other);
-}
-
-static int client_add(int fd, int *maxi)
-{
- int i;
-
- for (i = 0; i < client_size; i++) {
- if (client[i].fd == -1) {
- client[i].fd = fd;
- pollfd[i].fd = fd;
- pollfd[i].events = POLLIN;
- if (i > *maxi)
- *maxi = i;
- printf("client %d fd %d added\n", i, fd);
- return i;
- }
- }
- printf("client add failed\n");
- return -1;
-}
-
-static void client_dead(int ci)
-{
- printf("client %d fd %d dead\n", ci, client[ci].fd);
- close(client[ci].fd);
- client[ci].fd = -1;
- pollfd[ci].fd = -1;
-}
-
-static void client_init(void)
-{
- int i;
-
- for (i = 0; i < client_size; i++)
- client[i].fd = -1;
-}
-
-static void print_commands(void)
-{
- printf("Usage:\n");
- printf("max locks (maxn) is %d (x of 0 to %d)\n", maxn, maxn-1);
- printf("max resources (maxr) is %d, lock x used on resource (x %% maxr)\n", maxr);
- printf("EXIT - exit program after unlocking any held locks\n");
- printf("kill - exit program without unlocking any locks\n");
- printf("lock x mode - request/convert lock x\n");
- printf("unlock x - unlock lock x\n");
- printf("unlockf x - force unlock lock x\n");
- printf("cancel x - cancel lock x\n");
- printf("canceld x lkid - cancel lock x, return EDEADLK as status\n");
- printf("lock_sync x mode - synchronous version of lock\n");
- printf("unlock_sync x - synchronous version of unlock\n");
- printf("ex x - equivalent to: lock x 5\n");
- printf("pr x - equivalent to: lock x 3\n");
- printf("hold - for x in 0 to max, lock x 3\n");
- printf("release - for x in 0 to max, unlock x\n");
- printf("purge nodeid pid - purge orphan locks of process\n");
- printf("stress n - loop doing random lock/unlock/unlockf/cancel on all locks, n times\n");
- printf("tstress n - stress timeouts\n");
- printf("dstress n - stress deadlock\n");
- printf("timeout n - enable lock timeouts, set timeout to n seconds\n");
- printf("dump - show info for all locks\n");
- printf("minhold - set minimum number of seconds locks will be held\n");
- printf("ignore_bast - ignore all basts\n");
- printf("noqueue - toggle NOQUEUE flag for all requests\n");
- printf("persistent - toggle PERSISTENT flag for all requests\n");
- printf("quiet - toggle quiet flag\n");
- printf("verbose - toggle verbose flag\n");
- printf("settings - show settings\n");
-
- printf("\ncombined operations\n");
- printf("hold-kill - hold; kill\n");
- printf("release-kill - release; kill\n");
- printf("lock-kill x mode - lock; kill\n");
- printf("unlock-kill x - unlock; kill\n");
- printf("lock-cancel x mode msec - lock; sleep; cancel\n");
- printf("lock-unlockf x mode msec - lock; sleep; unlockf\n");
- printf("lock-cancel-kill x mode msec - lock; sleep; cancel; kill\n");
- printf("lock-unlockf-kill x mode msec - lock; sleep; unlockf; kill\n");
- printf("purgetest nodeid pid\n");
-}
-
-static void print_settings(void)
-{
- printf("timewarn %d\n", timewarn);
- printf("timeout %llu\n", (unsigned long long) timeout);
- printf("noqueue %d\n", noqueue);
- printf("persistent %d\n", persistent);
- printf("ignore_bast %d\n", ignore_bast);
- printf("quiet %d\n", quiet);
- printf("verbose %d\n", verbose);
- printf("maxn %d\n", maxn);
- printf("maxr %d\n", maxr);
- printf("iterations %d\n", iterations);
- printf("minhold %d\n", minhold);
- printf("stress_stop %d\n", stress_stop);
- printf("stress_delay %d\n", stress_delay);
- printf("stress_lock_only %d\n", stress_lock_only);
- printf("our_xid %llx\n", (unsigned long long)our_xid);
-}
-
-static void process_command(int *quit)
-{
- char inbuf[132];
- int x = 0, y = 0;
-
- fgets(inbuf, sizeof(inbuf), stdin);
- sscanf(inbuf, "%s %d %d", cmd, &x, &y);
-
- if (!strncmp(cmd, "EXIT", 4)) {
- *quit = 1;
- unlock_all();
- return;
- }
-
- if (!strncmp(cmd, "CLOSE", 5)) {
- *quit = 1;
- openclose_ls = 1;
- unlock_all();
- return;
- }
-
- if (!strncmp(cmd, "kill", 4)) {
- printf("process exiting\n");
- exit(0);
- }
-
- if (!strncmp(cmd, "lock", 4) && strlen(cmd) == 4) {
- lock(x, y);
- return;
- }
-
- if (!strncmp(cmd, "unlock", 6) && strlen(cmd) == 6) {
- unlock(x);
- return;
- }
-
- if (!strncmp(cmd, "unlockf", 7) && strlen(cmd) == 7) {
- unlockf(x);
- return;
- }
-
- if (!strncmp(cmd, "cancel", 6) && strlen(cmd) == 6) {
- cancel(x);
- return;
- }
-
- if (!strncmp(cmd, "canceld", 7) && strlen(cmd) == 7) {
- canceld(x, y);
- return;
- }
-
- if (!strncmp(cmd, "lock_sync", 9) && strlen(cmd) == 9) {
- lock_sync(x, y);
- return;
- }
-
- if (!strncmp(cmd, "unlock_sync", 11) && strlen(cmd) == 11) {
- unlock_sync(x);
- return;
- }
-
- if (!strncmp(cmd, "lock-kill", 9) && strlen(cmd) == 9) {
- lock(x, y);
- printf("process exiting\n");
- exit(0);
- }
-
- if (!strncmp(cmd, "unlock-kill", 11) && strlen(cmd) == 11) {
- unlock(x);
- printf("process exiting\n");
- exit(0);
- }
-
- if (!strncmp(cmd, "lock-cancel", 11) && strlen(cmd) == 11) {
- lock(x, y);
- /* usleep(1000 * z); */
- cancel(x);
- return;
- }
-
- if (!strncmp(cmd, "lock-unlockf", 12) && strlen(cmd) == 12) {
- lock(x, y);
- /* usleep(1000 * z); */
- unlockf(x);
- return;
- }
-
- if (!strncmp(cmd, "ex", 2)) {
- lock(x, LKM_EXMODE);
- return;
- }
-
- if (!strncmp(cmd, "pr", 2)) {
- lock(x, LKM_PRMODE);
- return;
- }
-
- if (!strncmp(cmd, "hold", 4) && strlen(cmd) == 4) {
- lock_all(LKM_PRMODE);
- return;
- }
-
- if (!strncmp(cmd, "hold-kill", 9) && strlen(cmd) == 9) {
- lock_all(LKM_PRMODE);
- exit(0);
- }
-
- if (!strncmp(cmd, "release", 7) && strlen(cmd) == 7) {
- unlock_all();
- return;
- }
-
- if (!strncmp(cmd, "release-kill", 12) && strlen(cmd) == 12) {
- unlock_all();
- exit(0);
- }
-
- if (!strncmp(cmd, "dump", 4) && strlen(cmd) == 4) {
- dump();
- return;
- }
-
- if (!strncmp(cmd, "stress", 6) && strlen(cmd) == 6) {
- if (iterations && !x)
- x = iterations;
- stress(x);
- return;
- }
-
- if (!strncmp(cmd, "tstress", 7) && strlen(cmd) == 7) {
- tstress(x);
- return;
- }
-
- if (!strncmp(cmd, "dstress", 7) && strlen(cmd) == 7) {
- dstress(x);
- return;
- }
-
- if (!strncmp(cmd, "stress_delay", 12) && strlen(cmd) == 12) {
- stress_delay = x;
- return;
- }
-
- if (!strncmp(cmd, "stress_lock_only", 16) && strlen(cmd) == 16) {
- stress_lock_only = !stress_lock_only;
- printf("stress_lock_only is %s\n", stress_lock_only ? "on" : "off");
- return;
- }
-
- if (!strncmp(cmd, "stress_stop", 11) && strlen(cmd) == 11) {
- stress_stop = !stress_stop;
- printf("stress_stop is %d\n", stress_stop);
- return;
- }
-
- if (!strncmp(cmd, "ignore_bast", 11) && strlen(cmd) == 11) {
- ignore_bast = !ignore_bast;
- printf("ignore_bast is %s\n", ignore_bast ? "on" : "off");
- return;
- }
-
- if (!strncmp(cmd, "our_xid", 7) && strlen(cmd) == 7) {
- our_xid = x;
- printf("our_xid is %llx\n", (unsigned long long)our_xid);
- return;
- }
-
-
- if (!strncmp(cmd, "purge", 5) && strlen(cmd) == 5) {
- purge(x, y);
- return;
- }
-
- if (!strncmp(cmd, "purgetest", 9) && strlen(cmd) == 9) {
- purgetest(x, y);
- return;
- }
-
- if (!strncmp(cmd, "noqueue", 7)) {
- noqueue = !noqueue;
- printf("noqueue is %s\n", noqueue ? "on" : "off");
- return;
- }
-
- if (!strncmp(cmd, "persistent", 10)) {
- persistent = !persistent;
- printf("persistent is %s\n", persistent ? "on" : "off");
- return;
- }
-
- if (!strncmp(cmd, "minhold", 7)) {
- minhold = x;
- return;
- }
-
- if (!strncmp(cmd, "timeout", 7)) {
- timeout = (uint64_t) 100 * x; /* dlm takes it in centiseconds */
- printf("timeout is %d\n", x);
- return;
- }
-
- if (!strncmp(cmd, "quiet", 5)) {
- quiet = !quiet;
- printf("quiet is %d\n", quiet);
- return;
- }
-
- if (!strncmp(cmd, "verbose", 7)) {
- verbose = !verbose;
- printf("verbose is %d\n", verbose);
- return;
- }
-
- if (!strncmp(cmd, "help", 4)) {
- print_commands();
- return;
- }
-
- if (!strncmp(cmd, "settings", 8)) {
- print_settings();
- return;
- }
-
- printf("unknown command %s\n", cmd);
-}
-
-static void print_usage(void)
-{
- printf("Options:\n");
- printf("\n");
- printf(" -n The number of locks to work with, default %d\n", MAX_LOCKS);
- printf(" -r The number of resources to work with, default %d\n", MAX_RESOURCES);
- printf(" -i Iterations in looping stress test, default 0 is no limit\n");
- printf(" -t Enable timeout warnings\n");
-}
-
-static void decode_arguments(int argc, char **argv)
-{
- int cont = 1;
- int optchar;
-
- while (cont) {
- optchar = getopt(argc, argv, "n:r:i:thVoq:v:");
-
- switch (optchar) {
-
- case 'n':
- maxn = atoi(optarg);
- break;
-
- case 'r':
- maxr = atoi(optarg);
- break;
-
- case 'i':
- iterations = atoi(optarg);
- break;
-
- case 't':
- timewarn = 1;
- break;
-
- case 'o':
- openclose_ls = 1;
- break;
-
- case 'q':
- quiet = atoi(optarg);
- break;
-
- case 'v':
- verbose = atoi(optarg);
- break;
-
- case 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case 'V':
- printf("%s (built %s %s)\n", argv[0], __DATE__, __TIME__);
- /* printf("%s\n", REDHAT_COPYRIGHT); */
- exit(EXIT_SUCCESS);
- break;
-
- case ':':
- case '?':
- fprintf(stderr, "Please use '-h' for usage.\n");
- exit(EXIT_FAILURE);
- break;
-
- case EOF:
- cont = 0;
- break;
-
- default:
- fprintf(stderr, "unknown option: %c\n", optchar);
- exit(EXIT_FAILURE);
- break;
- };
- }
-}
-
-static void sigterm_handler(int sig)
-{
- stress_stop = 1;
-}
-
-int main(int argc, char *argv[])
-{
- uint32_t major, minor, patch;
- struct lk *lk;
- int i, rv, maxi = 0, quit = 0;
-
- srandom(time(NULL));
-
- decode_arguments(argc, argv);
-
- if (maxn < maxr) {
- printf("number of resources must be >= number of locks\n");
- return -1;
- }
- if (maxn % maxr) {
- printf("number of locks must be multiple of number of resources\n");
- return -1;
- }
-
- printf("maxn = %d\n", maxn);
- printf("maxr = %d\n", maxr);
- printf("locks per resource = %d\n", maxn / maxr);
-
- signal(SIGTERM, sigterm_handler);
-
- client_init();
-
- locks = malloc(maxn * sizeof(struct lk));
- if (!locks) {
- printf("no mem for %d locks\n", maxn);
- return 0;
- }
- memset(locks, 0, sizeof(*locks));
-
- lk = locks;
- for (i = 0; i < maxn; i++) {
- lk->id = i;
- lk->grmode = -1;
- lk->rqmode = -1;
- lk++;
- }
-
- rv = dlm_kernel_version(&major, &minor, &patch);
- if (rv < 0) {
- printf("can't detect dlm in kernel %d\n", errno);
- return -1;
- }
- printf("dlm kernel version: %u.%u.%u\n", major, minor, patch);
- dlm_library_version(&major, &minor, &patch);
- printf("dlm library version: %u.%u.%u\n", major, minor, patch);
-
- if (openclose_ls) {
- printf("dlm_open_lockspace...\n");
-
- dh = dlm_open_lockspace("test");
- if (!dh) {
- printf("dlm_open_lockspace error %lu %d\n",
- (unsigned long)dh, errno);
- return -ENOTCONN;
- }
- } else {
- printf("dlm_new_lockspace...\n");
-
- dh = dlm_new_lockspace("test", 0600,
- timewarn ? DLM_LSFL_TIMEWARN : 0);
- if (!dh) {
- printf("dlm_new_lockspace error %lu %d\n",
- (unsigned long)dh, errno);
- return -ENOTCONN;
- }
- }
-
- rv = dlm_ls_get_fd(dh);
- if (rv < 0) {
- printf("dlm_ls_get_fd error %d %d\n", rv, errno);
- dlm_release_lockspace("test", dh, 1);
- return rv;
- }
- libdlm_fd = rv;
-
- client_add(libdlm_fd, &maxi);
-
- client_add(STDIN_FILENO, &maxi);
-
- printf("Type EXIT to finish, help for usage\n");
-
- while (1) {
- rv = poll(pollfd, maxi + 1, -1);
- if (rv < 0 && errno == EINTR)
- continue;
- if (rv < 0)
- printf("poll error %d errno %d\n", rv, errno);
-
- for (i = 0; i <= maxi; i++) {
- if (client[i].fd < 0)
- continue;
-
- if (pollfd[i].revents & POLLIN) {
- if (pollfd[i].fd == libdlm_fd)
- process_libdlm();
- else if (pollfd[i].fd == STDIN_FILENO)
- process_command(&quit);
- }
-
- if (pollfd[i].revents & (POLLHUP | POLLERR | POLLNVAL))
- client_dead(i);
- }
-
- if (quit && all_unlocks_done())
- break;
- }
-
- if (openclose_ls) {
- printf("dlm_close_lockspace\n");
-
- rv = dlm_close_lockspace(dh);
- if (rv < 0)
- printf("dlm_close_lockspace error %d %d\n", rv, errno);
- } else {
- printf("dlm_release_lockspace\n");
-
- rv = dlm_release_lockspace("test", dh, 1);
- if (rv < 0)
- printf("dlm_release_lockspace error %d %d\n", rv, errno);
- }
-
- return 0;
-}
-
diff --git a/dlm/tests/usertest/flood.c b/dlm/tests/usertest/flood.c
deleted file mode 100644
index c01bc0d..0000000
--- a/dlm/tests/usertest/flood.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* Flood the DLM !
- but not too much...
-*/
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/poll.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <unistd.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "libdlm.h"
-
-static pthread_cond_t cond;
-static pthread_mutex_t mutex;
-
-static int count = 0;
-
-static void usage(char *prog, FILE *file)
-{
- fprintf(file, "Usage:\n");
- fprintf(file, "%s [mcnpquhV] <lockname>\n", prog);
- fprintf(file, "\n");
- fprintf(file, " -V Show version of %s\n", prog);
- fprintf(file, " -h Show this help information\n");
- fprintf(file, " -m <num> Maximum number of locks to hold (default 100000)\n");
- fprintf(file, " -i <num> Show progress in <n> increments (default 1000)\n");
- fprintf(file, " -n <num> Number of resources (default 10)\n");
- fprintf(file, " -q Quit\n");
-
-
- fprintf(file, "\n");
-
-}
-
-static void ast_routine(void *arg)
-{
- struct dlm_lksb *lksb = arg;
-
- if (lksb->sb_status == 0) {
- dlm_unlock(lksb->sb_lkid, 0, lksb, lksb);
- return;
- }
-
- if (lksb->sb_status == EUNLOCK) {
- count--;
- }
-}
-
-int main(int argc, char *argv[])
-{
- int flags = 0;
- int lockops = 0;
- int maxlocks = 100000;
- int rescount = 10;
- int increment = 1000;
- int quiet = 0;
- int status;
- int i;
- int mode = LKM_CRMODE;
- int lksbnum = 0;
- signed char opt;
- char **resources;
- struct dlm_lksb *lksbs;
-
- /* Deal with command-line arguments */
- opterr = 0;
- optind = 0;
- while ((opt=getopt(argc,argv,"?m:i:qn:vV")) != EOF)
- {
- switch(opt)
- {
- case 'h':
- usage(argv[0], stdout);
- exit(0);
-
- case '?':
- usage(argv[0], stderr);
- exit(0);
-
- case 'm':
- maxlocks = atoi(optarg);
- break;
-
- case 'i':
- increment = atoi(optarg);
- break;
-
- case 'n':
- rescount = atoi(optarg);
- break;
-
- case 'q':
- quiet = 1;
- break;
-
- case 'V':
- printf("\nflood version 0.3\n\n");
- exit(1);
- break;
- }
- }
-
- if ((resources = malloc(sizeof(char*) * rescount)) == NULL)
- {
- perror("exhausted virtual memory");
- return 1;
- }
- for (i=0; i < rescount; i++) {
- char resname[256];
- sprintf(resname, "TESTLOCK%d", i);
- resources[i] = strdup(resname);
- }
-
- lksbs = malloc(sizeof(struct dlm_lksb) * maxlocks);
- if (!lksbs)
- {
- perror("cannot allocate lksbs");
- return 1;
- }
-
- pthread_cond_init(&cond, NULL);
- pthread_mutex_init(&mutex, NULL);
- pthread_mutex_lock(&mutex);
-
- dlm_pthread_init();
-
- while (1) {
- char *resource = resources[rand() % rescount];
-
- status = dlm_lock(mode,
- &lksbs[lksbnum],
- flags,
- resource,
- strlen(resource),
- 0, // Parent,
- ast_routine,
- &lksbs[lksbnum],
- NULL, // bast_routine,
- NULL); // Range
- if (status == -1)
- {
- perror("lock failed");
- return -1;
- }
-
- count++;
- lockops++;
- if ((lockops % increment) == 0 && !quiet)
- fprintf(stderr, "%d lockops, %d locks\n", lockops, count);
-
- while (count > maxlocks) {
- sleep(1);
- }
- lksbnum = (lksbnum+1)%maxlocks;
- }
-
- return 0;
-}
diff --git a/dlm/tests/usertest/joinleave.c b/dlm/tests/usertest/joinleave.c
deleted file mode 100644
index 5dc2c3e..0000000
--- a/dlm/tests/usertest/joinleave.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/time.h>
-#include <syslog.h>
-#include <sys/types.h>
-#include <sys/errno.h>
-
-#include "libdlm.h"
-
-static dlm_lshandle_t *dh;
-
-int main(int argc, char *argv[])
-{
- struct timeval begin, end, diff;
- char *name;
- int sec = 0;
-
- if (argc < 2) {
- printf("%s <lockspace name> [sleep sec]\n", argv[0]);
- exit(-1);
- }
-
- name = argv[1];
-
- if (argc > 2)
- sec = atoi(argv[2]);
-
- printf("Joining lockspace \"%s\" ... ", name);
- fflush(stdout);
-
- gettimeofday(&begin, NULL);
- dh = dlm_create_lockspace(name, 0600);
- if (!dh) {
- printf("dlm_create_lockspace error %p %d\n", dh, errno);
- return -ENOTCONN;
- }
- gettimeofday(&end, NULL);
-
- timersub(&end, &begin, &diff);
- printf("%lu s\n", diff.tv_sec);
-
- if (sec)
- sleep(sec);
-
- printf("Leaving lockspace \"%s\" ... ", name);
- fflush(stdout);
-
- gettimeofday(&begin, NULL);
- dlm_release_lockspace(name, dh, 1);
- gettimeofday(&end, NULL);
-
- timersub(&end, &begin, &diff);
- printf("%lu s\n", diff.tv_sec);
-
- return 0;
-}
-
diff --git a/dlm/tests/usertest/lstest.c b/dlm/tests/usertest/lstest.c
deleted file mode 100644
index ef582bf..0000000
--- a/dlm/tests/usertest/lstest.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/* Test program for userland lockspaces */
-
-#ifdef _REENTRANT
-#include <pthread.h>
-#endif
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/poll.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <unistd.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "libdlm.h"
-
-static struct dlm_lksb lksb;
-static int use_threads = 0;
-static int quiet = 0;
-
-/* Used by the pthread test */
-static pthread_cond_t cond;
-static pthread_mutex_t mutex;
-
-/* Used by the poll() test */
-static int ast_called = 0;
-
-static int modetonum(char *modestr)
-{
- int mode = LKM_EXMODE;
-
- if (strncasecmp(modestr, "NL", 2) == 0) mode = LKM_NLMODE;
- if (strncasecmp(modestr, "CR", 2) == 0) mode = LKM_CRMODE;
- if (strncasecmp(modestr, "CW", 2) == 0) mode = LKM_CWMODE;
- if (strncasecmp(modestr, "PR", 2) == 0) mode = LKM_PRMODE;
- if (strncasecmp(modestr, "PW", 2) == 0) mode = LKM_PWMODE;
- if (strncasecmp(modestr, "EX", 2) == 0) mode = LKM_EXMODE;
-
- return mode;
-}
-
-static const char *numtomode(int mode)
-{
- switch (mode)
- {
- case LKM_NLMODE: return "NL";
- case LKM_CRMODE: return "CR";
- case LKM_CWMODE: return "CW";
- case LKM_PRMODE: return "PR";
- case LKM_PWMODE: return "PW";
- case LKM_EXMODE: return "EX";
- default: return "??";
- }
-}
-
-static void usage(char *prog, FILE *file)
-{
- fprintf(file, "Usage:\n");
- fprintf(file, "%s [mcnpqdlrfuhV] <lockname>\n", prog);
- fprintf(file, "\n");
- fprintf(file, " -V Show version of dlmtest\n");
- fprintf(file, " -h Show this help information\n");
- fprintf(file, " -m <mode> lock mode (default EX)\n");
- fprintf(file, " -n don't block\n");
- fprintf(file, " -p Use pthreads\n");
- fprintf(file, " -q Quiet\n");
- fprintf(file, " -d <secs> Delay betwen lock & unlock\n");
- fprintf(file, " -l <ls> Lockspace name to create\n");
- fprintf(file, " -r Don't release lockspace before finishing\n");
- fprintf(file, " -f Force release lockspace\n");
- fprintf(file, " -u Don't unlock explicitly\n");
- fprintf(file, "\n");
-
-}
-
-static void ast_routine(void *arg)
-{
- struct dlm_lksb *alksb = arg;
-
- if (!quiet)
- printf("ast called, status = %d, lkid=%x\n", alksb->sb_status, alksb->sb_lkid);
-
- /* Wake the main thread */
- if (use_threads)
- {
- pthread_mutex_lock(&mutex);
- pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
- }
- else
- {
- ast_called = 1;
- }
-}
-
-static void bast_routine(void *arg)
-{
- struct dlm_lksb *blksb = arg;
-
- if (!quiet)
- printf("\nblocking ast called, status = %d, lkid=%x\n", blksb->sb_status, blksb->sb_lkid);
-}
-
-/* Using poll(2) to wait for and dispatch ASTs */
-static int poll_for_ast(dlm_lshandle_t ls)
-{
- struct pollfd pfd;
-
- pfd.fd = dlm_ls_get_fd(ls);
- pfd.events = POLLIN;
- while (!ast_called)
- {
- if (poll(&pfd, 1, 0) < 0)
- {
- perror("poll");
- return -1;
- }
- dlm_dispatch(dlm_ls_get_fd(ls));
- }
- ast_called = 0;
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- const char *resource = "LOCK-NAME";
- int flags = 0;
- int status;
- int mode = LKM_EXMODE;
- int do_unlock = 1;
- int release_ls = 1;
- int open_ls = 0;
- int force = 0;
- int sleeptime = 5;
- signed char opt;
- char lsname[64];
- dlm_lshandle_t ls;
-
- strcpy(lsname, "testls");
-
- /* Deal with command-line arguments */
- opterr = 0;
- optind = 0;
- while ((opt=getopt(argc,argv,"?m:nqupd:c:l:rfoV")) != EOF)
- {
- switch(opt)
- {
- case 'h':
- usage(argv[0], stdout);
- exit(0);
-
- case '?':
- usage(argv[0], stderr);
- exit(0);
-
- case 'm':
- mode = modetonum(optarg);
- break;
-
- case 'l':
- strcpy(lsname, optarg);
- break;
-
- case 'd':
- sleeptime = atoi(optarg);
- break;
-
- case 'p':
- use_threads++;
- break;
-
- case 'o':
- open_ls++;
- break;
-
- case 'f':
- force++;
- break;
-
- case 'r':
- release_ls = 0;
- break;
-
- case 'n':
- flags |= LKF_NOQUEUE;
- break;
-
- case 'q':
- quiet = 1;
- break;
-
- case 'u':
- do_unlock = 0;
- break;
-
- case 'V':
- printf("\nasttest version 0.2\n\n");
- exit(1);
- break;
- }
- }
-
- if (argv[optind])
- resource = argv[optind];
-
-
- if (!open_ls)
- {
- if (!quiet)
- fprintf(stderr, "Creating lockspace %s\n", lsname);
-
-
- ls = dlm_create_lockspace(lsname, 0444);
- if (ls == NULL)
- {
- perror("ls create");
- exit(4);
- }
- }
- else
- {
- if (!quiet)
- fprintf(stderr, "Opening lockspace %s\n", lsname);
-
-
- ls = dlm_open_lockspace(lsname);
- if (ls == NULL)
- {
- perror("ls open");
- exit(4);
- }
- }
-
-
- if (!quiet)
- fprintf(stderr, "locking %s %s %s...", resource,
- numtomode(mode),
- (flags&LKF_NOQUEUE?"(NOQUEUE)":""));
-
- fflush(stderr);
-
- if (use_threads)
- {
- pthread_cond_init(&cond, NULL);
- pthread_mutex_init(&mutex, NULL);
- pthread_mutex_lock(&mutex);
-
- status = dlm_ls_pthread_init(ls); printf("status=%d\n", status);
- status = dlm_ls_pthread_init(ls); printf("status=%d\n", status);
- }
-
- status = dlm_ls_lock(ls,mode,
- &lksb,
- flags,
- resource,
- strlen(resource),
- 0, // Parent,
- ast_routine,
- &lksb,
- bast_routine,
- NULL); // Range
- if (status == -1)
- {
- if (!quiet) fprintf(stderr, "\n");
- perror("lock");
-
- return -1;
- }
-
- /* Wait */
- if (use_threads)
- pthread_cond_wait(&cond, &mutex);
- else
- poll_for_ast(ls);
-
- sleep(sleeptime);
-
- if (!quiet)
- {
- fprintf(stderr, "unlocking %s...", resource);
- fflush(stderr);
- }
-
- if (do_unlock)
- {
- status = dlm_ls_unlock(ls,
- lksb.sb_lkid,
- 0, // flags
- &lksb,
- &lksb); // AST args
- if (status == -1)
- {
- if (!quiet) fprintf(stderr, "\n");
- perror("unlock");
- return -1;
- }
-
- /* Wait */
- if (use_threads)
- pthread_cond_wait(&cond, &mutex);
- else
- poll_for_ast(ls);
- }
-
- if (release_ls)
- {
- if (!quiet)
- fprintf(stderr, "Releasing ls %s\n", lsname);
-
- status = dlm_release_lockspace(lsname, ls, force);
- if (status)
- perror("release ls");
- }
-
- return 0;
-}
-
diff --git a/dlm/tests/usertest/lvb.c b/dlm/tests/usertest/lvb.c
deleted file mode 100644
index db2ce32..0000000
--- a/dlm/tests/usertest/lvb.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/* Simple LVB test prog */
-
-#ifdef VMS
-#include starlet
-#include psldef
-#include ssdef
-#include errno
-#include descrip
-#include rsdmdef
-#include lckdef
-
-#include stdio
-#include stdlib
-#include string
-
-struct lksb
-{
- int sb_status;
- int sb_lkid;
- char sb_lvb[16];
-};
-#endif
-
-#ifdef __linux__
-#include <stdio.h>
-#include <pthread.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libdlm.h>
-#include <unistd.h>
-#define LCK$M_VALBLK LKF_VALBLK
-#define LCK$M_CONVERT LKF_CONVERT
-#define LCK$K_CRMODE LKM_CRMODE
-#define LCK$K_PWMODE LKM_PWMODE
-#define PSL$C_USER 0
-#define SS$_NORMAL 0
-#define SS$_DEADLOCK EDEADLOCK
-#define EVMSERR errno
-#define sys$exit exit
-#define sys$hiber pause
-
-
-struct lksb {
- int sb_status;
- uint32_t sb_lkid;
- char sb_flags;
- char *sb_lvb;
-};
-
-struct dsc$descriptor_s
-{
- int dsc$w_length;
- char *dsc$a_pointer;
-};
-
-static int sys$enq(int efn, int mode, struct lksb *lksb, int flags,
- struct dsc$descriptor_s *name, int parent,
- void *compast, void *astarg, void *blockast,
- int accmode, int nullarg)
-{
- if (name)
- return dlm_lock(mode, (struct dlm_lksb *)lksb, flags,
- name->dsc$a_pointer,
- name->dsc$w_length,
- parent,
- compast, astarg,
- blockast, NULL);
- else
- return dlm_lock(mode, (struct dlm_lksb *)lksb, flags,
- NULL,
- 0,
- parent,
- compast, astarg,
- blockast, NULL);
-}
-
-static int sys$deq(int lkid, struct lksb *lksb, int accmode, int flags, int c)
-{
- return dlm_unlock(lkid, flags, (struct dlm_lksb *)lksb, NULL);
-}
-
-static char *linux_strerror(int vmserr, int err)
-{
- return strerror(err);
-}
-#define strerror linux_strerror
-
-#endif
-
-
-static struct lksb our_lksb;
-static int cur_mode;
-static void compast_routine(void *arg);
-static void blockast_routine(void *arg, int mode);
-static const char *name = "TESTLOCK";
-
-#ifdef __linux__
-static char lksb_lvb[DLM_LVB_LEN];
-#endif
-
-static void start_lock(int mode)
-{
- struct dsc$descriptor_s name_s;
- int status;
-
- cur_mode = mode;
-
-/* Make a descriptor of the name */
- memset(&name_s, 0, sizeof(struct dsc$descriptor_s));
- name_s.dsc$w_length = strlen(name);
- name_s.dsc$a_pointer = (char *)name;
-
- /* Lock it */
- status = sys$enq(0,
- cur_mode,
- &our_lksb,
- LCK$M_VALBLK, /* flags */
- &name_s,
- 0, /* parent */
- compast_routine,
- 0, /* astp */
- blockast_routine,
- PSL$C_USER,
- 0);
-
- if (status != SS$_NORMAL)
- {
- printf("lock enq failed : %s\n", strerror(EVMSERR, status));
- sys$exit(status);
- }
-
- printf("Lock ID is %x\n", our_lksb.sb_lkid);
- return;
-}
-
-static int convert_lock(int mode, char *lvb)
-{
- int status;
-
- memset(our_lksb.sb_lvb, 0, 16);
- if (lvb[strlen(lvb)-1] == '\n')
- lvb[strlen(lvb)-1] = '\0';
-
- cur_mode = mode;
- strcpy(our_lksb.sb_lvb, lvb);
- printf("converting to %d\n", mode);
-
- /* Lock it */
- status = sys$enq(0,
- mode,
- &our_lksb,
- LCK$M_CONVERT | LCK$M_VALBLK,
- NULL,
- 0, /* parent */
- compast_routine,
- 0, /* astp */
- blockast_routine,
- PSL$C_USER,
- 0);
-
- if (status != SS$_NORMAL)
- {
- printf("convert enq failed : %s\n", strerror(EVMSERR, status));
- }
-
- return status;
-}
-
-static void unlock(void)
-{
- int status;
-
- status = sys$deq(our_lksb.sb_lkid, NULL,0,0,0);
- if (status != SS$_NORMAL)
- {
- printf("denq failed : %s\n", strerror(EVMSERR, status));
- }
-}
-
-static void compast_routine(void *arg)
-{
-#ifdef __linux__
- if (our_lksb.sb_flags & DLM_SBF_VALNOTVALID)
- {
- printf("testlock: LVB not valid\n");
- sys$hiber();
- }
-#endif
- if (our_lksb.sb_status == SS$_DEADLOCK)
- {
- printf("testlock: deadlocked\n");
- unlock();
- return;
- }
-
- if (our_lksb.sb_status == SS$_NORMAL)
- {
- printf("testlock. compast, now at %d, lvb=%s\n", cur_mode, our_lksb.sb_lvb);
- }
- else
- {
- printf("testlock: lock failed (compast): %s\n", strerror(EVMSERR, our_lksb.sb_status));
- sys$hiber();
- }
-}
-
-static void blockast_routine(void *arg, int mode)
-{
- printf("testlock. blkast.\n");
-}
-
-int main(int argc, char *argv[])
-{
- char buf[80];
-
-#ifdef __linux__
- our_lksb.sb_lvb = lksb_lvb;
- dlm_pthread_init();
-#endif
-
- if (argc > 1)
- name = argv[1];
-
- start_lock(LCK$K_CRMODE);
-
- do {
- char cmd;
-
- fgets(buf, sizeof(buf), stdin);
- cmd = buf[0] & 0x5F;
-
- if (cmd == 'W')
- convert_lock(LCK$K_CRMODE, &buf[1]);
- else
- convert_lock(LCK$K_PWMODE, &buf[1]);
- }
- while (buf[0] != 'x');
-
- return SS$_NORMAL;
-}
-
diff --git a/dlm/tests/usertest/pingtest.c b/dlm/tests/usertest/pingtest.c
deleted file mode 100644
index 2fdbf18..0000000
--- a/dlm/tests/usertest/pingtest.c
+++ /dev/null
@@ -1,343 +0,0 @@
-
-/* Ping Test the locking interface */
-
-#ifdef __linux__
-#include <pthread.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <netdb.h>
-#include <unistd.h>
-
-#include <libdlm.h>
-
-static char our_lvb[DLM_LVB_LEN];
-static struct dlm_lksb our_lksb = {.sb_lvbptr = our_lvb};
-static int *lvb_int = (int *)our_lvb;
-#define SUCCESS 0
-#endif
-
-
-#ifdef VMS
-#include starlet
-#include psldef
-#include ssdef
-#include errno
-#include descrip
-#include rsdmdef
-#include lckdef
-
-#include stdio
-#include stdlib
-#include string
-
-struct lksb
-{
- int sb_status;
- int sb_lkid;
- char sb_lvb[16];
-};
-
-static struct lksb our_lksb;
-static int *lvb_int = (int *)&our_lksb.sb_lvb;
-
-#define LKM_NLMODE LCK$K_NLMODE
-#define LKM_CRMODE LCK$K_CRMODE
-#define LKM_CWMODE LCK$K_CWMODE
-#define LKM_PRMODE LCK$K_PRMODE
-#define LKM_PWMODE LCK$K_PWMODE
-#define LKM_EXMODE LCK$K_EXMODE
-#define EDEADLOCK SS$_DEADLOCK
-
-/* This is wrong...VMS does not deliver ASTs
- for $DEQ but we'll never get this code, honest.
- */
-#define EUNLOCK 65535
-
-#define SUCCESS SS$_NORMAL
-#endif
-
-static const char *lockname="ping";
-static int us = 1;
-static int maxnode = 2;
-static int cur_mode;
-
-static int granted = 0;
-static void compast_routine(void *arg);
-static void blockast_routine(void *arg);
-
-#ifdef __linux__
-static int convert_lock(int mode)
-{
- int status;
-
- printf("pinglock: convert to %d starting\n", mode);
- status = dlm_lock( mode,
- &our_lksb,
- LKF_VALBLK | LKF_CONVERT,
- NULL,
- 0,
- 0,
- compast_routine,
- &our_lksb,
- blockast_routine,
- NULL);
- if (status != 0)
- {
- perror("pinglock: convert failed");
- }
- else
- {
- cur_mode = mode;
- printf("pinglock: convert to %d started\n", mode);
- }
- return status;
-}
-
-static void unlock(void)
-{
- int status;
- status = dlm_unlock( our_lksb.sb_lkid,
- 0,
- &our_lksb,
- 0);
- if (status != 0)
- perror("pinglock: unlock failed");
-
-}
-
-static void start_lock(void)
-{
- int status;
- cur_mode = LKM_EXMODE;
-
- *lvb_int = us-1;
-
- printf("pinglock: starting\n");
- status = dlm_lock( cur_mode,
- &our_lksb,
- LKF_VALBLK,
- lockname,
- strlen(lockname)+1, /* include trailing NUL for ease of following */
- 0, /* Parent */
- compast_routine,
- &our_lksb,
- blockast_routine,
- NULL);
- if (status != 0)
- perror("pinglock: lock failed");
-}
-
-#endif /* __linux__ */
-
-#ifdef VMS
-
-static void start_lock()
-{
- struct dsc$descriptor_s name_s;
- int status;
- char *name = "PINGLOCK";
-
- cur_mode = LCK$K_EXMODE;
-
- *lvb_int = us-1;
-
-/* Make a descriptor of the name */
- memset(&name_s, 0, sizeof(struct dsc$descriptor_s));
- name_s.dsc$w_length = strlen(name);
- name_s.dsc$a_pointer = name;
-
- /* Lock it */
- status = sys$enqw(0,
- cur_mode,
- &our_lksb,
- 0, /* flags */
- &name_s,
- 0, /* parent */
- compast_routine,
- 0, /* astp */
- blockast_routine,
- PSL$C_USER,
- RSDM$K_PROCESS_RSDM_ID,
- 0);
-
- if (status != SS$_NORMAL)
- {
- printf("lock enq failed : %s\n", strerror(EVMSERR, status));
- sys$exit(status);
- }
-
- printf("Lock ID is %x\n", our_lksb.sb_lkid);
- return;
-}
-
-static int convert_lock(int mode)
-{
- int status;
- int old_mode = cur_mode;
-
- printf("converting to %d\n", mode);
-
- /* Lock it */
- status = sys$enq(0,
- mode,
- &our_lksb,
- LCK$M_CONVERT | LCK$M_VALBLK,
- NULL,
- 0, /* parent */
- compast_routine,
- 0, /* astp */
- blockast_routine,
- PSL$C_USER,
- RSDM$K_PROCESS_RSDM_ID,
- 0);
-
- if (status != SS$_NORMAL)
- {
- printf("convert enq failed : %s\n", strerror(EVMSERR, status));
- sys$wake();
- }
- else
- {
- cur_mode = mode;
- status = 0; /* simulate Unix retcodes */
- }
- return status;
-}
-
-static void unlock()
-{
- int status;
-
- status = sys$deq(our_lksb.sb_lkid, NULL,0,0,0);
- if (status != SS$_NORMAL)
- {
- printf("denq failed : %s\n", strerror(EVMSERR, status));
- sys$wake();
- }
-}
-
-#endif
-
-static void compast_routine(void *arg)
-{
-
-#ifdef __linux__
- if (our_lksb.sb_flags & DLM_SBF_VALNOTVALID)
-#endif
-#ifdef VMS
- if (our_lksb.sb_status == SS$_VALNOTVALID)
-#endif
- {
- printf(" valblk not valid. current value is %d\n", *lvb_int);
- unlock();
- exit(10);
- }
-
- if (our_lksb.sb_status == EDEADLOCK)
- {
- printf("pinglock: deadlocked\n");
- unlock();
- exit(11);
- }
-
- if (our_lksb.sb_status == EUNLOCK)
- {
- return;
- }
-
- if (our_lksb.sb_status == SUCCESS)
- {
- granted = 1;
- switch (cur_mode)
- {
- case LKM_NLMODE:
- printf("pinglock. compast, (valblk = %d) now at NL\n", *lvb_int);
- if (convert_lock(LKM_CRMODE) == 0)
- granted = 0;
- break;
-
- case LKM_CRMODE:
- printf("pinglock. compast, (valblk = %d) now at CR\n", *lvb_int);
- if (*lvb_int == us-1)
- {
- if (convert_lock(LKM_EXMODE) == 0)
- granted = 0;
- }
- break;
-
- case LKM_EXMODE:
- printf("pinglock. compast. (valblk = %d) now at EX\n", *lvb_int);
- if (*lvb_int == us-1)
- {
- (*lvb_int)++;
- *lvb_int %= maxnode;
- printf("pinglock. compast. incrementing valblk to %d\n", *lvb_int);
- }
- if (convert_lock(LKM_CRMODE) == 0)
- granted = 0;
- break;
- }
- }
- else
- {
- printf("pinglock: lock failed (compast): %d\n", our_lksb.sb_status);
- unlock();
- }
-}
-
-static void blockast_routine(void *arg)
-{
- printf("pinglock. blkast, granted = %d\n", granted);
- if (!granted)
- {
- return;
- }
-
- printf("pinglock. blkast, demoting lock to NL\n");
- if (convert_lock(LKM_NLMODE) == 0)
- granted = 0;
-}
-
-
-#ifdef __linux__
-int main(int argc, char *argv[])
-{
- if (argc < 3)
- {
- printf("usage: %s <maxnodes> <us>\n", argv[0]);
- return 2;
- }
- maxnode = atoi(argv[1]);
- us = atoi(argv[2]);
-
- dlm_pthread_init();
- start_lock();
- while(1)
- sleep(100000);
- return 0;
-}
-
-
-#endif
-
-#ifdef VMS
-int main(int argc, char *argv[])
-{
- if (argc < 3)
- {
- printf("usage: %s <maxnodes> <us>\n", argv[0]);
- return 2;
- }
- maxnode = atoi(argv[1]);
- us = atoi(argv[2]);
-
- start_lock();
- while(1)
- sys$hiber();
-
- return SS$_NORMAL;
-}
-#endif
diff --git a/dlm/tests/usertest/sublocks.c b/dlm/tests/usertest/sublocks.c
deleted file mode 100644
index d994b86..0000000
--- a/dlm/tests/usertest/sublocks.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/* Test program for userland DLM interface */
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <unistd.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "libdlm.h"
-
-static int modetonum(char *modestr)
-{
- int mode = LKM_EXMODE;
-
- if (strncasecmp(modestr, "NL", 2) == 0) mode = LKM_NLMODE;
- if (strncasecmp(modestr, "CR", 2) == 0) mode = LKM_CRMODE;
- if (strncasecmp(modestr, "CW", 2) == 0) mode = LKM_CWMODE;
- if (strncasecmp(modestr, "PR", 2) == 0) mode = LKM_PRMODE;
- if (strncasecmp(modestr, "PW", 2) == 0) mode = LKM_PWMODE;
- if (strncasecmp(modestr, "EX", 2) == 0) mode = LKM_EXMODE;
-
- return mode;
-}
-
-static void usage(char *prog, FILE *file)
-{
- fprintf(file, "Usage:\n");
- fprintf(file, "%s [mndvV] <parent>\n", prog);
- fprintf(file, "\n");
- fprintf(file, " -V Show version of %s\n", prog);
- fprintf(file, " -h Show this help information\n");
- fprintf(file, " -v Do it verbosely\n");
- fprintf(file, " -m <mode> lock mode (default CR)\n");
- fprintf(file, " -p Pause at end\n");
- fprintf(file, " -d <num> Depth of lock tree (default 4)\n");
- fprintf(file, " -n <num> Number of children (default 4)\n");
- fprintf(file, " -s <name> Subresource name (eg SUBRES-%%d)\n");
- fprintf(file, "\n");
-
-}
-
-int maxdepth = 4;
-int nchildren = 4;
-int verbose = 0;
-char *subresformat="SUBRES-%d-%d";
-
-
-int do_childlocks(int parent, int mode, int depth, int flags)
-{
- int status;
- int i;
- char subresname[64];
- struct dlm_lksb lksb;
-
- if (depth > maxdepth) return 0;
-
- memset(&lksb, 0, sizeof(lksb));
-
- for (i = 0; i < nchildren; i++)
- {
- sprintf(subresname, subresformat, depth, i);
-
- if (verbose)
- printf("locking '%s', depth %d\n", subresname, depth);
-
- status = dlm_lock_wait(mode, &lksb, flags, subresname, strlen(subresname)+1,
- parent, NULL, NULL, NULL);
- if (status || !lksb.sb_lkid)
- {
- perror("lock failed");
- return 0;
- }
- do_childlocks(lksb.sb_lkid, mode, depth+1, flags);
- }
- return 0;
-}
-
-
-int main(int argc, char *argv[])
-{
- char *resource = "LOCK-NAME";
- int flags = 0;
- int status;
- int mode = LKM_CRMODE;
- int pause_at_end=0;
- struct dlm_lksb lksb;
- signed char opt;
-
- /* Deal with command-line arguments */
- opterr = 0;
- optind = 0;
- while ((opt=getopt(argc,argv,"?m:n:d:s:pvV")) != EOF)
- {
- switch(opt)
- {
- case 'h':
- usage(argv[0], stdout);
- exit(0);
-
- case '?':
- usage(argv[0], stderr);
- exit(0);
-
- case 'm':
- mode = modetonum(optarg);
- break;
-
- case 'v':
- verbose++;
- break;
-
- case 'p':
- pause_at_end++;
- break;
-
- case 'd':
- maxdepth = atoi(optarg);
- break;
-
- case 'n':
- nchildren = atoi(optarg);
- break;
-
- case 's':
- strcpy(subresformat, optarg);
- break;
-
- case 'V':
- printf("\n%s version 0.1\n\n", argv[0]);
- exit(1);
- break;
- }
- }
-
- if (argv[optind])
- resource = argv[optind];
-
- /* Lock parent */
- if (verbose)
- fprintf(stderr, "locking parent '%s'\n", resource);
-
- fflush(stderr);
-
- status = dlm_lock_wait(mode, &lksb, flags,
- resource, strlen(resource)+1,
- 0, NULL, NULL, NULL);
- if (status == -1)
- {
- perror("lock");
- return -1;
- }
-
- if (lksb.sb_lkid == 0)
- {
- fprintf(stderr, "error: got lockid of zero\n");
- return 0;
- }
-
- do_childlocks(lksb.sb_lkid, mode, 0, flags);
-
- if (pause_at_end)
- {
- printf("paused\n");
- pause();
- }
- return 0;
-}
diff --git a/dlm/tests/usertest/threads.c b/dlm/tests/usertest/threads.c
deleted file mode 100644
index afbd19a..0000000
--- a/dlm/tests/usertest/threads.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Threaded DLM example
- */
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/poll.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <limits.h>
-#include <unistd.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include "libdlm.h"
-
-struct lock_wait {
- pthread_cond_t cond;
- pthread_mutex_t mutex;
- struct dlm_lksb lksb;
-};
-
-struct thread_args
-{
- dlm_lshandle_t *lockspace;
- char *resource;
- int flags;
- int delay;
- int mode;
- int verbose;
- int num;
-};
-
-static int modetonum(char *modestr)
-{
- int mode = LKM_EXMODE;
-
- if (strncasecmp(modestr, "NL", 2) == 0) mode = LKM_NLMODE;
- if (strncasecmp(modestr, "CR", 2) == 0) mode = LKM_CRMODE;
- if (strncasecmp(modestr, "CW", 2) == 0) mode = LKM_CWMODE;
- if (strncasecmp(modestr, "PR", 2) == 0) mode = LKM_PRMODE;
- if (strncasecmp(modestr, "PW", 2) == 0) mode = LKM_PWMODE;
- if (strncasecmp(modestr, "EX", 2) == 0) mode = LKM_EXMODE;
-
- return mode;
-}
-
-static void usage(char *prog, FILE *file)
-{
- fprintf(file, "Usage:\n");
- fprintf(file, "%s [mcnpquhV] <lockname>\n", prog);
- fprintf(file, "\n");
- fprintf(file, " -V show version of %s\n", prog);
- fprintf(file, " -h show this help information\n");
- fprintf(file, " -m <mode> lock mode (default EX)\n");
- fprintf(file, " -n don't block\n");
- fprintf(file, " -t <threads> number of threads\n");
- fprintf(file, " -d <secs> delay while holding lock\n");
- fprintf(file, " -l <name> lockspace name\n");
- fprintf(file, " -v verbose (up to 3)\n");
- fprintf(file, "\n");
-
-}
-
-/* Simply wakes the thread that initiated the lock */
-static void sync_ast_routine(void *arg)
-{
- struct lock_wait *lwait = arg;
-
- pthread_mutex_lock(&lwait->mutex);
- pthread_cond_signal(&lwait->cond);
- pthread_mutex_unlock(&lwait->mutex);
-}
-
-/* Get/Convert a lock and wait for it to complete (or fail) */
-static int sync_lock(dlm_lshandle_t lockspace,
- const char *resource,
- int mode,
- int flags,
- int *lockid)
-{
- int status;
- struct lock_wait lwait;
-
- if (!lockid) {
- errno = EINVAL;
- return -1;
- }
-
- /* Conversions need the lockid in the LKSB */
- if (flags & LKF_CONVERT)
- lwait.lksb.sb_lkid = *lockid;
-
- pthread_cond_init(&lwait.cond, NULL);
- pthread_mutex_init(&lwait.mutex, NULL);
- pthread_mutex_lock(&lwait.mutex);
-
- status = dlm_ls_lock(lockspace,
- mode,
- &lwait.lksb,
- flags,
- resource,
- strlen(resource),
- 0, sync_ast_routine, &lwait, NULL, NULL);
- if (status)
- return status;
-
- /* Wait for it to complete */
- pthread_cond_wait(&lwait.cond, &lwait.mutex);
- pthread_mutex_unlock(&lwait.mutex);
-
- *lockid = lwait.lksb.sb_lkid;
-
- errno = lwait.lksb.sb_status;
-
- if (lwait.lksb.sb_status)
- return -1;
- else
- return 0;
-}
-
-/* Unlock - and wait for it to complete */
-static int sync_unlock(dlm_lshandle_t lockspace, int lockid)
-{
- int status;
- struct lock_wait lwait;
-
- pthread_cond_init(&lwait.cond, NULL);
- pthread_mutex_init(&lwait.mutex, NULL);
- pthread_mutex_lock(&lwait.mutex);
-
- status = dlm_ls_unlock(lockspace, lockid, 0, &lwait.lksb, &lwait);
-
- if (status)
- return status;
-
- /* Wait for it to complete */
- pthread_cond_wait(&lwait.cond, &lwait.mutex);
- pthread_mutex_unlock(&lwait.mutex);
-
- errno = lwait.lksb.sb_status;
- if (lwait.lksb.sb_status != EUNLOCK)
- return -1;
- else
- return 0;
-
-}
-
-static void *thread_fn(void *arg)
-{
- struct thread_args *ta = arg;
- int lockid=0;
- int status;
-
- if (ta->verbose > 1)
- fprintf(stderr, "Locking in thread %lx\n", pthread_self());
-
- status = sync_lock(ta->lockspace, ta->resource,
- ta->mode, ta->flags, &lockid);
-
- if (status)
- {
- if (ta->verbose)
- fprintf(stderr, "Lock in thread %lx failed: %s\n", pthread_self(), strerror(errno));
- return NULL;
- }
-
- sleep(ta->delay);
-
- if (ta->verbose > 1)
- fprintf(stderr, "Unlocking in thread %lx\n", pthread_self());
-
- status = sync_unlock(ta->lockspace,lockid);
- if (status)
- {
- if (ta->verbose)
- fprintf(stderr, "Unlock in thread %lx failed: %s\n", pthread_self(), strerror(errno));
- }
-
- return NULL;
-}
-
-
-int main(int argc, char *argv[])
-{
- char const *resource = "LOCK-NAME";
- char const *lockspace_name = "threadtest";
- dlm_lshandle_t *lockspace;
- int flags = 0;
- int num_threads = 5;
- int delay = 1;
- int mode = LKM_EXMODE;
- int verbose = 0;
- int i;
- signed char opt;
- pthread_t *threads;
- struct thread_args ta;
-
- /* Deal with command-line arguments */
- opterr = 0;
- optind = 0;
- while ((opt=getopt(argc,argv,"h?nt:d:l:m:vV")) != EOF)
- {
- switch(opt)
- {
- case 'h':
- usage(argv[0], stdout);
- exit(0);
-
- case '?':
- usage(argv[0], stderr);
- exit(0);
-
- case 'n':
- flags |= LKF_NOQUEUE;
- break;
-
- case 't':
- num_threads = atoi(optarg);
- break;
-
- case 'm':
- mode = modetonum(optarg);
- break;
-
- case 'l':
- lockspace_name = strdup(optarg);
- break;
-
- case 'd':
- delay = atoi(optarg);
- break;
-
- case 'v':
- verbose++;
- break;
-
- case 'V':
- printf("\nthread example version 0.1\n\n");
- exit(1);
- break;
- }
- }
-
- if (argv[optind])
- resource = argv[optind];
-
- if (verbose)
- fprintf(stderr, "Creating lockspace '%s'...", lockspace_name);
-
- /* You need to be root to create the lockspace ... but not to use it */
- lockspace = dlm_create_lockspace(lockspace_name, 0666);
- if (!lockspace) {
- perror("Unable to create lockspace");
- return 1;
- }
- if (verbose)
- fprintf(stderr, "done\n");
-
- dlm_ls_pthread_init(lockspace);
-
- threads = malloc(sizeof(pthread_t) * num_threads);
- if (!threads)
- {
- perror("can't malloc threads array");
- return 2;
- }
-
- if (verbose)
- fprintf(stderr, "Starting threads\n");
-
- ta.lockspace = lockspace;
- ta.mode = mode;
- ta.flags = flags;
- ta.delay = delay;
- ta.verbose = verbose;
- ta.resource = (char *)resource;
-
- for (i=0; i<num_threads; i++)
- {
- if (verbose > 2)
- fprintf(stderr, "Starting thread %d\n", i);
-
- pthread_create(&threads[i], NULL, thread_fn, &ta);
- }
-
- if (verbose)
- fprintf(stderr, "All threads started\n");
-
- for (i=0; i<num_threads; i++)
- {
- void *status;
- if (verbose > 2)
- fprintf(stderr, "Waiting for thread %d\n", i);
- pthread_join(threads[i], &status);
- }
-
- return 0;
-}
-
diff --git a/dlm/tool/Makefile b/dlm/tool/Makefile
deleted file mode 100644
index 9d75b6c..0000000
--- a/dlm/tool/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-TARGET= dlm_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
-
-CFLAGS += -I${dlmincdir} -I${dlmcontrolincdir}
-CFLAGS += -I$(SRCDIR)/group/dlm_controld/
-CFLAGS += -I${incdir}
-CFLAGS += -I${KERNEL_SRC}/include/
-
-LDFLAGS += -L${dlmlibdir} -L${dlmcontrollibdir} -ldlm -ldlmcontrol
-LDFLAGS += -L${libdir}
-
-${TARGET}: ${OBJS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-clean: generalclean
-
-depends:
- $(MAKE) -C ../libdlm all
- $(MAKE) -C ../libdlmcontrol all
-
--include $(OBJS:.o=.d)
diff --git a/dlm/tool/main.c b/dlm/tool/main.c
deleted file mode 100644
index 4752008..0000000
--- a/dlm/tool/main.c
+++ /dev/null
@@ -1,1324 +0,0 @@
-#include <sys/types.h>
-#include <sys/un.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <netinet/in.h>
-
-#include <linux/dlmconstants.h>
-#include "libdlm.h"
-#include "libdlmcontrol.h"
-#include "copyright.cf"
-
-#define LKM_IVMODE -1
-
-#define OP_JOIN 1
-#define OP_LEAVE 2
-#define OP_JOINLEAVE 3
-#define OP_LIST 4
-#define OP_DEADLOCK_CHECK 5
-#define OP_DUMP 6
-#define OP_PLOCKS 7
-#define OP_LOCKDUMP 8
-#define OP_LOCKDEBUG 9
-#define OP_LOG_PLOCK 10
-
-static char *prog_name;
-static char *lsname;
-static int operation;
-static int opt_ind;
-static int ls_all_nodes = 0;
-static int opt_dir = 0;
-static int opt_excl = 0;
-static int opt_fs = 0;
-static int dump_mstcpy = 0;
-static mode_t create_mode = 0600;
-static int verbose;
-static int wide;
-static int summarize;
-
-#define MAX_LS 128
-#define MAX_NODES 128
-
-/* from linux/fs/dlm/dlm_internal.h */
-#define DLM_LKSTS_WAITING 1
-#define DLM_LKSTS_GRANTED 2
-#define DLM_LKSTS_CONVERT 3
-
-#define DLM_MSG_REQUEST 1
-#define DLM_MSG_CONVERT 2
-#define DLM_MSG_UNLOCK 3
-#define DLM_MSG_CANCEL 4
-#define DLM_MSG_REQUEST_REPLY 5
-#define DLM_MSG_CONVERT_REPLY 6
-#define DLM_MSG_UNLOCK_REPLY 7
-#define DLM_MSG_CANCEL_REPLY 8
-#define DLM_MSG_GRANT 9
-#define DLM_MSG_BAST 10
-#define DLM_MSG_LOOKUP 11
-#define DLM_MSG_REMOVE 12
-#define DLM_MSG_LOOKUP_REPLY 13
-#define DLM_MSG_PURGE 14
-
-
-struct dlmc_lockspace lss[MAX_LS];
-struct dlmc_node nodes[MAX_NODES];
-
-struct rinfo {
- int print_granted;
- int print_convert;
- int print_waiting;
- int print_lookup;
- int namelen;
- int nodeid;
- int lvb;
- unsigned int lkb_count;
- unsigned int lkb_granted;
- unsigned int lkb_convert;
- unsigned int lkb_waiting;
- unsigned int lkb_lookup;
- unsigned int lkb_wait_msg;
- unsigned int lkb_master_copy;
- unsigned int lkb_local_copy;
- unsigned int lkb_process_copy;
-};
-
-struct summary {
- unsigned int rsb_total;
- unsigned int rsb_with_lvb;
- unsigned int rsb_no_locks;
- unsigned int rsb_lookup;
- unsigned int rsb_master;
- unsigned int rsb_local;
- unsigned int rsb_nodeid_error;
- unsigned int lkb_count;
- unsigned int lkb_granted;
- unsigned int lkb_convert;
- unsigned int lkb_waiting;
- unsigned int lkb_lookup;
- unsigned int lkb_wait_msg;
- unsigned int lkb_master_copy;
- unsigned int lkb_local_copy;
- unsigned int lkb_process_copy;
- unsigned int expect_replies;
-};
-
-static const char *mode_str(int mode)
-{
- switch (mode) {
- case -1:
- return "IV";
- case LKM_NLMODE:
- return "NL";
- case LKM_CRMODE:
- return "CR";
- case LKM_CWMODE:
- return "CW";
- case LKM_PRMODE:
- return "PR";
- case LKM_PWMODE:
- return "PW";
- case LKM_EXMODE:
- return "EX";
- }
- return "??";
-}
-
-static const char *msg_str(int type)
-{
- switch (type) {
- case DLM_MSG_REQUEST:
- return "request";
- case DLM_MSG_CONVERT:
- return "convert";
- case DLM_MSG_UNLOCK:
- return "unlock ";
- case DLM_MSG_CANCEL:
- return "cancel ";
- case DLM_MSG_REQUEST_REPLY:
- return "r_reply";
- case DLM_MSG_CONVERT_REPLY:
- return "c_reply";
- case DLM_MSG_UNLOCK_REPLY:
- return "u_reply";
- case DLM_MSG_CANCEL_REPLY:
- return "c_reply";
- case DLM_MSG_GRANT:
- return "grant ";
- case DLM_MSG_BAST:
- return "bast ";
- case DLM_MSG_LOOKUP:
- return "lookup ";
- case DLM_MSG_REMOVE:
- return "remove ";
- case DLM_MSG_LOOKUP_REPLY:
- return "l_reply";
- case DLM_MSG_PURGE:
- return "purge ";
- default:
- return "unknown";
- }
-}
-
-static void print_usage(void)
-{
- printf("Usage:\n");
- printf("\n");
- printf("dlm_tool [options] [join | leave | lockdump | lockdebug |\n"
- " ls | dump | log_plock | plocks |\n"
- " deadlock_check]\n");
- printf("\n");
- printf("Options:\n");
- printf(" -n Show all node information in ls\n");
- printf(" -d <n> Resource directory off/on (0/1) in join, default 0\n");
- printf(" -e <n> Exclusive create off/on (0/1) in join, default 0\n");
- printf(" -f <n> FS memory allocation off/on (0/1) in join, default 0\n");
- printf(" -m <mode> Permission mode for lockspace device (octal), default 0600\n");
- printf(" -M Print MSTCPY locks in lockdump\n"
- " (remote locks that are locally mastered)\n");
- printf(" -s Summary following lockdebug output\n");
- printf(" (experimental, format not fixed)\n");
- printf(" -v Verbose lockdebug output\n");
- printf(" -w Wide lockdebug output\n");
- printf(" -h Print this help, then exit\n");
- printf(" -V Print program version information, then exit\n");
- printf("\n");
-}
-
-#define OPTION_STRING "MhVnd:m:e:f:vws"
-
-static void decode_arguments(int argc, char **argv)
-{
- int cont = 1;
- int optchar;
- int need_lsname;
- char modebuf[8];
-
- while (cont) {
- optchar = getopt(argc, argv, OPTION_STRING);
-
- switch (optchar) {
- case 'd':
- opt_dir = atoi(optarg);
- break;
-
- case 'e':
- opt_excl = atoi(optarg);
- break;
-
- case 'f':
- opt_fs = atoi(optarg);
- break;
-
- case 'm':
- memset(modebuf, 0, sizeof(modebuf));
- snprintf(modebuf, 8, "%s", optarg);
- sscanf(modebuf, "%o", &create_mode);
- break;
-
- case 'M':
- dump_mstcpy = 1;
- break;
-
- case 'n':
- ls_all_nodes = 1;
- break;
-
- case 's':
- summarize = 1;
- break;
-
- case 'v':
- verbose = 1;
- break;
-
- case 'w':
- wide = 1;
- break;
-
- case 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case 'V':
- printf("%s %s (built %s %s)\n",
- prog_name, RELEASE_VERSION, __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- break;
-
- case ':':
- case '?':
- fprintf(stderr, "Please use '-h' for usage.\n");
- exit(EXIT_FAILURE);
- break;
-
- case EOF:
- cont = 0;
- break;
-
- default:
- fprintf(stderr, "unknown option: %c\n", optchar);
- exit(EXIT_FAILURE);
- break;
- };
- }
-
- need_lsname = 1;
-
- while (optind < argc) {
-
- /*
- * libdlm
- */
-
- if (!strncmp(argv[optind], "join", 4) &&
- (strlen(argv[optind]) == 4)) {
- operation = OP_JOIN;
- opt_ind = optind + 1;
- break;
- } else if (!strncmp(argv[optind], "leave", 5) &&
- (strlen(argv[optind]) == 5)) {
- operation = OP_LEAVE;
- opt_ind = optind + 1;
- break;
- } else if (!strncmp(argv[optind], "joinleave", 9) &&
- (strlen(argv[optind]) == 9)) {
- operation = OP_JOINLEAVE;
- opt_ind = optind + 1;
- break;
- }
-
- /*
- * libdlmcontrol
- */
-
- else if (!strncmp(argv[optind], "ls", 2) &&
- (strlen(argv[optind]) == 2)) {
- operation = OP_LIST;
- opt_ind = optind + 1;
- need_lsname = 0;
- break;
- } else if (!strncmp(argv[optind], "deadlock_check", 14) &&
- (strlen(argv[optind]) == 14)) {
- operation = OP_DEADLOCK_CHECK;
- opt_ind = optind + 1;
- break;
- } else if (!strncmp(argv[optind], "dump", 4) &&
- (strlen(argv[optind]) == 4)) {
- operation = OP_DUMP;
- opt_ind = optind + 1;
- need_lsname = 0;
- break;
- } else if (!strncmp(argv[optind], "plocks", 6) &&
- (strlen(argv[optind]) == 6)) {
- operation = OP_PLOCKS;
- opt_ind = optind + 1;
- break;
- } else if (!strncmp(argv[optind], "log_plock", 9) &&
- (strlen(argv[optind]) == 9)) {
- operation = OP_LOG_PLOCK;
- opt_ind = optind + 1;
- need_lsname = 0;
- break;
- }
-
- /*
- * debugfs
- */
-
- else if (!strncmp(argv[optind], "lockdump", 8) &&
- (strlen(argv[optind]) == 8)) {
- operation = OP_LOCKDUMP;
- opt_ind = optind + 1;
- break;
- } else if (!strncmp(argv[optind], "lockdebug", 9) &&
- (strlen(argv[optind]) == 9)) {
- operation = OP_LOCKDEBUG;
- opt_ind = optind + 1;
- break;
- }
- optind++;
- }
-
- if (!operation || !opt_ind) {
- print_usage();
- exit(EXIT_FAILURE);
- }
-
- if (optind < argc - 1)
- lsname = argv[opt_ind];
- else if (need_lsname) {
- fprintf(stderr, "lockspace name required\n");
- exit(EXIT_FAILURE);
- }
-}
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, (char *)buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0)
- return rv;
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-static char *flag_str(uint32_t flags)
-{
- static char join_flags[128];
-
- memset(join_flags, 0, sizeof(join_flags));
-
- strcat(join_flags, "flags ");
-
- if (flags & DLM_LSFL_NODIR)
- strcat(join_flags, "NODIR ");
-
- if (flags & DLM_LSFL_NEWEXCL)
- strcat(join_flags, "NEWEXCL ");
-
- if (flags & DLM_LSFL_FS)
- strcat(join_flags, "FS ");
-
- return join_flags;
-}
-
-static void do_join(char *name)
-{
- dlm_lshandle_t *dh;
- uint32_t flags = 0;
-
- if (!opt_dir)
- flags |= DLM_LSFL_NODIR;
-
- if (opt_excl)
- flags |= DLM_LSFL_NEWEXCL;
-
- if (opt_fs)
- flags |= DLM_LSFL_FS;
-
- printf("Joining lockspace \"%s\" permission %o %s\n",
- name, create_mode, flags ? flag_str(flags) : "");
- fflush(stdout);
-
- dh = dlm_new_lockspace(name, create_mode, flags);
- if (!dh) {
- fprintf(stderr, "dlm_new_lockspace %s error %d\n",
- name, errno);
- exit(-1);
- }
-
- dlm_close_lockspace(dh);
- /* there's no autofree so the ls should stay around */
- printf("done\n");
-}
-
-static void do_leave(char *name)
-{
- dlm_lshandle_t *dh;
-
- printf("Leaving lockspace \"%s\"\n", name);
- fflush(stdout);
-
- dh = dlm_open_lockspace(name);
- if (!dh) {
- fprintf(stderr, "dlm_open_lockspace %s error %p %d\n",
- name, dh, errno);
- exit(-1);
- }
-
- dlm_release_lockspace(name, dh, 1);
- printf("done\n");
-}
-
-static char *pr_master(int nodeid)
-{
- static char buf[64];
-
- memset(buf, 0, sizeof(buf));
-
- if (nodeid > 0)
- sprintf(buf, "Local %d", nodeid);
- else if (!nodeid)
- sprintf(buf, "Master");
- else if (nodeid == -1)
- sprintf(buf, "Lookup");
-
- return buf;
-}
-
-static char *pr_extra(uint32_t flags, int root_list, int recover_list,
- int recover_locks_count, char *first_lkid)
-{
- static char buf[128];
- int first = 0;
-
- memset(buf, 0, sizeof(buf));
-
- if (strcmp(first_lkid, "0"))
- first = 1;
-
- if (flags || first || root_list || recover_list || recover_locks_count)
- sprintf(buf,
- "flags %08x first_lkid %s root %d recover %d locks %d",
- flags, first_lkid, root_list, recover_list, recover_locks_count);
-
- return buf;
-}
-
-static void print_rsb(char *line, struct rinfo *ri)
-{
- char type[4], namefmt[4], *p;
- char addr[64];
- char first_lkid[64];
- int rv, nodeid, root_list, recover_list, recover_locks_count, namelen;
- uint32_t flags;
-
- rv = sscanf(line, "%s %s %d %s %u %d %d %u %u %s",
- type,
- addr,
- &nodeid,
- first_lkid,
- &flags,
- &root_list,
- &recover_list,
- &recover_locks_count,
- &namelen,
- namefmt);
-
- if (rv != 10)
- goto fail;
-
- /* used for lkb prints */
- ri->nodeid = nodeid;
-
- ri->namelen = namelen;
-
- p = strchr(line, '\n');
- if (!p)
- goto fail;
- *p = '\0';
-
- p = strstr(line, namefmt);
- if (!p)
- goto fail;
- p += 4;
-
- strcat(addr, " ");
-
- if (!strncmp(namefmt, "str", 3))
- printf("Resource len %2d \"%s\"\n", namelen, p);
- else if (!strncmp(namefmt, "hex", 3))
- printf("Resource len %2d hex %s\n", namelen, p);
- else
- goto fail;
-
- printf("%-16s %s\n",
- pr_master(nodeid),
- pr_extra(flags, root_list, recover_list, recover_locks_count, first_lkid));
- return;
-
- fail:
- fprintf(stderr, "print_rsb error rv %d line \"%s\"\n", rv, line);
-}
-
-static void print_lvb(char *line)
-{
- char lvb[1024];
- char type[4];
- int i, c, rv, lvblen;
- uint32_t lvbseq;
-
- memset(lvb, 0, 1024);
-
- rv = sscanf(line, "%s %u %d %[0-9A-Fa-f ]", type, &lvbseq, &lvblen, lvb);
-
- if (rv != 4) {
- fprintf(stderr, "print_lvb error rv %d line \"%s\"\n", rv, line);
- return;
- }
-
- printf("LVB len %d seq %u\n", lvblen, lvbseq);
-
- for (c = 0, i = 0; ; i++) {
- printf("%c", lvb[i]);
- if (lvb[i] != ' ')
- c++;
- if (!wide && lvb[i] == ' ' && !(c % 32))
- printf("\n");
- if (c == (lvblen * 2))
- break;
- }
- printf("\n");
-}
-
-struct lkb {
- uint64_t xid, timestamp, time_bast;
- uint32_t id, remid, exflags, flags, lvbseq;
- int nodeid, ownpid, status, grmode, rqmode, highbast, rsb_lookup, wait_type;
-};
-
-static const char *pr_grmode(struct lkb *lkb)
-{
- if (lkb->status == DLM_LKSTS_GRANTED || lkb->status == DLM_LKSTS_CONVERT)
- return mode_str(lkb->grmode);
- else if (lkb->status == DLM_LKSTS_WAITING || lkb->rsb_lookup)
- return "--";
- else
- return "XX";
-}
-
-static const char *pr_rqmode(struct lkb *lkb)
-{
- static char buf[5];
-
- memset(buf, 0, sizeof(buf));
-
- if (lkb->status == DLM_LKSTS_GRANTED) {
- return " ";
- } else if (lkb->status == DLM_LKSTS_CONVERT ||
- lkb->status == DLM_LKSTS_WAITING ||
- lkb->rsb_lookup) {
- sprintf(buf, "(%s)", mode_str(lkb->rqmode));
- return buf;
- } else {
- return "(XX)";
- }
-}
-
-static const char *pr_remote(struct lkb *lkb, struct rinfo *ri)
-{
- static char buf[64];
-
- memset(buf, 0, sizeof(buf));
-
- if (!lkb->nodeid) {
- return " ";
- } else if (lkb->nodeid != ri->nodeid) {
- sprintf(buf, "Remote: %3d %08x", lkb->nodeid, lkb->remid);
- return buf;
- } else {
- sprintf(buf, "Master: %3d %08x", lkb->nodeid, lkb->remid);
- return buf;
- }
-}
-
-static const char *pr_wait(struct lkb *lkb)
-{
- static char buf[16];
-
- memset(buf, 0, sizeof(buf));
-
- if (!lkb->wait_type) {
- return " ";
- } else {
- sprintf(buf, " wait %02d", lkb->wait_type);
- return buf;
- }
-}
-
-static char *pr_verbose(struct lkb *lkb)
-{
- static char buf[128];
-
- memset(buf, 0, sizeof(buf));
-
- sprintf(buf, "time %016llu flags %08x %08x bast %d %llu",
- (unsigned long long)lkb->timestamp,
- lkb->exflags, lkb->flags, lkb->highbast,
- (unsigned long long)lkb->time_bast);
-
- return buf;
-}
-
-static void print_lkb(char *line, struct rinfo *ri)
-{
- struct lkb lkb;
- char type[4];
- int rv;
-
- rv = sscanf(line, "%s %x %d %x %u %"PRIu64" %x %x %d %d %d %d %d %d %u %"PRIu64" %"PRIu64,
- type,
- &lkb.id,
- &lkb.nodeid,
- &lkb.remid,
- &lkb.ownpid,
- &lkb.xid,
- &lkb.exflags,
- &lkb.flags,
- &lkb.status,
- &lkb.grmode,
- &lkb.rqmode,
- &lkb.highbast,
- &lkb.rsb_lookup,
- &lkb.wait_type,
- &lkb.lvbseq,
- &lkb.timestamp,
- &lkb.time_bast);
-
- ri->lkb_count++;
-
- if (lkb.status == DLM_LKSTS_GRANTED) {
- if (!ri->print_granted++)
- printf("Granted\n");
- ri->lkb_granted++;
- }
- if (lkb.status == DLM_LKSTS_CONVERT) {
- if (!ri->print_convert++)
- printf("Convert\n");
- ri->lkb_convert++;
- }
- if (lkb.status == DLM_LKSTS_WAITING) {
- if (!ri->print_waiting++)
- printf("Waiting\n");
- ri->lkb_waiting++;
- }
- if (lkb.rsb_lookup) {
- if (!ri->print_lookup++)
- printf("Lookup\n");
- ri->lkb_lookup++;
- }
-
- if (lkb.wait_type)
- ri->lkb_wait_msg++;
-
- if (!ri->nodeid) {
- if (lkb.nodeid)
- ri->lkb_master_copy++;
- else
- ri->lkb_local_copy++;
- } else {
- ri->lkb_process_copy++;
- }
-
- printf("%08x %s %s %s %s %s\n",
- lkb.id, pr_grmode(&lkb), pr_rqmode(&lkb),
- pr_remote(&lkb, ri), pr_wait(&lkb),
- (verbose && wide) ? pr_verbose(&lkb) : "");
-
- if (verbose && !wide)
- printf("%s\n", pr_verbose(&lkb));
-}
-
-static void clear_rinfo(struct rinfo *ri)
-{
- memset(ri, 0, sizeof(struct rinfo));
- ri->nodeid = -9;
-}
-
-static void count_rinfo(struct summary *s, struct rinfo *ri)
-{
- /* the first time called */
- if (!ri->namelen)
- return;
-
- s->rsb_total++;
-
- if (ri->lvb)
- s->rsb_with_lvb++;
-
- if (!ri->lkb_count) {
- s->rsb_no_locks++;
- printf("no locks\n");
- }
-
- if (!ri->nodeid)
- s->rsb_master++;
- else if (ri->nodeid == -1)
- s->rsb_lookup++;
- else if (ri->nodeid > 0)
- s->rsb_local++;
- else
- s->rsb_nodeid_error++;
-
- s->lkb_count += ri->lkb_count;
- s->lkb_granted += ri->lkb_granted;
- s->lkb_convert += ri->lkb_convert;
- s->lkb_waiting += ri->lkb_waiting;
- s->lkb_lookup += ri->lkb_lookup;
- s->lkb_wait_msg += ri->lkb_wait_msg;
- s->lkb_master_copy += ri->lkb_master_copy;
- s->lkb_local_copy += ri->lkb_local_copy;
- s->lkb_process_copy += ri->lkb_process_copy;
-}
-
-static void print_summary(struct summary *s)
-{
- printf("rsb\n");
- printf(" total %u\n", s->rsb_total);
- printf(" master %u\n", s->rsb_master);
- printf(" remote master %u\n", s->rsb_local);
- printf(" lookup master %u\n", s->rsb_lookup);
- printf(" with lvb %u\n", s->rsb_with_lvb);
- printf(" with no locks %u\n", s->rsb_no_locks);
- printf(" nodeid error %u\n", s->rsb_nodeid_error);
- printf("\n");
-
- printf("lkb\n");
- printf(" total %u\n", s->lkb_count);
- printf(" granted %u\n", s->lkb_granted);
- printf(" convert %u\n", s->lkb_convert);
- printf(" waiting %u\n", s->lkb_waiting);
- printf(" local copy %u\n", s->lkb_local_copy);
- printf(" master copy %u\n", s->lkb_master_copy);
- printf(" process copy %u\n", s->lkb_process_copy);
- printf(" rsb lookup %u\n", s->lkb_lookup);
- printf(" wait message %u\n", s->lkb_wait_msg);
- printf(" expect reply %u\n", s->expect_replies);
-}
-
-#define LOCK_LINE_MAX 1024
-
-static void do_waiters(char *name, struct summary *sum)
-{
- FILE *file;
- char path[PATH_MAX];
- char line[LOCK_LINE_MAX];
- char rname[65];
- int header = 0;
- int i, j, spaces;
- int rv, nodeid, wait_type;
- uint32_t id;
-
- snprintf(path, PATH_MAX, "/sys/kernel/debug/dlm/%s_waiters", name);
-
- file = fopen(path, "r");
- if (!file)
- return;
-
- while (fgets(line, LOCK_LINE_MAX, file)) {
- if (!header) {
- printf("\n");
- printf("Expecting reply\n");
- header = 1;
- }
-
- rv = sscanf(line, "%x %d %d",
- &id, &wait_type, &nodeid);
-
- if (rv != 3) {
- printf("waiters: %s", line);
- continue;
- }
-
- /* parse the resource name from the remainder of the line */
- j = 0;
- spaces = 0;
-
- for (i = 0; i < LOCK_LINE_MAX; i++) {
- if (line[i] == '\n')
- break;
- if (spaces == 3) {
- rname[j++] = line[i];
- if (j == (sizeof(rname) - 1))
- break;
- } else if (line[i] == ' ') {
- spaces++;
- }
- }
-
- printf("nodeid %2d msg %s lkid %08x resource \"%s\"\n",
- nodeid, msg_str(wait_type), id, rname);
-
- sum->expect_replies++;
- }
- fclose(file);
-}
-
-static void do_lockdebug(char *name)
-{
- struct summary summary;
- struct rinfo info;
- FILE *file;
- char path[PATH_MAX];
- char line[LOCK_LINE_MAX];
- int old = 0;
-
- snprintf(path, PATH_MAX, "/sys/kernel/debug/dlm/%s_all", name);
-
- file = fopen(path, "r");
- if (!file) {
- snprintf(path, PATH_MAX, "/sys/kernel/debug/dlm/%s", name);
- file = fopen(path, "r");
- if (!file) {
- fprintf(stderr, "can't open %s: %s\n", path, strerror(errno));
- return;
- }
- old = 1;
- }
-
- memset(&summary, 0, sizeof(struct summary));
- memset(&info, 0, sizeof(struct rinfo));
-
- while (fgets(line, LOCK_LINE_MAX, file)) {
-
- if (old)
- goto raw;
-
- if (!strncmp(line, "version", 7))
- continue;
-
- if (!strncmp(line, "rsb", 3)) {
- count_rinfo(&summary, &info);
- clear_rinfo(&info);
- printf("\n");
- print_rsb(line, &info);
- continue;
- }
-
- if (!strncmp(line, "lvb", 3)) {
- print_lvb(line);
- info.lvb = 1;
- continue;
- }
-
- if (!strncmp(line, "lkb", 3)) {
- print_lkb(line, &info);
- continue;
- }
- raw:
- printf("%s", line);
- }
- fclose(file);
-
- do_waiters(name, &summary);
-
- if (summarize) {
- printf("\n");
- print_summary(&summary);
- }
-}
-
-static void parse_r_name(char *line, char *name)
-{
- char *p;
- int i = 0;
- int begin = 0;
-
- for (p = line; ; p++) {
- if (*p == '"') {
- if (begin)
- break;
- begin = 1;
- continue;
- }
- if (begin)
- name[i++] = *p;
- }
-}
-
-static void do_lockdump(char *name)
-{
- FILE *file;
- char path[PATH_MAX];
- char line[LOCK_LINE_MAX];
- char r_name[65];
- int r_nodeid;
- int r_len;
- int rv;
- unsigned int time;
- unsigned long long xid;
- uint32_t id;
- int nodeid;
- uint32_t remid;
- int ownpid;
- uint32_t exflags;
- uint32_t flags;
- int8_t status;
- int8_t grmode;
- int8_t rqmode;
-
- snprintf(path, PATH_MAX, "/sys/kernel/debug/dlm/%s_locks", name);
-
- file = fopen(path, "r");
- if (!file) {
- fprintf(stderr, "can't open %s: %s\n", path, strerror(errno));
- return;
- }
-
- /* skip the header on the first line */
- if (!fgets(line, LOCK_LINE_MAX, file))
- return;
-
- while (fgets(line, LOCK_LINE_MAX, file)) {
- rv = sscanf(line, "%x %d %x %u %llu %x %x %hhd %hhd %hhd %u %d %d",
- &id,
- &nodeid,
- &remid,
- &ownpid,
- &xid,
- &exflags,
- &flags,
- &status,
- &grmode,
- &rqmode,
- &time,
- &r_nodeid,
- &r_len);
-
- if (rv != 13) {
- fprintf(stderr, "invalid debugfs line %d: %s\n",
- rv, line);
- return;
- }
-
- memset(r_name, 0, sizeof(r_name));
- parse_r_name(line, r_name);
-
- /* don't print MSTCPY locks without -M */
- if (!r_nodeid && nodeid) {
- if (!dump_mstcpy)
- continue;
- printf("id %08x gr %s rq %s pid %u MSTCPY %d \"%s\"\n",
- id, mode_str(grmode), mode_str(rqmode),
- ownpid, nodeid, r_name);
- continue;
- }
-
- /* A hack because dlm-kernel doesn't set rqmode back to IV when
- a NOQUEUE convert fails, which means in a lockdump it looks
- like a granted lock is still converting since rqmode is not
- IV. (does it make sense to include status in the output,
- e.g. G,C,W?) */
-
- if (status == DLM_LKSTS_GRANTED)
- rqmode = LKM_IVMODE;
-
- printf("id %08x gr %s rq %s pid %u master %d \"%s\"\n",
- id, mode_str(grmode), mode_str(rqmode),
- ownpid, nodeid, r_name);
- }
-
- fclose(file);
-}
-
-static char *dlmc_lf_str(uint32_t flags)
-{
- static char str[128];
- int i = 0;
-
- memset(str, 0, sizeof(str));
-
- if (flags & DLMC_LF_SAVE_PLOCKS) {
- i++;
- strcat(str, "save_plock");
- }
- if (flags & DLMC_LF_NEED_PLOCKS) {
- strcat(str, i++ ? "," : "");
- strcat(str, "need_plock");
- }
- if (flags & DLMC_LF_FS_REGISTERED) {
- strcat(str, i++ ? "," : "");
- strcat(str, "fs_reg");
- }
- if (flags & DLMC_LF_KERNEL_STOPPED) {
- strcat(str, i++ ? "," : "");
- strcat(str, "kern_stop");
- }
- if (flags & DLMC_LF_LEAVING) {
- strcat(str, i++ ? "," : "");
- strcat(str, "leave");
- }
- if (flags & DLMC_LF_JOINING) {
- strcat(str, i++ ? "," : "");
- strcat(str, "join");
- }
-
- return str;
-}
-
-static const char *nf_check_str(uint32_t flags)
-{
- if (flags & DLMC_NF_CHECK_FENCING)
- return "fence";
-
- if (flags & DLMC_NF_CHECK_QUORUM)
- return "quorum";
-
- if (flags & DLMC_NF_CHECK_FS)
- return "fs";
-
- return "none";
-}
-
-static const char *condition_str(int cond)
-{
- switch (cond) {
- case 0:
- return "";
- case 1:
- return "fencing";
- case 2:
- return "quorum";
- case 3:
- return "fs";
- case 4:
- return "pending";
- default:
- return "unknown";
- }
-}
-
-static int node_compare(const void *va, const void *vb)
-{
- const struct dlmc_node *a = va;
- const struct dlmc_node *b = vb;
-
- return a->nodeid - b->nodeid;
-}
-
-static void show_nodeids(int count, struct dlmc_node *nodes_in)
-{
- struct dlmc_node *n = nodes_in;
- int i;
-
- for (i = 0; i < count; i++) {
- printf("%d ", n->nodeid);
- n++;
- }
- printf("\n");
-}
-
-static void show_ls(struct dlmc_lockspace *ls)
-{
- int rv, node_count;
-
- printf("name %s\n", ls->name);
- printf("id 0x%08x\n", ls->global_id);
- printf("flags 0x%08x %s\n",
- ls->flags, dlmc_lf_str(ls->flags));
- printf("change member %d joined %d remove %d failed %d seq %d,%d\n",
- ls->cg_prev.member_count, ls->cg_prev.joined_count,
- ls->cg_prev.remove_count, ls->cg_prev.failed_count,
- ls->cg_prev.combined_seq, ls->cg_prev.seq);
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
- rv = dlmc_lockspace_nodes(ls->name, DLMC_NODES_MEMBERS,
- MAX_NODES, &node_count, nodes);
- if (rv < 0) {
- printf("members error\n");
- goto next;
- }
- qsort(nodes, node_count, sizeof(struct dlmc_node), node_compare);
-
- printf("members ");
- show_nodeids(node_count, nodes);
-
- next:
- if (!ls->cg_next.seq)
- return;
-
- printf("new change member %d joined %d remove %d failed %d seq %d,%d\n",
- ls->cg_next.member_count, ls->cg_next.joined_count,
- ls->cg_next.remove_count, ls->cg_next.failed_count,
- ls->cg_next.combined_seq, ls->cg_next.seq);
-
- printf("new status wait_messages %d wait_condition %d %s\n",
- ls->cg_next.wait_messages, ls->cg_next.wait_condition,
- condition_str(ls->cg_next.wait_condition));
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
- rv = dlmc_lockspace_nodes(ls->name, DLMC_NODES_NEXT,
- MAX_NODES, &node_count, nodes);
- if (rv < 0) {
- printf("new members error\n");
- return;
- }
- qsort(nodes, node_count, sizeof(struct dlmc_node), node_compare);
-
- printf("new members ");
- show_nodeids(node_count, nodes);
-}
-
-static int member_int(struct dlmc_node *n)
-{
- if (n->flags & DLMC_NF_DISALLOWED)
- return -1;
- if (n->flags & DLMC_NF_MEMBER)
- return 1;
- return 0;
-}
-
-static void show_all_nodes(int count, struct dlmc_node *nodes_in)
-{
- struct dlmc_node *n = nodes_in;
- int i;
-
- for (i = 0; i < count; i++) {
- printf("nodeid %d member %d failed %d start %d seq_add %u seq_rem %u check %s\n",
- n->nodeid,
- member_int(n),
- n->failed_reason,
- (n->flags & DLMC_NF_START) ? 1 : 0,
- n->added_seq,
- n->removed_seq,
- nf_check_str(n->flags));
- n++;
- }
-}
-
-static void do_list(char *name)
-{
- struct dlmc_lockspace *ls;
- int node_count;
- int ls_count;
- int rv;
- int i;
-
- memset(lss, 0, sizeof(lss));
-
- if (name) {
- ls_count = 1;
- rv = dlmc_lockspace_info(name, lss);
- } else {
- rv = dlmc_lockspaces(MAX_LS, &ls_count, lss);
- }
-
- if (rv < 0)
- exit(EXIT_FAILURE); /* dlm_controld probably not running */
-
- if (ls_count)
- printf("dlm lockspaces\n");
-
- for (i = 0; i < ls_count; i++) {
- ls = &lss[i];
-
- show_ls(ls);
-
- if (!ls_all_nodes)
- goto next;
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
-
- rv = dlmc_lockspace_nodes(ls->name, DLMC_NODES_ALL,
- MAX_NODES, &node_count, nodes);
- if (rv < 0) {
- printf("all nodes error %d %d\n", rv, errno);
- goto next;
- }
-
- qsort(nodes, node_count, sizeof(struct dlmc_node),node_compare);
-
- printf("all nodes\n");
- show_all_nodes(node_count, nodes);
- next:
- printf("\n");
- }
-}
-
-static void do_deadlock_check(char *name)
-{
- dlmc_deadlock_check(name);
-}
-
-static void do_plocks(char *name)
-{
- char buf[DLMC_DUMP_SIZE];
-
- memset(buf, 0, sizeof(buf));
-
- dlmc_dump_plocks(name, buf);
-
- do_write(STDOUT_FILENO, buf, strlen(buf));
-}
-
-static void do_dump(void)
-{
- char buf[DLMC_DUMP_SIZE];
-
- memset(buf, 0, sizeof(buf));
-
- dlmc_dump_debug(buf);
-
- do_write(STDOUT_FILENO, buf, strlen(buf));
-}
-
-static void do_log_plock(void)
-{
- char buf[DLMC_DUMP_SIZE];
-
- memset(buf, 0, sizeof(buf));
-
- dlmc_dump_log_plock(buf);
-
- do_write(STDOUT_FILENO, buf, strlen(buf));
-}
-
-int main(int argc, char **argv)
-{
- prog_name = argv[0];
- decode_arguments(argc, argv);
-
- switch (operation) {
-
- /* calls to libdlm; pass a command to dlm-kernel */
-
- case OP_JOIN:
- do_join(lsname);
- break;
-
- case OP_LEAVE:
- do_leave(lsname);
- break;
-
- case OP_JOINLEAVE:
- do_join(lsname);
- do_leave(lsname);
- break;
-
- /* calls to libdlmcontrol; pass a command/query to dlm_controld */
-
- case OP_LIST:
- do_list(lsname);
- break;
-
- case OP_DUMP:
- do_dump();
- break;
-
- case OP_LOG_PLOCK:
- do_log_plock();
- break;
-
- case OP_PLOCKS:
- do_plocks(lsname);
- break;
-
- case OP_DEADLOCK_CHECK:
- do_deadlock_check(lsname);
- break;
-
- /* calls to read debugfs; query info from dlm-kernel */
-
- case OP_LOCKDUMP:
- do_lockdump(lsname);
- break;
-
- case OP_LOCKDEBUG:
- do_lockdebug(lsname);
- break;
- }
- return 0;
-}
-
diff --git a/doc/COPYING.applications b/doc/COPYING.applications
deleted file mode 100644
index d511905..0000000
--- a/doc/COPYING.applications
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/doc/COPYING.libraries b/doc/COPYING.libraries
deleted file mode 100644
index 2d2d780..0000000
--- a/doc/COPYING.libraries
+++ /dev/null
@@ -1,510 +0,0 @@
-
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations
-below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it
-becomes a de-facto standard. To achieve this, non-free programs must
-be allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control
-compilation and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at least
- three years, to give the same user the materials specified in
- Subsection 6a, above, for a charge no more than the cost of
- performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply, and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License
-may add an explicit geographical distribution limitation excluding those
-countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms
-of the ordinary General Public License).
-
- To apply these terms, attach the following notices to the library.
-It is safest to attach them to the start of each source file to most
-effectively convey the exclusion of warranty; and each file should
-have at least the "copyright" line and a pointer to where the full
-notice is found.
-
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or
-your school, if any, to sign a "copyright disclaimer" for the library,
-if necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James
- Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
diff --git a/doc/COPYRIGHT b/doc/COPYRIGHT
deleted file mode 100644
index 55331b3..0000000
--- a/doc/COPYRIGHT
+++ /dev/null
@@ -1,239 +0,0 @@
-Unless specified otherwise in the "exceptions section" below:
-
-Copyright (C) 1997-2003 Sistina Software, Inc. All rights reserved.
-Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
-
-Exceptions:
-
-contrib/libaislock:
- Contributed by Stanley Wang of Intel.
-
-cman/qdisk/crc32.c:
- Copyright (C) 2000 Bryan Call <bc at fodder.org>
- Modified by Lon H. Hohberger <lhh at redhat.com>
- Copyright (C) 2003-2010 Red Hat, Inc. All rights reserved.
-
-cman/qdisk/daemon_init.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author: Jeff Moyer <jmoyer at redhat.com>
-
-cman/qdisk/disk.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author: Tim Burke <tburke at redhat.com>
-
-cman/qdisk/scandisk.{c,h}:
- Original design by: Joel Becker <Joel.Becker at oracle.com> and
- Fabio M. Di Nitto <fdinitto at redhat.com>
-
-cman/daemon/fnvhash.c
- This code is in the public domain.
- Phong Vo (http://www.research.att.com/info/kpv/)
- Glenn Fowler (http://www.research.att.com/~gsf/)
- Landon Curt Noll (http://www.isthe.com/chongo/)
-
-dlm/doc/example.c:
- Author: Daniel Phillips <phillips at redhat.com>
-
-fence/agents/apc_snmp/powernet369.mib:
- Copyright (c) 2005 American Power Conversion, Inc.
- PowerNet is a Trademark of American Power Conversion Corp.
-
-fence/agents/ifmib/fence_ifmib.py:
- Copyright (C) 2008-2010 Ross Vandegrift.
- Written by Ross Vandegrift <ross at kallisti.us>
-
-fence/agents/ipmilan/expect.{c,h}:
- Copyright (C) 2000 Alan Robertson <alanr at unix.sh>
-
-fence/agents/xvm/tcp.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author: Jeff Moyer <jmoyer at redhat.com>
-
-fence/man/fence_ifmib.8:
- Copyright (C) 2008-2010 Ross Vandegrift.
- Written by Ross Vandegrift <ross at kallisti.us>
-
-gfs/man/gfs_mount.8:
- Portions copyright (C) 2001-2003 The OpenGFS Project
- Portions copyright (C) 2004 <ben.m.cahill at intel.com>
- Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
-
-gfs2/man/gfs2_mount.8:
- Portions copyright (C) 2001-2003 The OpenGFS2 Project
- Portions copyright (C) 2004 <ben.m.cahill at intel.com>
- Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
-
-gfs-kernel/src/gfs/fixed_div64.h:
- Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- Mountain View, CA 94043, or:
- http://www.sgi.com
- For further information regarding this notice, see:
- http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
-
-From rgmanager/AUTHORS:
-
-Lon Hohberger lhh at redhat.com
-* Resource tree
-* Failover domains
-* Resource agent scripts
-
-Gregory Myrdal [private]
-* Misc utilities
-* Resource agent scripts
-
-Jeff Moyer jmoyer at redhat.com
-* Syslog wrapper & logging program
-
-Portions of this code (C) 2000-2001 Mission Critical Linux, Inc.
-
-rgmanager/include/clulog.h:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author: Jeff Moyer <moyer at missioncriticallinux.com>
-
-rgmanager/src/clulib/clulog.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author: Jeff Moyer <moyer at missioncriticallinux.com>
-
-rgmanager/src/clulib/daemon_init.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author: Jeff Moyer <moyer at missioncriticallinux.com>
-
-rgmanager/src/clulib/msgsimple.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/clulib/tmgr.c:
- Copyright (C) 2006-2007 Crosswalk.
- Copyright (C) 2007-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/clulib/wrap_lock.c:
- Copyright (C) 2006-2007 Crosswalk.
- Copyright (C) 2007-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/daemons/groups.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/daemons/main.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/utils/clubufflush.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author: Gregory P. Myrdal <Myrdal at MissionCriticalLinux.Com>
-
-rgmanager/src/utils/clufindhostname.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Richard Rabbat <rabbat at missioncriticallinux.com>
-
-rgmanager/src/utils/clulog.c:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author: Jeff Moyer <moyer at missioncriticallinux.com>
-
-rgmanager/src/utils/syscall.h
- Copyright (C) 1995-1997 Olaf Kirch <okir at monad.swb.de>
- Copyright (C) 1997-2003 Sistina Software, Inc. All rights reserved.
- Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/resources/ASEHAagent.sh:
- Sybase Availability Agent for Red Hat Cluster v15.0.2
- Copyright (C) - 2007
- Sybase, Inc. All rights reserved.
-
- Sybase Availability Agent for Red Hat Cluster v15.0.2 is licensed
- under the GNU General Public License Version 2.
-
- Author(s):
- Jian-ping Hui <jphui at sybase.com>
-
-rgmanager/src/resources/clusterfs.sh:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/resources/follow-service.sl
- Author:
- Marc Grimme, Mark Hlawatschek, October 2008
- Copyright (C) 2008-2010 ATIX AG
-
-rgmanager/src/resources/fs.sh:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/resources/ip.sh:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/resources/netfs.sh:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/resources/netexport.sh:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
-
-rgmanager/src/resources/ocf-shellfuncs:
- Copyright (C) 2004 SUSE LINUX AG, Lars Marowsky-Bree. All Rights Reserved.
-
-rgmanager/src/resources/oracledb.sh:
- Author(s):
- Hardy Merrill <hmerrill at redhat.com>
- Michael Moon <Michael dot Moon at oracle.com>
-
-rgmanager/src/resources/SAPDatabase:
- Author: Alexander Krauth
- Copyright (C) 2006 Alexander Krauth
-
-rgmanager/src/resources/SAPInstance:
- Author: Alexander Krauth
- Copyright (C) 2006 Alexander Krauth
-
-rgmanager/src/resources/smb.sh:
- Copyright (C) 2000 Mission Critical Linux
- Copyright (C) 2002-2010 Red Hat, Inc. All rights reserved.
- Author(s):
- Lon Hohberger (lhh at redhat.com)
- Tim Burke (tburke at redhat.com)
-
-Authors as known by current RCS as of the time of writing:
-
-Abhijith Das <adas at redhat.com>
-Adam Manthei <amanthei at redhat.com>
-A. J. Lewis <alewis at redhat.com>
-Alasdair G. Kergon <agk at redhat.com>
-Andrew Price <andy at andrewprice.me.uk>
-Benjamin Marzinski <bmarzins at redhat.com>
-Bob Peterson <rpeterso at redhat.com>
-Chris Feist <cfeist at redhat.com>
-Christine Caulfield <ccaulfie at redhat.com>
-Daniel Phillips <phillips at redhat.com>
-David Teigland <teigland at redhat.com>
-Fabio M. Di Nitto <fdinitto at redhat.com>
-James Parsons <jparsons at redhat.com>
-Joel Becker <joel.becker at oracle.com>
-Jonathan Brassow <jbrassow at redhat.com>
-jparsons <jparsons at redhat.com>
-Ken Preslan <kpreslan at redhat.com>
-Lon Hohberger <lhh at redhat.com>
-Marc - A. Dahlhaus <mad at wol.de>
-Marek 'marx' Grac <mgrac at redhat.com>
-Mark Hlawatschek <hlawatschek at atix.de>
-Michael Conrad Tadpol Tilstra <mtilstra at redhat.com>
-Patrick Caulfield <pcaulfie at redhat.com>
-Robert Peterson <rpeterso at redhat.com>
-Ross Vandegrift <ross at kallisti.us>
-Ryan McCabe <rmccabe at redhat.com>
-Ryan O'Hara <rohara at redhat.com>
-Stanko Kupcevic <kupcevic at redhat.com>
-Steven Whitehouse <swhiteho at redhat.com>
-Wendy Cheng <wcheng at redhat.com>
diff --git a/doc/Makefile b/doc/Makefile
deleted file mode 100644
index efc83e6..0000000
--- a/doc/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-DOCS = usage.txt \
- COPYING.applications \
- COPYING.libraries \
- COPYRIGHT \
- README.licence \
- cluster_conf.html
-
-TARGET= cluster
-
-LOGRORATED = $(TARGET)
-
-all: $(TARGET)
-
-include ../make/defines.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-include $(OBJDIR)/make/clean.mk
-
-$(TARGET):
- cat $(S)/$(TARGET).logrotate.in | sed \
- -e 's#@LOGDIR@#${logdir}#g' \
- > $(TARGET)
-
-clean: generalclean
diff --git a/doc/README.licence b/doc/README.licence
deleted file mode 100644
index 075aa77..0000000
--- a/doc/README.licence
+++ /dev/null
@@ -1,33 +0,0 @@
-The Red Hat Cluster is a collection of free software built on top of different
-libraries and applications.
-
-For a detailed list of authors and copyright holders, please check the
-included COPYRIGHT file.
-
-Libraries:
-
-You can redistribute them and/or modify them under the terms of the GNU Lesser
-General Public License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-The libraries are distributed in the hope that they will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
-details.
-
-Applications:
-
-You can redistribute them and/or modify them under the terms of the GNU General
-Public License as published by the Free Software Foundation; either version
-2 of the License, or (at your option) any later version.
-
-The applications are distributed in the hope that they will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-details.
-
-A copy of each license is included for your convenience in COPYING.applications
-and COPYING.libraries.
-
-If missing, write to the Free Software Foundation, Inc., 51 Franklin St,
-Fifth Floor, Boston, MA 02110-1301 USA.
diff --git a/doc/cluster.logrotate.in b/doc/cluster.logrotate.in
deleted file mode 100644
index bd55cce..0000000
--- a/doc/cluster.logrotate.in
+++ /dev/null
@@ -1,9 +0,0 @@
-@LOGDIR@/*log {
- missingok
- compress
- copytruncate
- daily
- rotate 31
- minsize 2048
- notifempty
-}
diff --git a/doc/cluster_conf.html b/doc/cluster_conf.html
deleted file mode 100644
index 5bfafac..0000000
--- a/doc/cluster_conf.html
+++ /dev/null
@@ -1,1240 +0,0 @@
-<html>
-<h2><a name="toc_tree_reference"/>Tree Structure Reference</h2>
-<small><a href="#toc_tag_reference">Jump to Tag Reference</a></small><br/><br/>
-<<a href="#tag_cluster">cluster</a> ...><br/>
- <<a href="#tag_cman">cman</a> ...><br/>
- <<a href="#tag_multicast">multicast</a> .../><br/>
- <<a href="#tag_cman">/cman</a>><br/>
- <<a href="#tag_totem">totem</a> ...><br/>
- <<a href="#tag_interface">interface</a> .../><br/>
- <<a href="#tag_totem">/totem</a>><br/>
- <<a href="#tag_quorumd">quorumd</a> ...><br/>
- <<a href="#tag_heuristic">heuristic</a> .../><br/>
- <<a href="#tag_quorumd">/quorumd</a>><br/>
- <<a href="#tag_fence_daemon">fence_daemon</a> .../><br/>
- <<a href="#tag_fence_xvmd">fence_xvmd</a> .../><br/>
- <<a href="#tag_dlm">dlm</a> ...><br/>
- <<a href="#tag_lockspace">lockspace</a> ...><br/>
- <<a href="#tag_master">master</a> .../><br/>
- <<a href="#tag_lockspace">/lockspace</a>><br/>
- <<a href="#tag_dlm">/dlm</a>><br/>
- <<a href="#tag_gfs_controld">gfs_controld</a> .../><br/>
- <<a href="#tag_group">group</a> .../><br/>
- <<a href="#tag_logging">logging</a> ...><br/>
- <<a href="#tag_logging_daemon">logging_daemon</a> .../><br/>
- <<a href="#tag_logging">/logging</a>><br/>
- <<a href="#tag_clusternodes">clusternodes</a>><br/>
- <<a href="#tag_clusternode">clusternode</a> ...><br/>
- <<a href="#tag_altname">altname</a> .../><br/>
- <a href="#ref_FENCE">FENCE</a><br/>
- <a href="#ref_UNFENCE">UNFENCE</a><br/>
- <<a href="#tag_clusternode">/clusternode</a>><br/>
- <<a href="#tag_clusternodes">/clusternodes</a>><br/>
- <<a href="#tag_fencedevices">fencedevices</a>><br/>
- <<a href="#tag_fencedevice">fencedevice</a> ...><br/>
- <a href="#ref_FENCEDEVICEOPTIONS">FENCEDEVICEOPTIONS</a><br/>
- <<a href="#tag_fencedevice">/fencedevice</a>><br/>
- <<a href="#tag_fencedevices">/fencedevices</a>><br/>
- <<a href="#tag_rm">rm</a> ...><br/>
- <<a href="#tag_failoverdomains">failoverdomains</a>><br/>
- <<a href="#tag_failoverdomain">failoverdomain</a> ...><br/>
- <<a href="#tag_failoverdomainnode">failoverdomainnode</a> .../><br/>
- <<a href="#tag_failoverdomain">/failoverdomain</a>><br/>
- <<a href="#tag_failoverdomains">/failoverdomains</a>><br/>
- <<a href="#tag_events">events</a>><br/>
- <<a href="#tag_event">event</a> .../><br/>
- <<a href="#tag_events">/events</a>><br/>
- <<a href="#tag_resources">resources</a>><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_resources">/resources</a>><br/>
- <a href="#ref_SERVICE">SERVICE</a><br/>
- <a href="#ref_VM">VM</a><br/>
- <<a href="#tag_rm">/rm</a>><br/>
- <<a href="#tag_clvmd">clvmd</a> .../><br/>
-<<a href="#tag_cluster">/cluster</a>><br/>
-<br/><a name="ref_SERVICE"/>SERVICE definition<br/>
- <<a href="#tag_service">service</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_service">/service</a>><br/>
-<br/><a name="ref_IP"/>IP definition<br/>
- <<a href="#tag_ip">ip</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_ip">/ip</a>><br/>
-<br/><a name="ref_NFSCLIENT"/>NFSCLIENT definition<br/>
- <<a href="#tag_nfsclient">nfsclient</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_nfsclient">/nfsclient</a>><br/>
-<br/><a name="ref_NFSEXPORT"/>NFSEXPORT definition<br/>
- <<a href="#tag_nfsexport">nfsexport</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_nfsexport">/nfsexport</a>><br/>
-<br/><a name="ref_SCRIPT"/>SCRIPT definition<br/>
- <<a href="#tag_script">script</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_script">/script</a>><br/>
-<br/><a name="ref_NETFS"/>NETFS definition<br/>
- <<a href="#tag_netfs">netfs</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_netfs">/netfs</a>><br/>
-<br/><a name="ref_CLUSTERFS"/>CLUSTERFS definition<br/>
- <<a href="#tag_clusterfs">clusterfs</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_clusterfs">/clusterfs</a>><br/>
-<br/><a name="ref_APACHE"/>APACHE definition<br/>
- <<a href="#tag_apache">apache</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_apache">/apache</a>><br/>
-<br/><a name="ref_OPENLDAP"/>OPENLDAP definition<br/>
- <<a href="#tag_openldap">openldap</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_openldap">/openldap</a>><br/>
-<br/><a name="ref_SAMBA"/>SAMBA definition<br/>
- <<a href="#tag_samba">samba</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_samba">/samba</a>><br/>
-<br/><a name="ref_MYSQL"/>MYSQL definition<br/>
- <<a href="#tag_mysql">mysql</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_mysql">/mysql</a>><br/>
-<br/><a name="ref_POSTGRES-8"/>POSTGRES-8 definition<br/>
- <<a href="#tag_postgres-8">postgres-8</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_postgres-8">/postgres-8</a>><br/>
-<br/><a name="ref_TOMCAT-6"/>TOMCAT-6 definition<br/>
- <<a href="#tag_tomcat-6">tomcat-6</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_tomcat-6">/tomcat-6</a>><br/>
-<br/><a name="ref_LVM"/>LVM definition<br/>
- <<a href="#tag_lvm">lvm</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_lvm">/lvm</a>><br/>
-<br/><a name="ref_VM"/>VM definition<br/>
- <<a href="#tag_vm">vm</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_vm">/vm</a>><br/>
-<br/><a name="ref_SAPINSTANCE"/>SAPINSTANCE definition<br/>
- <<a href="#tag_SAPInstance">SAPInstance</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_SAPInstance">/SAPInstance</a>><br/>
-<br/><a name="ref_SAPDATABASE"/>SAPDATABASE definition<br/>
- <<a href="#tag_SAPDatabase">SAPDatabase</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_SAPDatabase">/SAPDatabase</a>><br/>
-<br/><a name="ref_NAMED"/>NAMED definition<br/>
- <<a href="#tag_named">named</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_named">/named</a>><br/>
-<br/><a name="ref_ASEHAAGENT"/>ASEHAAGENT definition<br/>
- <<a href="#tag_ASEHAagent">ASEHAagent</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_ASEHAagent">/ASEHAagent</a>><br/>
-<br/><a name="ref_NFSSERVER"/>NFSSERVER definition<br/>
- <<a href="#tag_nfsserver">nfsserver</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_nfsserver">/nfsserver</a>><br/>
-<br/><a name="ref_ORAINSTANCE"/>ORAINSTANCE definition<br/>
- <<a href="#tag_orainstance">orainstance</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_orainstance">/orainstance</a>><br/>
-<br/><a name="ref_ORALISTENER"/>ORALISTENER definition<br/>
- <<a href="#tag_oralistener">oralistener</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_oralistener">/oralistener</a>><br/>
-<br/><a name="ref_FS"/>FS definition<br/>
- <<a href="#tag_fs">fs</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_fs">/fs</a>><br/>
-<br/><a name="ref_ORACLEDB"/>ORACLEDB definition<br/>
- <<a href="#tag_oracledb">oracledb</a> ...><br/>
- <a href="#ref_CHILDREN">CHILDREN</a><br/>
- <<a href="#tag_oracledb">/oracledb</a>><br/>
-<br/><a name="ref_CHILDREN"/>CHILDREN definition<br/>
- <a href="#ref_SERVICE">SERVICE</a><br/>
- <a href="#ref_IP">IP</a><br/>
- <a href="#ref_NFSCLIENT">NFSCLIENT</a><br/>
- <a href="#ref_NFSEXPORT">NFSEXPORT</a><br/>
- <a href="#ref_SCRIPT">SCRIPT</a><br/>
- <a href="#ref_NETFS">NETFS</a><br/>
- <a href="#ref_CLUSTERFS">CLUSTERFS</a><br/>
- <a href="#ref_APACHE">APACHE</a><br/>
- <a href="#ref_OPENLDAP">OPENLDAP</a><br/>
- <a href="#ref_SAMBA">SAMBA</a><br/>
- <a href="#ref_MYSQL">MYSQL</a><br/>
- <a href="#ref_POSTGRES-8">POSTGRES-8</a><br/>
- <a href="#ref_TOMCAT-6">TOMCAT-6</a><br/>
- <a href="#ref_LVM">LVM</a><br/>
- <a href="#ref_VM">VM</a><br/>
- <a href="#ref_SAPINSTANCE">SAPINSTANCE</a><br/>
- <a href="#ref_SAPDATABASE">SAPDATABASE</a><br/>
- <a href="#ref_NAMED">NAMED</a><br/>
- <a href="#ref_ASEHAAGENT">ASEHAAGENT</a><br/>
- <a href="#ref_NFSSERVER">NFSSERVER</a><br/>
- <a href="#ref_ORAINSTANCE">ORAINSTANCE</a><br/>
- <a href="#ref_ORALISTENER">ORALISTENER</a><br/>
- <a href="#ref_FS">FS</a><br/>
- <a href="#ref_ORACLEDB">ORACLEDB</a><br/>
- <a href="#ref_RESOURCEACTION">RESOURCEACTION</a><br/>
-<br/><a name="ref_RESOURCEACTION"/>RESOURCEACTION definition<br/>
- <<a href="#tag_action">action</a> .../><br/>
-<br/><a name="ref_FENCE"/>FENCE definition<br/>
- <<a href="#tag_fence">fence</a>><br/>
- <<a href="#tag_method">method</a> ...><br/>
- <a href="#ref_DEVICE">DEVICE</a><br/>
- <<a href="#tag_method">/method</a>><br/>
- <<a href="#tag_fence">/fence</a>><br/>
-<br/><a name="ref_UNFENCE"/>UNFENCE definition<br/>
- <<a href="#tag_unfence">unfence</a>><br/>
- <a href="#ref_DEVICE">DEVICE</a><br/>
- <<a href="#tag_unfence">/unfence</a>><br/>
-<br/><a name="ref_DEVICE"/>DEVICE definition<br/>
- <<a href="#tag_device">device</a> ...><br/>
- <a href="#ref_FENCEDEVICEOPTIONS">FENCEDEVICEOPTIONS</a><br/>
- <<a href="#tag_device">/device</a>><br/>
-<br/><a name="ref_FENCEDEVICEOPTIONS"/>FENCEDEVICEOPTIONS definition<br/>
-<h2>Tag Reference<a name="toc_tag_reference"/></h2><small><a href="#toc_tree_reference">Jump to Tree Structure Reference</a></small><br/><br/>
-<table>
-<tr valign="top"><td><a href="#tag_action"><b>action</b></a></td><td>Overrides resource action timings for a resource instance.</td></tr>
-<tr valign="top"><td><a href="#tag_altname"><b>altname</b></a></td><td>Defines a second network interface to use for corosync redundant ring mode. cman(5)</td></tr>
-<tr valign="top"><td><a href="#tag_apache"><b>apache</b></a></td><td>Defines an Apache web server</td></tr>
-<tr valign="top"><td><a href="#tag_ASEHAagent"><b>ASEHAagent</b></a></td><td>Sybase ASE Failover Instance</td></tr>
-<tr valign="top"><td><a href="#tag_cluster"><b>cluster</b></a></td><td>Defines cluster properties, and contains all other configuration. cluster.conf(5)</td></tr>
-<tr valign="top"><td><a href="#tag_clusterfs"><b>clusterfs</b></a></td><td>Defines a cluster file system mount.</td></tr>
-<tr valign="top"><td><a href="#tag_clusternode"><b>clusternode</b></a></td><td>Defines cluster node properties, and contains other node specific configuration. cluster.conf(5)</td></tr>
-<tr valign="top"><td><a href="#tag_clusternodes"><b>clusternodes</b></a></td><td>Contains all cluster node definitions. cluster.conf(5)</td></tr>
-<tr valign="top"><td><a href="#tag_clvmd"><b>clvmd</b></a></td><td>The clvmd element contains attributes that define parameters for the cluster LVM daemon.</td></tr>
-<tr valign="top"><td><a href="#tag_cman"><b>cman</b></a></td><td>The cman element contains attributes that define the following cluster-wide parameters and behaviors: whether the cluster is a two-node cluster, expected votes, user-specified multicast address, and logging.</td></tr>
-<tr valign="top"><td><a href="#tag_device"><b>device</b></a></td><td>Defines the properties of a device used for fencing or unfencing a node. fenced(8)</td></tr>
-<tr valign="top"><td><a href="#tag_dlm"><b>dlm</b></a></td><td>Configuration for dlm and dlm_controld daemon. dlm_controld(8)</td></tr>
-<tr valign="top"><td><a href="#tag_event"><b>event</b></a></td><td>Defines an event.</td></tr>
-<tr valign="top"><td><a href="#tag_events"><b>events</b></a></td><td>Event definitions (central_processing only).</td></tr>
-<tr valign="top"><td><a href="#tag_failoverdomain"><b>failoverdomain</b></a></td><td>Specifies properties of a specific failover domain</td></tr>
-<tr valign="top"><td><a href="#tag_failoverdomainnode"><b>failoverdomainnode</b></a></td><td>A node in a failover domain</td></tr>
-<tr valign="top"><td><a href="#tag_failoverdomains"><b>failoverdomains</b></a></td><td>Failover domain definitions.</td></tr>
-<tr valign="top"><td><a href="#tag_fence"><b>fence</b></a></td><td>Contains methods for fencing the node in different ways. fenced(8)</td></tr>
-<tr valign="top"><td><a href="#tag_fencedevice"><b>fencedevice</b></a></td><td>Defines fence device properties. fenced(8)</td></tr>
-<tr valign="top"><td><a href="#tag_fencedevices"><b>fencedevices</b></a></td><td>Contains all fence device definitions. fenced(8)</td></tr>
-<tr valign="top"><td><a href="#tag_fence_daemon"><b>fence_daemon</b></a></td><td>Configuration for fenced daemon. fenced(8)</td></tr>
-<tr valign="top"><td><a href="#tag_fence_xvmd"><b>fence_xvmd</b></a></td><td>Fence_xvm daemon. The fence_xvmd fence device is an I/O fencing host that resides on dom0 and is used in conjunction with the fence_xvm fencing agent. Together, these two programs fence Xen virtual machines that are in a cluster. There is a requirement that the parent dom0s are also a part of their own CMAN/OpenAIS based cluster, and that the dom0 cluster does not share any members with the domU cluster. Furthermore, the dom0 cluster is required to have fencing if domU recovery is expected to be automatic.</td></tr>
-<tr valign="top"><td><a href="#tag_fs"><b>fs</b></a></td><td>Defines a file system mount.</td></tr>
-<tr valign="top"><td><a href="#tag_gfs_controld"><b>gfs_controld</b></a></td><td>Configuration for gfs_controld daemon. gfs_controld(8)</td></tr>
-<tr valign="top"><td><a href="#tag_group"><b>group</b></a></td><td>Defines groupd configuration. groupd(8)</td></tr>
-<tr valign="top"><td><a href="#tag_heuristic"><b>heuristic</b></a></td><td>Defines a heuristic. qdisk(5).</td></tr>
-<tr valign="top"><td><a href="#tag_interface"><b>interface</b></a></td><td>Defines Totem interface options. corosync.conf(5)</td></tr>
-<tr valign="top"><td><a href="#tag_ip"><b>ip</b></a></td><td>This is an IP address.</td></tr>
-<tr valign="top"><td><a href="#tag_lockspace"><b>lockspace</b></a></td><td>Individual lockspace configuration. dlm_controld(8)</td></tr>
-<tr valign="top"><td><a href="#tag_logging"><b>logging</b></a></td><td>Defines global logging configuration, and contains daemon-specific configuration. cluster.conf(5)</td></tr>
-<tr valign="top"><td><a href="#tag_logging_daemon"><b>logging_daemon</b></a></td><td>Defines daemon-specific logging configuration. cluster.conf(5)</td></tr>
-<tr valign="top"><td><a href="#tag_lvm"><b>lvm</b></a></td><td>LVM Failover script</td></tr>
-<tr valign="top"><td><a href="#tag_master"><b>master</b></a></td><td>Defines a master node. dlm_controld(8)</td></tr>
-<tr valign="top"><td><a href="#tag_method"><b>method</b></a></td><td>Contains one or more devices for fencing the node a single way. fenced(8)</td></tr>
-<tr valign="top"><td><a href="#tag_multicast"><b>multicast</b></a></td><td>The multicast element provides the ability for a user to specify a multicast address instead of using the multicast address generated by cman. If a user does not specify a multicast address, cman creates one. It forms the upper 16 bits of the multicast address with 239.192 and forms the lower 16 bits based on the cluster ID.</td></tr>
-<tr valign="top"><td><a href="#tag_mysql"><b>mysql</b></a></td><td>Defines a MySQL database server</td></tr>
-<tr valign="top"><td><a href="#tag_named"><b>named</b></a></td><td>Defines an instance of named server</td></tr>
-<tr valign="top"><td><a href="#tag_netfs"><b>netfs</b></a></td><td>Defines an NFS/CIFS file system mount.</td></tr>
-<tr valign="top"><td><a href="#tag_nfsclient"><b>nfsclient</b></a></td><td>Defines an NFS client.</td></tr>
-<tr valign="top"><td><a href="#tag_nfsexport"><b>nfsexport</b></a></td><td>This defines an NFS export.</td></tr>
-<tr valign="top"><td><a href="#tag_nfsserver"><b>nfsserver</b></a></td><td>This defines an NFS server resource.</td></tr>
-<tr valign="top"><td><a href="#tag_openldap"><b>openldap</b></a></td><td>Defines an Open LDAP server</td></tr>
-<tr valign="top"><td><a href="#tag_oracledb"><b>oracledb</b></a></td><td>Oracle 10g Failover Instance</td></tr>
-<tr valign="top"><td><a href="#tag_orainstance"><b>orainstance</b></a></td><td>Oracle 10g Failover Instance</td></tr>
-<tr valign="top"><td><a href="#tag_oralistener"><b>oralistener</b></a></td><td>Oracle 10g Listener Instance</td></tr>
-<tr valign="top"><td><a href="#tag_postgres-8"><b>postgres-8</b></a></td><td>Defines a PostgreSQL server</td></tr>
-<tr valign="top"><td><a href="#tag_quorumd"><b>quorumd</b></a></td><td>This element and its attributes define parameters for the quorum disk daemon, quorumd. qdisk(5).</td></tr>
-<tr valign="top"><td><a href="#tag_resources"><b>resources</b></a></td><td>Defines global resources which may be referenced in services. You may redefine actions for resources here, but child resource definitions are ignored in this section.</td></tr>
-<tr valign="top"><td><a href="#tag_rm"><b>rm</b></a></td><td>This element and its attributes define resources (for example an IP address) required to create HA cluster services, the HA cluster services themselves, and failover domains for the HA cluster services.</td></tr>
-<tr valign="top"><td><a href="#tag_samba"><b>samba</b></a></td><td>Dynamic smbd/nmbd resource agent</td></tr>
-<tr valign="top"><td><a href="#tag_SAPDatabase"><b>SAPDatabase</b></a></td><td>SAP database resource agent</td></tr>
-<tr valign="top"><td><a href="#tag_SAPInstance"><b>SAPInstance</b></a></td><td>SAP instance resource agent</td></tr>
-<tr valign="top"><td><a href="#tag_script"><b>script</b></a></td><td>LSB-compliant init script as a clustered resource.</td></tr>
-<tr valign="top"><td><a href="#tag_service"><b>service</b></a></td><td>Defines a service (resource group).</td></tr>
-<tr valign="top"><td><a href="#tag_tomcat-6"><b>tomcat-6</b></a></td><td>Defines a Tomcat server</td></tr>
-<tr valign="top"><td><a href="#tag_totem"><b>totem</b></a></td><td>OpenAIS msg transport protocol</td></tr>
-<tr valign="top"><td><a href="#tag_unfence"><b>unfence</b></a></td><td>Contains devices for unfencing the node. fence_node(8)</td></tr>
-<tr valign="top"><td><a href="#tag_vm"><b>vm</b></a></td><td>Defines a Virtual Machine</td></tr>
-</table>
-<hr/>
-<h3><a name="tag_action"/>action</h3>
-Overrides resource action timings for a resource instance.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. Name of resource action (start, stop, status, etc.).</td></tr>
- <tr><td><b>depth</b></td><td>Status check depth (resource agent dependent; * = all depths).</td></tr>
- <tr><td><b>interval</b></td><td>Status check interval.</td></tr>
- <tr><td><b>timeout</b></td><td>Action timeout. Meaningless unless __enforce_timeouts is set for this resource.</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_altname"/>altname</h3>
-Defines a second network interface to use for corosync redundant ring mode. cman(5)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. A second hostname or IP address of the node. cman(5)</td></tr>
- <tr><td><b>mcast</b></td><td>The multicast address to use on the second interface. cman(5)</td></tr>
- <tr><td><b>port</b></td><td>The network port to use on the second interface. cman(5)</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_apache"/>apache</h3>
-Defines an Apache web server<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_file</b></td><td>Initial ServerConfigFile</td></tr>
- <tr><td><b>httpd_options</b></td><td>Other command-line options for httpd</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing apache resource in the resources section.</td></tr>
- <tr><td><b>server_root</b></td><td>Initial ServerRoot</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>shutdown_wait</b></td><td>Wait X seconds for correct end of service shutdown</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_ASEHAagent"/>ASEHAagent</h3>
-Sybase ASE Failover Instance<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>deep_probe_timeout</b></td><td>Deep probe timeout value</td></tr>
- <tr><td><b>interfaces_file</b></td><td>Interfaces file</td></tr>
- <tr><td><b>login_file</b></td><td>Login file</td></tr>
- <tr><td><b>name</b></td><td>name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing ASEHAagent resource in the resources section.</td></tr>
- <tr><td><b>server_name</b></td><td>ASE server name</td></tr>
- <tr><td><b>shutdown_timeout</b></td><td>Shutdown timeout value</td></tr>
- <tr><td><b>start_timeout</b></td><td>Start timeout value</td></tr>
- <tr><td><b>sybase_ase</b></td><td>SYBASE_ASE directory name</td></tr>
- <tr><td><b>sybase_home</b></td><td>SYBASE home directory</td></tr>
- <tr><td><b>sybase_ocs</b></td><td>SYBASE_OCS directory name</td></tr>
- <tr><td><b>sybase_user</b></td><td>Sybase user</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_cluster"/>cluster</h3>
-Defines cluster properties, and contains all other configuration. cluster.conf(5)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_version</b></td><td>Required. Revision level of cluster.conf file. cluster.conf(5)</td></tr>
- <tr><td><b>name</b></td><td>Required. Name of the cluster. cluster.conf(5)</td></tr>
-</table><br/>
-Children: <a href="#tag_cman">cman</a> <a href="#tag_totem">totem</a> <a href="#tag_quorumd">quorumd</a> <a href="#tag_fence_daemon">fence_daemon</a> <a href="#tag_fence_xvmd">fence_xvmd</a> <a href="#tag_dlm">dlm</a> <a href="#tag_gfs_controld">gfs_controld</a> <a href="#tag_group">group</a> <a href="#tag_logging">logging</a> <a href="#tag_clusternodes">clusternodes</a> <a href="#tag_fencedevices">fencedevices</a> <a href="#tag_rm">rm</a> <a href="#tag_clvmd">clvmd</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_clusterfs"/>clusterfs</h3>
-Defines a cluster file system mount.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>device</b></td><td>Device or Label</td></tr>
- <tr><td><b>force_unmount</b></td><td>Force Unmount</td></tr>
- <tr><td><b>fsid</b></td><td>NFS File system ID</td></tr>
- <tr><td><b>fstype</b></td><td>File system type</td></tr>
- <tr><td><b>mountpoint</b></td><td>Mount Point</td></tr>
- <tr><td><b>name</b></td><td>File System Name</td></tr>
- <tr><td><b>nfslock</b></td><td>Enable NFS lock workarounds</td></tr>
- <tr><td><b>options</b></td><td>Mount Options</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing clusterfs resource in the resources section.</td></tr>
- <tr><td><b>self_fence</b></td><td>Seppuku Unmount</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_clusternode"/>clusternode</h3>
-Defines cluster node properties, and contains other node specific configuration. cluster.conf(5)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. The hostname or IP address of the node. cluster.conf(5)</td></tr>
- <tr><td><b>nodeid</b></td><td>Required. A unique integer to use as a node identifier. cluster.conf(5)</td></tr>
- <tr><td><b>votes</b></td><td>The number of votes the node contributes to quorum. cman(5)</td></tr>
- <tr><td><b>weight</b></td><td>The dlm locking weight. dlm_controld(8)</td></tr>
-</table><br/>
-Children: <a href="#tag_altname">altname</a> <a href="#ref_FENCE">FENCE</a> <a href="#ref_UNFENCE">UNFENCE</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_clusternodes"/>clusternodes</h3>
-Contains all cluster node definitions. cluster.conf(5)<br/>
-<br/>
-Children: <a href="#tag_clusternode">clusternode</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_clvmd"/>clvmd</h3>
-The clvmd element contains attributes that define parameters for the cluster LVM daemon.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>interface</b></td><td>The interface attribute tells clvmd which cluster interface it should use for internode communications and locking. Valid values for this depend on how the daemon is configured at compile-time, but are typically cman, corosync or openais.</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_cman"/>cman</h3>
-The cman element contains attributes that define the following cluster-wide parameters and behaviors: whether the cluster is a two-node cluster, expected votes, user-specified multicast address, and logging.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>broadcast</b></td><td>enable cman broadcast</td></tr>
- <tr><td><b>ccsd_poll</b></td><td></td></tr>
- <tr><td><b>cluster_id</b></td><td> </td></tr>
- <tr><td><b>debug_mask</b></td><td></td></tr>
- <tr><td><b>disable_openais</b></td><td> </td></tr>
- <tr><td><b>disallowed</b></td><td>Set this to 1 enable cman's Disallowed mode. This is usually only needed for backwards compatibility.</td></tr>
- <tr><td><b>expected_votes</b></td><td>The expected votes value is used by cman to determine quorum. The cluster is quorate if the sum of votes of 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 overriden by setting an explicit expected_votes value.</td></tr>
- <tr><td><b>hash_cluster_id</b></td><td>Enable stronger hashing of cluster ID to avoid collisions.</td></tr>
- <tr><td><b>keyfile</b></td><td></td></tr>
- <tr><td><b>nodename</b></td><td>Local node name; this is set internally by cman-preconfig and should never be set by a user.</td></tr>
- <tr><td><b>port</b></td><td> </td></tr>
- <tr><td><b>quorum_dev_poll</b></td><td>The amount of time after a qdisk poll, in milliseconds, before a quorum disk is considered dead. The quorum disk daemon, qdisk, periodically sends hello messages to cman and ais, indicating that qdisk is present. If qdisk takes more time to send a hello message to cman and ais than by quorum_dev_poll, then cman declares qdisk dead and prints a message indicating that connection to the quorum device has been lost.</td></tr>
- <tr><td><b>shutdown_timeout</b></td><td>Timeout period, in milliseconds, to allow a service to respond during a shutdown.</td></tr>
- <tr><td><b>transport</b></td><td>Specifies transport mechanism to use. Available values are udp (multicast default), udpb (broadcast), udpu (unicast) and rdma (Infiniband). corosync.conf(5)</td></tr>
- <tr><td><b>two_node</b></td><td>The two_node attribute allows you to configure a cluster with only two nodes. Ordinarily, the loss of quorum after one of two nodes fails prevents the remaining node from continuing (if both nodes have one vote.) To enable a two-node cluster, set the two_node value equal to 1. If the two_node value is enabled, the expected_votes value must be set to 1.</td></tr>
- <tr><td><b>upgrading</b></td><td>Set this if you are performing a rolling upgrade of the cluster between major releases.</td></tr>
-</table><br/>
-Children: <a href="#tag_multicast">multicast</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_device"/>device</h3>
-Defines the properties of a device used for fencing or unfencing a node. fenced(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. The name of a fencedevice defined in the fencedevices section. fenced(8)</td></tr>
- <tr><td><b>action</b></td><td>Fencing action to take (off or on).</td></tr>
- <tr><td><b>aptpl</b></td><td></td></tr>
- <tr><td><b>auth</b></td><td>For IPMI LAN only. Authentication Type: none, password, md2, or md5</td></tr>
- <tr><td><b>channel_address</b></td><td>VM Channel IP address (default=10.0.2.179)</td></tr>
- <tr><td><b>cipher</b></td><td>Ciphersuite to use (same as ipmitool -C parameter)</td></tr>
- <tr><td><b>cmd_prompt</b></td><td>Force command prompt</td></tr>
- <tr><td><b>community</b></td><td>Set the community string</td></tr>
- <tr><td><b>cserver</b></td><td>The hostname (and optionally the username in the form of username@hostname) assigned to the device. Refer to the fence_egenera(8) man page for more information.</td></tr>
- <tr><td><b>debug</b></td><td>Specify (stdin) or increment (command line) debug level</td></tr>
- <tr><td><b>delay</b></td><td>Wait this many seconds before fencing is started. fence_egenera(8)</td></tr>
- <tr><td><b>device</b></td><td>The device the switch is connected to on the controlling host.</td></tr>
- <tr><td><b>devices</b></td><td>List of devices to fence (separated by commas).</td></tr>
- <tr><td><b>domain</b></td><td>Virtual Machine (domain name) to fence (deprecated)</td></tr>
- <tr><td><b>drac_version</b></td><td>Force DRAC version to use</td></tr>
- <tr><td><b>esh</b></td><td>Path to the esh command on the cserver. fence_egenera(8)</td></tr>
- <tr><td><b>exec</b></td><td>Command to execute</td></tr>
- <tr><td><b>hash</b></td><td>Packet hash strength (none, sha1, [sha256], sha512)</td></tr>
- <tr><td><b>help</b></td><td>Display help and exit</td></tr>
- <tr><td><b>hidden_page</b></td><td>Name of hidden page</td></tr>
- <tr><td><b>hmc_version</b></td><td>Force HMC version to use (3 or 4)</td></tr>
- <tr><td><b>identity_file</b></td><td>Identity file for ssh</td></tr>
- <tr><td><b>inet4_only</b></td><td>Forces agent to use IPv4 addresses only</td></tr>
- <tr><td><b>inet6_only</b></td><td>Forces agent to use IPv6 addresses only</td></tr>
- <tr><td><b>io_fencing</b></td><td>Fencing Action</td></tr>
- <tr><td><b>ipaddr</b></td><td>IP address or the name of the device.</td></tr>
- <tr><td><b>ipport</b></td><td>Multicast or VMChannel IP port (default=1229)</td></tr>
- <tr><td><b>ip_family</b></td><td>IP Family ([auto], ipv4, ipv6)</td></tr>
- <tr><td><b>key</b></td><td></td></tr>
- <tr><td><b>key_file</b></td><td>Shared key file (default=/etc/cluster/fence_xvm.key)</td></tr>
- <tr><td><b>lanplus</b></td><td>For IPMI LAN only. Set value to either True or 1; leave out for false.</td></tr>
- <tr><td><b>logfile</b></td><td>Location to output logs from fence_scsi.</td></tr>
- <tr><td><b>login</b></td><td>The login name used to access the device. </td></tr>
- <tr><td><b>login_timeout</b></td><td>Wait X seconds for cmd prompt after login</td></tr>
- <tr><td><b>lpan</b></td><td>The lpan to operate on. fence_egenera(8)</td></tr>
- <tr><td><b>managed</b></td><td>Managed system name</td></tr>
- <tr><td><b>method</b></td><td>Method to fence (onoff or cycle)</td></tr>
- <tr><td><b>missing_as_off</b></td><td>Missing port returns OFF instead of failure</td></tr>
- <tr><td><b>module_name</b></td><td>DRAC/MC module name</td></tr>
- <tr><td><b>multicast_address</b></td><td>Multicast address (default=225.0.0.12 / ff05::3:1)</td></tr>
- <tr><td><b>nodename</b></td><td>Name of the node to be fenced. Refer to fence_scsi(8) for more information.</td></tr>
- <tr><td><b>option</b></td><td> </td></tr>
- <tr><td><b>partition</b></td><td>Partition name</td></tr>
- <tr><td><b>passwd</b></td><td>The password used to authenticate the connection to the device.</td></tr>
- <tr><td><b>passwd_script</b></td><td>The script that supplies a password for access to the fence device. Using this supersedes the Password parameter.</td></tr>
- <tr><td><b>port</b></td><td>The switch outlet number.</td></tr>
- <tr><td><b>power_timeout</b></td><td>Test X seconds for status change after ON/OFF</td></tr>
- <tr><td><b>power_wait</b></td><td>Wait X seconds after issuing ON/OFF</td></tr>
- <tr><td><b>pserver</b></td><td>The pserver to operate on. fence_egenera(8)</td></tr>
- <tr><td><b>retrans</b></td><td>Multicast retransmit time (in 1/10sec; default=20)</td></tr>
- <tr><td><b>retry_on</b></td><td>Count of attempts to retry power on</td></tr>
- <tr><td><b>ribcl</b></td><td>Force ribcl version to use</td></tr>
- <tr><td><b>rpowerpath</b></td><td></td></tr>
- <tr><td><b>secure</b></td><td>SSH connection</td></tr>
- <tr><td><b>separator</b></td><td>Separator for CSV created by operation list</td></tr>
- <tr><td><b>serial_device</b></td><td>Serial device (default=/dev/ttyS1)</td></tr>
- <tr><td><b>serial_params</b></td><td>Serial Parameters (default=115200,8N1)</td></tr>
- <tr><td><b>servers</b></td><td>The hostname of each GNBD to disable. For multiple hostnames, separate each hostname with a space.</td></tr>
- <tr><td><b>shell_timeout</b></td><td>Wait X seconds for cmd prompt after issuing command</td></tr>
- <tr><td><b>snmp_auth_prot</b></td><td>Set authentication protocol (MD5|SHA)</td></tr>
- <tr><td><b>snmp_priv_passwd</b></td><td>Set privacy protocol password</td></tr>
- <tr><td><b>snmp_priv_passwd_script</b></td><td>Script to run to retrieve privacy password</td></tr>
- <tr><td><b>snmp_priv_prot</b></td><td>Set privacy protocol (DES|AES)</td></tr>
- <tr><td><b>snmp_sec_level</b></td><td>Set security level (noAuthNoPriv|authNoPriv|authPriv)</td></tr>
- <tr><td><b>snmp_version</b></td><td>Specifies SNMP version to use (1,2c,3)</td></tr>
- <tr><td><b>ssl</b></td><td>SSL connection</td></tr>
- <tr><td><b>switch</b></td><td>Physical switch number on device</td></tr>
- <tr><td><b>timeout</b></td><td>Fencing timeout (in seconds; default=30)</td></tr>
- <tr><td><b>udpport</b></td><td>UDP/TCP port to use for connection with device</td></tr>
- <tr><td><b>user</b></td><td>See fence_egenera(8)</td></tr>
- <tr><td><b>use_uuid</b></td><td>Treat [domain] as UUID instead of domain name. This is provided for compatibility with older fence_xvmd installations.</td></tr>
- <tr><td><b>verbose</b></td><td>Verbose mode</td></tr>
- <tr><td><b>version</b></td><td>Display version information and exit</td></tr>
- <tr><td><b>vmware_datacenter</b></td><td>Show only machines in specified datacenter</td></tr>
- <tr><td><b>vmware_type</b></td><td>Type of VMware to connect</td></tr>
-</table><br/>
-Children: <a href="#ref_FENCEDEVICEOPTIONS">FENCEDEVICEOPTIONS</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_dlm"/>dlm</h3>
-Configuration for dlm and dlm_controld daemon. dlm_controld(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>drop_resources_age</b></td><td>Plock ownership drop resources age. dlm_controld(8)</td></tr>
- <tr><td><b>drop_resources_count</b></td><td>Plock ownership drop resources count. dlm_controld(8)</td></tr>
- <tr><td><b>drop_resources_time</b></td><td>Plock ownership drop resources time. dlm_controld(8)</td></tr>
- <tr><td><b>enable_deadlk</b></td><td>Deadlock detection capability. dlm_controld(8)</td></tr>
- <tr><td><b>enable_fencing</b></td><td>Fencing recovery dependency. dlm_controld(8)</td></tr>
- <tr><td><b>enable_plock</b></td><td>Cluster fs posix lock capability. dlm_controld(8)</td></tr>
- <tr><td><b>enable_quorum</b></td><td>Quorum recovery dependency. dlm_controld(8)</td></tr>
- <tr><td><b>log_debug</b></td><td>Set to 1 to enable dlm kernel debugging messages. dlm_controld(8)</td></tr>
- <tr><td><b>plock_debug</b></td><td>Set to 1 to enable posix lock debugging. dlm_controld(8)</td></tr>
- <tr><td><b>plock_ownership</b></td><td>Set to 1/0 to enable/disable plock ownership. dlm_controld(8)</td></tr>
- <tr><td><b>plock_rate_limit</b></td><td>Limit the rate of plock operations. dlm_controld(8)</td></tr>
- <tr><td><b>protocol</b></td><td>The dlm lowcomms protocol. dlm_controld(8)</td></tr>
- <tr><td><b>timewarn</b></td><td>Number of centiseconds a lock is blocked before notifying dlm_controld deadlock code. dlm_controld(8)</td></tr>
-</table><br/>
-Children: <a href="#tag_lockspace">lockspace</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_event"/>event</h3>
-Defines an event.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. Symbolic name for an event.</td></tr>
- <tr><td><b>class</b></td><td>Event class (service, node).</td></tr>
- <tr><td><b>file</b></td><td>Path to S/Lang script to execute.</td></tr>
- <tr><td><b>node</b></td><td>(Node) The node name must match the specified value in order for the script to be run.</td></tr>
- <tr><td><b>node_clean</b></td><td>(Node) The node must have been fenced in order for the script to be run.</td></tr>
- <tr><td><b>node_id</b></td><td>(Node) The node ID must match the specified value in order for the script to be run.</td></tr>
- <tr><td><b>node_local</b></td><td>(Node) This script may only run on the current central processing node.</td></tr>
- <tr><td><b>node_state</b></td><td>(Node) The node state must match the specified value (0 or 1) in order for the script to be run.</td></tr>
- <tr><td><b>priority</b></td><td>Order (1..99) of event.</td></tr>
- <tr><td><b>service</b></td><td>(Service) The service name (service:foo) must match the specified value in order for the event script to be run.</td></tr>
- <tr><td><b>service_owner</b></td><td>(Service) The service owner must match the specified value in order for the event script to be run.</td></tr>
- <tr><td><b>service_state</b></td><td>(Service) The service's state must match the specified value in order for the script to be run (started, stopped, disabled, failed).</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_events"/>events</h3>
-Event definitions (central_processing only).<br/>
-<br/>
-Children: <a href="#tag_event">event</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_failoverdomain"/>failoverdomain</h3>
-Specifies properties of a specific failover domain<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. The name of the failover domain.</td></tr>
- <tr><td><b>nofailback</b></td><td>Do not move service to a more preferred node if it is currently running.</td></tr>
- <tr><td><b>ordered</b></td><td>Set value to 1 if the failover domain is ordered; set value to 0 if unordered.</td></tr>
- <tr><td><b>restricted</b></td><td>Set value to 1 if the failover domain is restricted; set value to 0 if unrestricted.</td></tr>
-</table><br/>
-Children: <a href="#tag_failoverdomainnode">failoverdomainnode</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_failoverdomainnode"/>failoverdomainnode</h3>
-A node in a failover domain<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. Name of the node.</td></tr>
- <tr><td><b>priority</b></td><td>A number specifying the priority; lower numbers having higher priority</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_failoverdomains"/>failoverdomains</h3>
-Failover domain definitions.<br/>
-<br/>
-Children: <a href="#tag_failoverdomain">failoverdomain</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_fence"/>fence</h3>
-Contains methods for fencing the node in different ways. fenced(8)<br/>
-<br/>
-Children: <a href="#tag_method">method</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_fencedevice"/>fencedevice</h3>
-Defines fence device properties. fenced(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>agent</b></td><td>Required. The fence agent to be used. fenced(8)</td></tr>
- <tr><td><b>name</b></td><td>Required. A name that is used to reference this fence device from clusternode fence section. fenced(8)</td></tr>
- <tr><td><b>action</b></td><td>Fencing action to take (off or on).</td></tr>
- <tr><td><b>aptpl</b></td><td></td></tr>
- <tr><td><b>auth</b></td><td>For IPMI LAN only. Authentication Type: none, password, md2, or md5</td></tr>
- <tr><td><b>channel_address</b></td><td>VM Channel IP address (default=10.0.2.179)</td></tr>
- <tr><td><b>cipher</b></td><td>Ciphersuite to use (same as ipmitool -C parameter)</td></tr>
- <tr><td><b>cmd_prompt</b></td><td>Force command prompt</td></tr>
- <tr><td><b>community</b></td><td>Set the community string</td></tr>
- <tr><td><b>cserver</b></td><td>The hostname (and optionally the username in the form of username@hostname) assigned to the device. Refer to the fence_egenera(8) man page for more information.</td></tr>
- <tr><td><b>debug</b></td><td>Specify (stdin) or increment (command line) debug level</td></tr>
- <tr><td><b>delay</b></td><td>Wait this many seconds before fencing is started. fence_egenera(8)</td></tr>
- <tr><td><b>device</b></td><td>The device the switch is connected to on the controlling host.</td></tr>
- <tr><td><b>devices</b></td><td>List of devices to fence (separated by commas).</td></tr>
- <tr><td><b>domain</b></td><td>Virtual Machine (domain name) to fence (deprecated)</td></tr>
- <tr><td><b>drac_version</b></td><td>Force DRAC version to use</td></tr>
- <tr><td><b>esh</b></td><td>Path to the esh command on the cserver. fence_egenera(8)</td></tr>
- <tr><td><b>exec</b></td><td>Command to execute</td></tr>
- <tr><td><b>hash</b></td><td>Packet hash strength (none, sha1, [sha256], sha512)</td></tr>
- <tr><td><b>help</b></td><td>Display help and exit</td></tr>
- <tr><td><b>hidden_page</b></td><td>Name of hidden page</td></tr>
- <tr><td><b>hmc_version</b></td><td>Force HMC version to use (3 or 4)</td></tr>
- <tr><td><b>identity_file</b></td><td>Identity file for ssh</td></tr>
- <tr><td><b>inet4_only</b></td><td>Forces agent to use IPv4 addresses only</td></tr>
- <tr><td><b>inet6_only</b></td><td>Forces agent to use IPv6 addresses only</td></tr>
- <tr><td><b>io_fencing</b></td><td>Fencing Action</td></tr>
- <tr><td><b>ipaddr</b></td><td>IP address or the name of the device.</td></tr>
- <tr><td><b>ipport</b></td><td>Multicast or VMChannel IP port (default=1229)</td></tr>
- <tr><td><b>ip_family</b></td><td>IP Family ([auto], ipv4, ipv6)</td></tr>
- <tr><td><b>key</b></td><td></td></tr>
- <tr><td><b>key_file</b></td><td>Shared key file (default=/etc/cluster/fence_xvm.key)</td></tr>
- <tr><td><b>lanplus</b></td><td>For IPMI LAN only. Set value to either True or 1; leave out for false.</td></tr>
- <tr><td><b>logfile</b></td><td>Location to output logs from fence_scsi.</td></tr>
- <tr><td><b>login</b></td><td>The login name used to access the device. </td></tr>
- <tr><td><b>login_timeout</b></td><td>Wait X seconds for cmd prompt after login</td></tr>
- <tr><td><b>lpan</b></td><td>The lpan to operate on. fence_egenera(8)</td></tr>
- <tr><td><b>managed</b></td><td>Managed system name</td></tr>
- <tr><td><b>method</b></td><td>Method to fence (onoff or cycle)</td></tr>
- <tr><td><b>missing_as_off</b></td><td>Missing port returns OFF instead of failure</td></tr>
- <tr><td><b>module_name</b></td><td>DRAC/MC module name</td></tr>
- <tr><td><b>multicast_address</b></td><td>Multicast address (default=225.0.0.12 / ff05::3:1)</td></tr>
- <tr><td><b>nodename</b></td><td>Name of the node to be fenced. Refer to fence_scsi(8) for more information.</td></tr>
- <tr><td><b>option</b></td><td> </td></tr>
- <tr><td><b>partition</b></td><td>Partition name</td></tr>
- <tr><td><b>passwd</b></td><td>The password used to authenticate the connection to the device.</td></tr>
- <tr><td><b>passwd_script</b></td><td>The script that supplies a password for access to the fence device. Using this supersedes the Password parameter.</td></tr>
- <tr><td><b>port</b></td><td>The switch outlet number.</td></tr>
- <tr><td><b>power_timeout</b></td><td>Test X seconds for status change after ON/OFF</td></tr>
- <tr><td><b>power_wait</b></td><td>Wait X seconds after issuing ON/OFF</td></tr>
- <tr><td><b>pserver</b></td><td>The pserver to operate on. fence_egenera(8)</td></tr>
- <tr><td><b>retrans</b></td><td>Multicast retransmit time (in 1/10sec; default=20)</td></tr>
- <tr><td><b>retry_on</b></td><td>Count of attempts to retry power on</td></tr>
- <tr><td><b>ribcl</b></td><td>Force ribcl version to use</td></tr>
- <tr><td><b>rpowerpath</b></td><td></td></tr>
- <tr><td><b>secure</b></td><td>SSH connection</td></tr>
- <tr><td><b>separator</b></td><td>Separator for CSV created by operation list</td></tr>
- <tr><td><b>serial_device</b></td><td>Serial device (default=/dev/ttyS1)</td></tr>
- <tr><td><b>serial_params</b></td><td>Serial Parameters (default=115200,8N1)</td></tr>
- <tr><td><b>servers</b></td><td>The hostname of each GNBD to disable. For multiple hostnames, separate each hostname with a space.</td></tr>
- <tr><td><b>shell_timeout</b></td><td>Wait X seconds for cmd prompt after issuing command</td></tr>
- <tr><td><b>snmp_auth_prot</b></td><td>Set authentication protocol (MD5|SHA)</td></tr>
- <tr><td><b>snmp_priv_passwd</b></td><td>Set privacy protocol password</td></tr>
- <tr><td><b>snmp_priv_passwd_script</b></td><td>Script to run to retrieve privacy password</td></tr>
- <tr><td><b>snmp_priv_prot</b></td><td>Set privacy protocol (DES|AES)</td></tr>
- <tr><td><b>snmp_sec_level</b></td><td>Set security level (noAuthNoPriv|authNoPriv|authPriv)</td></tr>
- <tr><td><b>snmp_version</b></td><td>Specifies SNMP version to use (1,2c,3)</td></tr>
- <tr><td><b>ssl</b></td><td>SSL connection</td></tr>
- <tr><td><b>switch</b></td><td>Physical switch number on device</td></tr>
- <tr><td><b>timeout</b></td><td>Fencing timeout (in seconds; default=30)</td></tr>
- <tr><td><b>udpport</b></td><td>UDP/TCP port to use for connection with device</td></tr>
- <tr><td><b>user</b></td><td>See fence_egenera(8)</td></tr>
- <tr><td><b>use_uuid</b></td><td>Treat [domain] as UUID instead of domain name. This is provided for compatibility with older fence_xvmd installations.</td></tr>
- <tr><td><b>verbose</b></td><td>Verbose mode</td></tr>
- <tr><td><b>version</b></td><td>Display version information and exit</td></tr>
- <tr><td><b>vmware_datacenter</b></td><td>Show only machines in specified datacenter</td></tr>
- <tr><td><b>vmware_type</b></td><td>Type of VMware to connect</td></tr>
-</table><br/>
-Children: <a href="#ref_FENCEDEVICEOPTIONS">FENCEDEVICEOPTIONS</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_fencedevices"/>fencedevices</h3>
-Contains all fence device definitions. fenced(8)<br/>
-<br/>
-Children: <a href="#tag_fencedevice">fencedevice</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_fence_daemon"/>fence_daemon</h3>
-Configuration for fenced daemon. fenced(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>clean_start</b></td><td>Set to 1 to disable startup fencing. fenced(8)</td></tr>
- <tr><td><b>override_path</b></td><td>Location of a FIFO used for communication between fenced and fence_ack_manual. fenced(8)</td></tr>
- <tr><td><b>override_time</b></td><td>Number of seconds to wait for a manual override after a failed fencing attempt before the next attempt. fenced(8)</td></tr>
- <tr><td><b>post_fail_delay</b></td><td>Number of seconds the daemon will wait before fencing any victims after a node fails. fenced(8)</td></tr>
- <tr><td><b>post_join_delay</b></td><td>Number of seconds the daemon will wait before fencing any victims after a node joins the fence domain. fenced(8)</td></tr>
- <tr><td><b>skip_undefined</b></td><td>Set to 1 to disable startup fencing of nodes with no fence methods defined. fenced(8)</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_fence_xvmd"/>fence_xvmd</h3>
-Fence_xvm daemon. The fence_xvmd fence device is an I/O fencing host that resides on dom0 and is used in conjunction with the fence_xvm fencing agent. Together, these two programs fence Xen virtual machines that are in a cluster. There is a requirement that the parent dom0s are also a part of their own CMAN/OpenAIS based cluster, and that the dom0 cluster does not share any members with the domU cluster. Furthermore, the dom0 cluster is required to have fencing if domU recovery is expected to be automatic.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>auth</b></td><td></td></tr>
- <tr><td><b>debug</b></td><td></td></tr>
- <tr><td><b>hash</b></td><td></td></tr>
- <tr><td><b>key_file</b></td><td></td></tr>
- <tr><td><b>multicast_address</b></td><td></td></tr>
- <tr><td><b>multicast_interface</b></td><td></td></tr>
- <tr><td><b>port</b></td><td></td></tr>
- <tr><td><b>uri</b></td><td></td></tr>
- <tr><td><b>use_uuid</b></td><td></td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_fs"/>fs</h3>
-Defines a file system mount.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>device</b></td><td>Device or Label</td></tr>
- <tr><td><b>force_fsck</b></td><td>Force fsck support</td></tr>
- <tr><td><b>force_unmount</b></td><td>Force Unmount</td></tr>
- <tr><td><b>fsid</b></td><td>NFS File system ID</td></tr>
- <tr><td><b>fstype</b></td><td>File system type</td></tr>
- <tr><td><b>mountpoint</b></td><td>Mount Point</td></tr>
- <tr><td><b>name</b></td><td>File System Name</td></tr>
- <tr><td><b>nfslock</b></td><td>Enable NFS lock workarounds</td></tr>
- <tr><td><b>options</b></td><td>Mount Options</td></tr>
- <tr><td><b>quick_status</b></td><td>Quick/brief status checks.</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing fs resource in the resources section.</td></tr>
- <tr><td><b>self_fence</b></td><td>Seppuku Unmount</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_gfs_controld"/>gfs_controld</h3>
-Configuration for gfs_controld daemon. gfs_controld(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>drop_resources_age</b></td><td>Plock ownership drop resources age. gfs_controld(8)</td></tr>
- <tr><td><b>drop_resources_count</b></td><td>Plock ownership drop resources count. gfs_controld(8)</td></tr>
- <tr><td><b>drop_resources_time</b></td><td>Plock ownership drop resources time. gfs_controld(8)</td></tr>
- <tr><td><b>enable_plock</b></td><td>Cluster fs posix lock capability. gfs_controld(8)</td></tr>
- <tr><td><b>enable_withdraw</b></td><td>Set to 1/0 to enable/disable a response to a withdraw. gfs_controld(8)</td></tr>
- <tr><td><b>plock_debug</b></td><td>Set to 1 to enable posix lock debugging. gfs_controld(8)</td></tr>
- <tr><td><b>plock_ownership</b></td><td>Set to 1/0 to enable/disable plock ownership. gfs_controld(8)</td></tr>
- <tr><td><b>plock_rate_limit</b></td><td>Limit the rate of plock operations. gfs_controld(8)</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_group"/>group</h3>
-Defines groupd configuration. groupd(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>groupd_compat</b></td><td>Enable compatibility with cluster2 nodes. groupd(8)</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_heuristic"/>heuristic</h3>
-Defines a heuristic. qdisk(5).<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>program</b></td><td>Required. The program used to determine if this heuristic is alive. This can be anything that can be executed by /bin/sh -c. A return value of 0 indicates success; anything else indicates failure.</td></tr>
- <tr><td><b>interval</b></td><td>The frequency (in seconds) at which the heuristic is polled. qdisk(5).</td></tr>
- <tr><td><b>score</b></td><td>The weight of this heuristic. Be careful when determining scores for heuristics.</td></tr>
- <tr><td><b>tko</b></td><td>The number of consecutive failures before a heuristic is discounted. qdisk(5).</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_interface"/>interface</h3>
-Defines Totem interface options. corosync.conf(5)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>bindnetaddr</b></td><td>Specifies the address to which the corosync executive should bind. corosync.conf(5)</td></tr>
- <tr><td><b>broadcast</b></td><td>If set to yes, use broadcast instead of multicast for communication. corosync.conf(5)</td></tr>
- <tr><td><b>mcastaddr</b></td><td>Defines the multicast address used by corosync for this interface. corosync.conf(5)</td></tr>
- <tr><td><b>mcastport</b></td><td>Specifies the UDP port number when using multicast. corosync.conf(5)</td></tr>
- <tr><td><b>ringnumber</b></td><td>Sets the ring interface for the interface for RRP mode. corosync.conf(5)</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_ip"/>ip</h3>
-This is an IP address.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>address</b></td><td>IP Address</td></tr>
- <tr><td><b>disable_rdisc</b></td><td>Disable updating of routing using RDISC protocol</td></tr>
- <tr><td><b>family</b></td><td>Family</td></tr>
- <tr><td><b>monitor_link</b></td><td>Monitor NIC Link</td></tr>
- <tr><td><b>nfslock</b></td><td>Enable NFS lock workarounds</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing ip resource in the resources section.</td></tr>
- <tr><td><b>sleeptime</b></td><td>Amount of time (seconds) to sleep.</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_lockspace"/>lockspace</h3>
-Individual lockspace configuration. dlm_controld(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. Name of the lockspace. dlm_controld(8)</td></tr>
- <tr><td><b>nodir</b></td><td>Set to 1 to disable the internal resource directory. dlm_controld(8)</td></tr>
-</table><br/>
-Children: <a href="#tag_master">master</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_logging"/>logging</h3>
-Defines global logging configuration, and contains daemon-specific configuration. cluster.conf(5)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>debug</b></td><td>Set to on to enable debugging messages in log file. cluster.conf(5)</td></tr>
- <tr><td><b>logfile</b></td><td>The log file path name. cluster.conf(5)</td></tr>
- <tr><td><b>logfile_priority</b></td><td>Messages at this level and higher are written to log file. cluster.conf(5)</td></tr>
- <tr><td><b>syslog_facility</b></td><td>The facility used for syslog messages. cluster.conf(5)</td></tr>
- <tr><td><b>syslog_priority</b></td><td>Messages at this level and higher are sent to syslog. cluster.conf(5)</td></tr>
- <tr><td><b>to_logfile</b></td><td>Set to yes/no to enable/disable messages to log file. cluster.conf(5)</td></tr>
- <tr><td><b>to_syslog</b></td><td>Set to yes/no to enable/disable messages to syslog. cluster.conf(5)</td></tr>
-</table><br/>
-Children: <a href="#tag_logging_daemon">logging_daemon</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_logging_daemon"/>logging_daemon</h3>
-Defines daemon-specific logging configuration. cluster.conf(5)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. The daemon name. cluster.conf(5)</td></tr>
- <tr><td><b>debug</b></td><td>Same as global.</td></tr>
- <tr><td><b>logfile</b></td><td>Same as global.</td></tr>
- <tr><td><b>logfile_priority</b></td><td>Same as global.</td></tr>
- <tr><td><b>subsys</b></td><td>A corosync subsystem name. cluster.conf(5)</td></tr>
- <tr><td><b>syslog_facility</b></td><td>Same as global.</td></tr>
- <tr><td><b>syslog_priority</b></td><td>Same as global.</td></tr>
- <tr><td><b>to_logfile</b></td><td>Same as global.</td></tr>
- <tr><td><b>to_syslog</b></td><td>Same as global.</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_lvm"/>lvm</h3>
-LVM Failover script<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>lv_name</b></td><td>Logical Volume name (optional).</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>nfslock</b></td><td>Enable NFS lock workarounds</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing lvm resource in the resources section.</td></tr>
- <tr><td><b>self_fence</b></td><td>Fence the node if it is not able to clean up LVM tags</td></tr>
- <tr><td><b>vg_name</b></td><td>Volume group name</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_master"/>master</h3>
-Defines a master node. dlm_controld(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. The name of a node that should be master resources/locks. dlm_controld(8)</td></tr>
- <tr><td><b>weight</b></td><td>The proportion of resources this node should master. dlm_controld(8)</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_method"/>method</h3>
-Contains one or more devices for fencing the node a single way. fenced(8)<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Required. A name used to distinguish multiple methods from each other. fenced(8)</td></tr>
-</table><br/>
-Children: <a href="#ref_DEVICE">DEVICE</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_multicast"/>multicast</h3>
-The multicast element provides the ability for a user to specify a multicast address instead of using the multicast address generated by cman. If a user does not specify a multicast address, cman creates one. It forms the upper 16 bits of the multicast address with 239.192 and forms the lower 16 bits based on the cluster ID.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>addr</b></td><td>Required. A multicast address specified by a user. If you do specify a multicast address, you should use the 239.192.x.x series that cman uses. Otherwise, using a multicast address outside that range may cause unpredictable results. For example, using 224.0.0.x (All hosts on the network) may not be routed correctly, or even routed at all by some hardware.</td></tr>
-</table><br/>
-<a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_mysql"/>mysql</h3>
-Defines a MySQL database server<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_file</b></td><td>Define configuration file</td></tr>
- <tr><td><b>listen_address</b></td><td>Define an IP address for MySQL server. If the address is not given then first IP address from the service is taken.</td></tr>
- <tr><td><b>mysqld_options</b></td><td>Other command-line options for mysqld</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing mysql resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>shutdown_wait</b></td><td>Wait X seconds for correct end of service shutdown</td></tr>
- <tr><td><b>startup_wait</b></td><td>Wait X seconds for correct end of service startup</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_named"/>named</h3>
-Defines an instance of named server<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_file</b></td><td>Config File</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>named_options</b></td><td>Other command-line options for named</td></tr>
- <tr><td><b>named_sdb</b></td><td>Simplified Database Backend</td></tr>
- <tr><td><b>named_working_dir</b></td><td>Other command-line options for named</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing named resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>shutdown_wait</b></td><td>Wait X seconds for correct end of service shutdown</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_netfs"/>netfs</h3>
-Defines an NFS/CIFS file system mount.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>export</b></td><td>Export</td></tr>
- <tr><td><b>force_unmount</b></td><td>Force Unmount</td></tr>
- <tr><td><b>fstype</b></td><td>File System Type</td></tr>
- <tr><td><b>host</b></td><td>IP or Host</td></tr>
- <tr><td><b>mountpoint</b></td><td>Mount Point</td></tr>
- <tr><td><b>name</b></td><td>File System Name</td></tr>
- <tr><td><b>no_unmount</b></td><td>Skip unmount opration</td></tr>
- <tr><td><b>options</b></td><td>Mount Options</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing netfs resource in the resources section.</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_nfsclient"/>nfsclient</h3>
-Defines an NFS client.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>allow_recover</b></td><td>Allow recovery</td></tr>
- <tr><td><b>fsid</b></td><td>File system ID</td></tr>
- <tr><td><b>name</b></td><td>Client Name</td></tr>
- <tr><td><b>options</b></td><td>Export Options</td></tr>
- <tr><td><b>path</b></td><td>Path to Export</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing nfsclient resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Service Name</td></tr>
- <tr><td><b>svcname</b></td><td></td></tr>
- <tr><td><b>target</b></td><td>Target Hostname, Wildcard, or Netgroup</td></tr>
- <tr><td><b>use_cache</b></td><td>Enable exportfs list caching</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_nfsexport"/>nfsexport</h3>
-This defines an NFS export.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>device</b></td><td>If you can see this, your GUI is broken.</td></tr>
- <tr><td><b>fsid</b></td><td>If you can see this, your GUI is broken.</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>path</b></td><td>If you can see this, your GUI is broken.</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing nfsexport resource in the resources section.</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_nfsserver"/>nfsserver</h3>
-This defines an NFS server resource.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>nfspath</b></td><td>This is the path containing shared NFS recovery information, relative to the path parameter.</td></tr>
- <tr><td><b>path</b></td><td>This is the path you intend to export.</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing nfsserver resource in the resources section.</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_openldap"/>openldap</h3>
-Defines an Open LDAP server<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_file</b></td><td>Config File</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing openldap resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>shutdown_wait</b></td><td>Wait X seconds for correct end of service shutdown</td></tr>
- <tr><td><b>slapd_options</b></td><td>Other command-line options for slapd</td></tr>
- <tr><td><b>url_list</b></td><td>URL list</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_oracledb"/>oracledb</h3>
-Oracle 10g Failover Instance<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>home</b></td><td>Oracle Home Directory</td></tr>
- <tr><td><b>listener_name</b></td><td>Oracle Listener Instance Name</td></tr>
- <tr><td><b>name</b></td><td>Oracle SID</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing oracledb resource in the resources section.</td></tr>
- <tr><td><b>type</b></td><td>Oracle Installation Type</td></tr>
- <tr><td><b>user</b></td><td>Oracle User Name</td></tr>
- <tr><td><b>vhost</b></td><td>Virtual Hostname</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_orainstance"/>orainstance</h3>
-Oracle 10g Failover Instance<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>home</b></td><td>Oracle Home Directory</td></tr>
- <tr><td><b>listeners</b></td><td>Oracle listeners</td></tr>
- <tr><td><b>lockfile</b></td><td>Pathname for lockfile</td></tr>
- <tr><td><b>name</b></td><td>Oracle SID</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing orainstance resource in the resources section.</td></tr>
- <tr><td><b>user</b></td><td>Oracle User Name</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_oralistener"/>oralistener</h3>
-Oracle 10g Listener Instance<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>home</b></td><td>Oracle Home Directory</td></tr>
- <tr><td><b>name</b></td><td>Listener name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing oralistener resource in the resources section.</td></tr>
- <tr><td><b>user</b></td><td>Oracle User Name</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_postgres-8"/>postgres-8</h3>
-Defines a PostgreSQL server<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_file</b></td><td>Config File</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>postmaster_options</b></td><td>Other command-line options for postmaster</td></tr>
- <tr><td><b>postmaster_user</b></td><td>User who runs the database server</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing postgres-8 resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>shutdown_wait</b></td><td>Wait X seconds for correct end of service shutdown</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_quorumd"/>quorumd</h3>
-This element and its attributes define parameters for the quorum disk daemon, quorumd. qdisk(5).<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>allow_kill</b></td><td>Instruct cman to evict nodes which are not updating the quorum disk. qdisk(5).</td></tr>
- <tr><td><b>cman_label</b></td><td>This is the name used by CMAN for the quorum device instead of the device name. qdisk(5).</td></tr>
- <tr><td><b>device</b></td><td>The storage device the quorum daemon uses. The device must be the same on all nodes. qdisk(5).</td></tr>
- <tr><td><b>interval</b></td><td>The frequency of read/write cycles, in seconds. qdisk(5).</td></tr>
- <tr><td><b>io_timeout</b></td><td>Die if we cannot get a write out to disk after interval*tko. qdisk(5).</td></tr>
- <tr><td><b>label</b></td><td>Specifies the quorum disk label created by the mkqdisk utility. If this field contains an entry, the label overrides the Device field. If this field is used, the quorum daemon reads /proc/partitions and checks for qdisk signatures on every block device found, comparing the label against the specified label. This is useful in configurations where the quorum device name differs among nodes. qdisk(5).</td></tr>
- <tr><td><b>master_wins</b></td><td>Enable master-wins mode (two node clusters). qdisk(5).</td></tr>
- <tr><td><b>max_error_cycles</b></td><td>Die after this many cycles which receive I/O errors. qdisk(5).</td></tr>
- <tr><td><b>min_score</b></td><td>The minimum score for a node to be considered alive. If omitted or set to 0, the default function, floor((n+1)/2), is used, where n is the sum of the heuristics scores. The Minimum Score value must never exceed the sum of the heuristic scores; otherwise, the quorum disk cannot be available. qdisk(5).</td></tr>
- <tr><td><b>paranoid</b></td><td>Reboot if we are running too slowly. qdisk(5).</td></tr>
- <tr><td><b>priority</b></td><td>Scheduler priority. qdisk(5).</td></tr>
- <tr><td><b>reboot</b></td><td>Reboot if our score drops too low. qdisk(5).</td></tr>
- <tr><td><b>scheduler</b></td><td>Scheduler. qdisk(5).</td></tr>
- <tr><td><b>status_file</b></td><td>Debugging file. qdisk(5).</td></tr>
- <tr><td><b>stop_cman</b></td><td>Stop cman if the quorum disk cannot be found during startup. qdisk(5).</td></tr>
- <tr><td><b>tko</b></td><td>The number of cycles a node must miss to be declared dead. qdisk(5).</td></tr>
- <tr><td><b>tko_up</b></td><td>Amount of positive changes before a host is considered online. qdisk(5).</td></tr>
- <tr><td><b>upgrade_wait</b></td><td>Amount of cycles wait for conflicts for a bid for master status. qdisk(5).</td></tr>
- <tr><td><b>use_uptime</b></td><td>Use /proc/uptime instead of gettimeofday(). qdisk(5).</td></tr>
- <tr><td><b>votes</b></td><td>The number of votes the quorum daemon advertises to CMAN when it has a high enough score. qdisk(5).</td></tr>
-</table><br/>
-Children: <a href="#tag_heuristic">heuristic</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_resources"/>resources</h3>
-Defines global resources which may be referenced in services. You may redefine actions for resources here, but child resource definitions are ignored in this section.<br/>
-<br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_rm"/>rm</h3>
-This element and its attributes define resources (for example an IP address) required to create HA cluster services, the HA cluster services themselves, and failover domains for the HA cluster services.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>central_processing</b></td><td>Enable central processing mode (requires cluster-wide shut down and restart of rgmanager.).</td></tr>
- <tr><td><b>log_facility</b></td><td>The facility is one of the following keywords: auth, authpriv, cron, daemon, kern, lpr, mail, news, syslog, user, uucp and local0 through local7</td></tr>
- <tr><td><b>log_level</b></td><td>An integer 0-7, inclusive, for all levels less than the selected. 0, system is unusable, emergency; 1, action must be taken immediately; 2, critical conditions; 3, error conditions; 4, warning conditions; 5, normal but significant condition; 6, informational; 7, debug-level messages.</td></tr>
- <tr><td><b>status_child_max</b></td><td>Maximum number of status child threads.</td></tr>
- <tr><td><b>status_poll_interval</b></td><td>Scan the resource tree every X seconds for resources which need to be checked.</td></tr>
- <tr><td><b>transition_throttling</b></td><td>During transitions, keep the event processor alive for this many seconds.</td></tr>
-</table><br/>
-Children: <a href="#tag_failoverdomains">failoverdomains</a> <a href="#tag_events">events</a> <a href="#tag_resources">resources</a> <a href="#ref_SERVICE">SERVICE</a> <a href="#ref_VM">VM</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_samba"/>samba</h3>
-Dynamic smbd/nmbd resource agent<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_file</b></td><td>Config File</td></tr>
- <tr><td><b>name</b></td><td>Samba Name</td></tr>
- <tr><td><b>nmbd_options</b></td><td>Other command-line options for nmbd</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing samba resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>shutdown_wait</b></td><td>Wait X seconds for correct end of service shutdown</td></tr>
- <tr><td><b>smbd_options</b></td><td>Other command-line options for smbd</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_SAPDatabase"/>SAPDatabase</h3>
-SAP database resource agent<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>AUTOMATIC_RECOVER</b></td><td>Enable or disable automatic startup recovery</td></tr>
- <tr><td><b>DBJ2EE_ONLY</b></td><td>only JAVA stack installed</td></tr>
- <tr><td><b>DBTYPE</b></td><td>database vendor</td></tr>
- <tr><td><b>DB_JARS</b></td><td>file name of the jdbc driver</td></tr>
- <tr><td><b>DIR_BOOTSTRAP</b></td><td>path to j2ee bootstrap directory</td></tr>
- <tr><td><b>DIR_EXECUTABLE</b></td><td>path of sapstartsrv and sapcontrol</td></tr>
- <tr><td><b>DIR_SECSTORE</b></td><td>path to j2ee secure store directory</td></tr>
- <tr><td><b>JAVA_HOME</b></td><td>Path to Java SDK</td></tr>
- <tr><td><b>NETSERVICENAME</b></td><td>listener name</td></tr>
- <tr><td><b>POST_START_USEREXIT</b></td><td>path to a post-start script</td></tr>
- <tr><td><b>POST_STOP_USEREXIT</b></td><td>path to a post-start script</td></tr>
- <tr><td><b>PRE_START_USEREXIT</b></td><td>path to a pre-start script</td></tr>
- <tr><td><b>PRE_STOP_USEREXIT</b></td><td>path to a pre-start script</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing SAPDatabase resource in the resources section.</td></tr>
- <tr><td><b>SID</b></td><td>SAP system ID</td></tr>
- <tr><td><b>STRICT_MONITORING</b></td><td>Activates application level monitoring</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_SAPInstance"/>SAPInstance</h3>
-SAP instance resource agent<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>AUTOMATIC_RECOVER</b></td><td>Enable or disable automatic startup recovery</td></tr>
- <tr><td><b>DIR_EXECUTABLE</b></td><td>path of sapstartsrv and sapcontrol</td></tr>
- <tr><td><b>DIR_PROFILE</b></td><td>path of start profile</td></tr>
- <tr><td><b>InstanceName</b></td><td>instance name: SID_INSTANCE_VIR-HOSTNAME</td></tr>
- <tr><td><b>POST_START_USEREXIT</b></td><td>path to a post-start script</td></tr>
- <tr><td><b>POST_STOP_USEREXIT</b></td><td>path to a post-start script</td></tr>
- <tr><td><b>PRE_START_USEREXIT</b></td><td>path to a pre-start script</td></tr>
- <tr><td><b>PRE_STOP_USEREXIT</b></td><td>path to a pre-start script</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing SAPInstance resource in the resources section.</td></tr>
- <tr><td><b>START_PROFILE</b></td><td>start profile name</td></tr>
- <tr><td><b>START_WAITTIME</b></td><td>Check the successful start after that time (do not wait for J2EE-Addin)</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_script"/>script</h3>
-LSB-compliant init script as a clustered resource.<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>file</b></td><td>Path to script</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing script resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_service"/>service</h3>
-Defines a service (resource group).<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>autostart</b></td><td>Automatic start after quorum formation</td></tr>
- <tr><td><b>depend</b></td><td>Top-level service this depends on, in service:name format.</td></tr>
- <tr><td><b>depend_mode</b></td><td>Service dependency mode (soft or hard).</td></tr>
- <tr><td><b>domain</b></td><td>Failover domain.</td></tr>
- <tr><td><b>exclusive</b></td><td>Exclusive service.</td></tr>
- <tr><td><b>max_restarts</b></td><td>Maximum restarts for this service.</td></tr>
- <tr><td><b>name</b></td><td>Name.</td></tr>
- <tr><td><b>nfslock</b></td><td>Enable NFS lock workarounds.</td></tr>
- <tr><td><b>nfs_client_cache</b></td><td>Enable exportfs list caching (performance).</td></tr>
- <tr><td><b>priority</b></td><td>Service priority.</td></tr>
- <tr><td><b>recovery</b></td><td>Failure recovery policy (restart, relocate, or disable).</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing service resource in the resources section.</td></tr>
- <tr><td><b>restart_expire_time</b></td><td>Restart expiration time; amount of time before a restart is forgotten.</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_tomcat-6"/>tomcat-6</h3>
-Defines a Tomcat server<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>config_file</b></td><td>Config File</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing tomcat-6 resource in the resources section.</td></tr>
- <tr><td><b>service_name</b></td><td>Inherit the service name.</td></tr>
- <tr><td><b>shutdown_wait</b></td><td>Wait X seconds for correct end of service shutdown</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_totem"/>totem</h3>
-OpenAIS msg transport protocol<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>consensus</b></td><td>This is a timeout value that specifies how many milliseconds to wait for consensus to be achieved before starting a new round of membership configuration.</td></tr>
- <tr><td><b>fail_recv_const</b></td><td> </td></tr>
- <tr><td><b>join</b></td><td>This is a timeout value that specifies how many milliseconds to wait for join messages in the membership protocol.</td></tr>
- <tr><td><b>keyfile</b></td><td></td></tr>
- <tr><td><b>rrp_mode</b></td><td>This attribute specifies the redundant ring protocol mode. Its value can be set to active, passive, or none. Active replication offers slightly lower latency from transmit to delivery in faulty network environments but with less performance. Passive replication may nearly double the speed of the totem protocol if the protocol doesn't become cpu bound. The final option is none, in which case only one network interface is used to operate the totem protocol. If only one interface directive is specified, none is automatically chosen. If multiple interface directives are specified, only active or passive may be chosen.</td></tr>
- <tr><td><b>secauth</b></td><td>This attribute specifies that HMAC/SHA1 authentication should be used to authenticate all messages. It further specifies that all data should be encrypted with the sober128 encryption algorithm to protect data from eavesdropping. For more information setting this value, refer the the openais.conf man page.</td></tr>
- <tr><td><b>token</b></td><td>This is a timeout value that specifies how many milliseconds elapse before a token loss is declared after not receiving a token. This is the time spent detecting a failure of a processor in the current configuration. Reforming a new configuration takes about 50 milliseconds in addition to this timeout.</td></tr>
- <tr><td><b>token_retransmits_before_loss_const</b></td><td>This value identifies how many token retransmits should be attempted before forming a new configuration. If this value is set, retransmit and hold will be automatically calculated from retransmits_before_loss and token.</td></tr>
-</table><br/>
-Children: <a href="#tag_interface">interface</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_unfence"/>unfence</h3>
-Contains devices for unfencing the node. fence_node(8)<br/>
-<br/>
-Children: <a href="#ref_DEVICE">DEVICE</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-<h3><a name="tag_vm"/>vm</h3>
-Defines a Virtual Machine<br/>
-<br/>
-<table><tr valign="top"><td>Attribute</td><td>Description</td></tr>
- <tr><td><b>autostart</b></td><td>Automatic start after quorum formation</td></tr>
- <tr><td><b>depend</b></td><td>Top-level service this depends on, in service:name format.</td></tr>
- <tr><td><b>depend_mode</b></td><td>Service dependency mode (soft or hard).</td></tr>
- <tr><td><b>domain</b></td><td>Cluster failover Domain</td></tr>
- <tr><td><b>exclusive</b></td><td>Exclusive resource group</td></tr>
- <tr><td><b>hypervisor</b></td><td>Hypervisor</td></tr>
- <tr><td><b>hypervisor_uri</b></td><td>Hypervisor URI (normally automatic).</td></tr>
- <tr><td><b>max_restarts</b></td><td>Maximum restarts for this service.</td></tr>
- <tr><td><b>migrate</b></td><td>Migration type (live or pause, default = live).</td></tr>
- <tr><td><b>migration_mapping</b></td><td>memberhost:targethost,memberhost:targethost ..</td></tr>
- <tr><td><b>migration_uri</b></td><td>Migration URI (normally automatic).</td></tr>
- <tr><td><b>name</b></td><td>Name</td></tr>
- <tr><td><b>path</b></td><td>Path to virtual machine configuration files.</td></tr>
- <tr><td><b>recovery</b></td><td>Failure recovery policy</td></tr>
- <tr><td><b>ref</b></td><td>Reference to existing vm resource in the resources section.</td></tr>
- <tr><td><b>restart_expire_time</b></td><td>Restart expiration time; amount of time before a restart is forgotten.</td></tr>
- <tr><td><b>snapshot</b></td><td>Path to the snapshot directory where the virtual machine image will be stored.</td></tr>
- <tr><td><b>status_program</b></td><td>Additional status check program</td></tr>
- <tr><td><b>use_virsh</b></td><td>If set to 1, vm.sh will use the virsh command to manage virtual machines instead of xm. This is required when using non-Xen virtual machines (e.g. qemu / KVM).</td></tr>
- <tr><td><b>xmlfile</b></td><td>Full path to libvirt XML file describing the domain.</td></tr>
- <tr><td><b>__enforce_timeouts</b></td><td>Consider a timeout for operations as fatal.</td></tr>
- <tr><td><b>__failure_expire_time</b></td><td>Amount of time before a failure is forgotten.</td></tr>
- <tr><td><b>__independent_subtree</b></td><td>Treat this and all children as an independent subtree.</td></tr>
- <tr><td><b>__max_failures</b></td><td>Maximum number of failures before returning a failure to a status check.</td></tr>
- <tr><td><b>__max_restarts</b></td><td>Maximum number restarts for an independent subtree before giving up.</td></tr>
- <tr><td><b>__restart_expire_time</b></td><td>Amount of time before a failure is forgotten for an independent subtree.</td></tr>
-</table><br/>
-Children: <a href="#ref_CHILDREN">CHILDREN</a> <br/><a href="#" onClick="history.go(-1)" />Back</a> | <a href="#toc_tag_reference">Contents</a>
-</html>
diff --git a/doc/cman_notify_template.sh b/doc/cman_notify_template.sh
deleted file mode 100644
index ef43860..0000000
--- a/doc/cman_notify_template.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/bash
-
-# This is a simple template that can be used as reference
-# for notification scripts. Note: notification scripts need
-# to be executable in order for cman_notify to run them.
-
-# Set the path for the commands you expect to execute!
-# cmannotifyd does not set any for you.
-
-PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
-
-# define a simple wrapper to echo that will log to file only if
-# debugging is enable.
-my_echo() {
- [ -n "$OUT" ] && echo $@ >> $OUT
-}
-
-LOGFILE="/var/log/cluster/file.log"
-
-# verify if you are running in debugging mode
-if [ "$CMAN_NOTIFICATION_DEBUG" = "1" ]; then
- # in debuggin mode, we want to see the whole output somewhere
- OUT="$LOGFILE"
- my_echo "debugging is enabled"
-fi
-
-# parse the notification we received.
-case "$CMAN_NOTIFICATION" in
- CMAN_REASON_CONFIG_UPDATE)
- # we received a configuration change
- my_echo "replace me with something to do"
- ;;
- CMAN_REASON_STATECHANGE)
- # we received a status change. A node might have left or joined
- # the cluster
- my_echo "replace me with something to do"
-
- # STATECHANGE contains information about the quorum status of
- # the node.
- # 1 = the node is part of a quorate cluster
- # 0 = there is no quorum
- if [ "$CMAN_NOTIFICATION_QUORUM" = "1" ]; then
- my_echo "we still have quorum"
- fi
- ;;
- CMAN_REASON_TRY_SHUTDOWN)
- # we received a shutdown request. It means that cman might go
- # offline very soon.
- my_echo "replace me with something to do"
- ;;
- *)
- # we received an unknown notification.
- my_echo "no clue of what to do with this"
- ;;
-esac
-
-exit 0
diff --git a/doc/usage.txt b/doc/usage.txt
deleted file mode 100644
index ad53a95..0000000
--- a/doc/usage.txt
+++ /dev/null
@@ -1,90 +0,0 @@
-cluster3 minimal setup and usage
-
-cluster configuration
----------------------
-
-Create /etc/cluster/cluster.conf and copy it to all nodes.
-
-Below is a minimal cluster.conf file using manual fencing. The node names
-should resolve to the address on the network interface you want to use for
-cluster communication.
-
-<?xml version="1.0"?>
-<cluster name="alpha" config_version="1">
-
-<clusternodes>
-<clusternode name="node-01" nodeid="1"/>
-<clusternode name="node-02" nodeid="2"/>
-<clusternode name="node-03" nodeid="3"/>
-</clusternodes>
-
-</cluster>
-
-
-cluster start
--------------
-
-Use the init script on all nodes:
-
-> service cman start
-
-Or, minimal manual steps:
-
-> modprobe configfs
-> modprobe dlm
-> modprobe gfs2 (if using gfs2)
-> mount -t configfs none /sys/kernel/config
-> cman_tool join
-> fenced
-> dlm_controld
-> gfs_controld (if using gfs2)
-> fence_tool join
-
-
-using clvm
-----------
-
-Use the init script on all nodes:
-
-> service clvmd start
-
-Or, manually:
-
-> clvmd
-> vgscan
-> vgchange -aly
-
-
-using rgmanager
----------------
-
-Use the init script on all nodes:
-
-> service rgmanager start
-
-Or, manually:
-
-> rgmanager
-
-Create services/resources to be managed in cluster.conf.
-
-
-using gfs2
-----------
-
-Create new file systems, using the cluster name from cluster.conf. Pick a
-unique name for each fs and select a number of journals greater than or equal
-to the number of nodes that will mount the fs.
-
-> mkfs.gfs2 -p lock_dlm -t <clustername>:<fsname> -j <#journals> <blockdev>
-
-Use the gfs2 init script to automate mounting gfs2 fs's listed in /etc/fstab:
-
-> service gfs2 start
-
-Or, manually:
-
-> mount -t gfs2 <blockdev> <mountpoint>
-
-(Replace "gfs2" with "gfs" everywhere above to use gfs instead of gfs2.)
-
diff --git a/fence/Makefile b/fence/Makefile
deleted file mode 100644
index a8783bb..0000000
--- a/fence/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-include ../make/defines.mk
-include $(OBJDIR)/make/passthrough.mk
-
-SUBDIRS=libfence libfenced fenced fence_node fence_tool fence_check man
diff --git a/fence/fence_check/Makefile b/fence/fence_check/Makefile
deleted file mode 100644
index 3788f26..0000000
--- a/fence/fence_check/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-include ../../make/defines.mk
-
-TARGET1 = fence_check
-
-SBINDIRT = $(TARGET1)
-
-all: $(TARGET1)
-
-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#@LOGDIR@#${logdir}#g' \
- -e 's#@VERSION@#${RELEASE_VERSION}#g' \
- > $(TARGET1)
-
-clean: generalclean
diff --git a/fence/fence_check/fence_check.in b/fence/fence_check/fence_check.in
deleted file mode 100644
index e194daf..0000000
--- a/fence/fence_check/fence_check.in
+++ /dev/null
@@ -1,241 +0,0 @@
-#!/bin/bash
-
-set +e
-export LC_ALL=C
-export PATH="/bin:/usr/bin:/sbin:/usr/sbin:@SBINDIR@"
-
-logfile=@LOGDIR@/fence_check.log
-verbose=""
-vardir=/var/run
-
-print_usage() {
- echo "Usage:"
- echo ""
- echo "fence_check [options]"
- echo ""
- echo "Options:"
- echo " -h Print this help, then exit"
- echo " -V Print program version information, then exit"
- echo " -d Disable output to logfile ($logfile)"
- echo " -v Produce verbose output"
- echo " -e Produce extra verbose output"
- echo " ATTENTION: IT MIGHT SHOW FENCE PASSWORDS IN LOG FILES!!!"
- echo " -f Override checks and force execution"
- echo " DO NOT USE ON PRODUCTION CLUSTERS!!!"
-}
-
-check_opts() {
- while [ "$1" != "--" ]; do
- case $1 in
- -h)
- print_usage
- exit 0
- ;;
- -V)
- echo "fence_check version @VERSION@"
- exit 0
- ;;
- -v)
- verbose=1
- ;;
- -e)
- fencenodeopts="-vv"
- ;;
- -d)
- logfile=""
- ;;
- -f)
- override="1"
- ;;
- esac
- shift
- done
-}
-
-opts=$(getopt hdefvV $@)
-if [ "$?" != 0 ]; then
- print_usage >&2
- exit 1
-fi
-check_opts $opts
-
-cleanup() {
- vecho "cleanup: $@"
- rm -f $vardir/fence_check.pid
- exit $1
-}
-
-trap "cleanup 1 ABRT" ABRT
-trap "cleanup 1 QUIT" QUIT
-trap "cleanup 1 TERM" TERM
-trap "cleanup 1 INT" INT
-
-lecho() {
- [ -n "$logfile" ] && echo "$@" | tee -a $logfile
- [ -z "$logfile" ] && echo "$@"
- return 0
-}
-
-vecho() {
- [ -z "$verbose" ] && return 0
- lecho "$@"
-}
-
-error_report()
-{
- lecho "Unable to perform fence_check: $@"
-}
-
-cman_running()
-{
- vecho -n "Checking if cman is running: "
- thisnodeid="$(cman_tool status 2>&1 | grep "Node ID:" | awk '{print $NF}')"
- [ -z "$thisnodeid" ] && {
- vecho "not running"
- return 1
- }
- vecho "running"
-}
-
-cman_has_quorum()
-{
- vecho -n "Checking if node is quorate: "
- cman_tool -t 1 -q wait > /dev/null 2>&1 || {
- vecho "not quorate"
- return 1
- }
- vecho "quorate"
-}
-
-fence_domain()
-{
- vecho -n "Checking if node is in fence domain: "
- fencels="$(fence_tool ls 2>&1)" || {
- vecho "not part of fence domain"
- return 1
- }
- vecho "yes"
-}
-
-fence_in_progress()
-{
- vecho -n "Checking if real fencing is in progress: "
- victim="$(echo "$fencels" | grep "victim count" | awk '{print $NF}')"
- [ "$victim" != "0" ] && {
- vecho "real fencing in progress"
- return 1
- }
- vecho "no fencing in progress"
-}
-
-fence_master()
-{
- vecho -n "Checking if node is fence master: "
- master="$(echo "$fencels" | grep "master nodeid" | awk '{print $NF}')"
- [ "$master" != "$thisnodeid" ] && {
- vecho "node is not fence master"
- return 1
- }
- vecho "this node is fence master"
-}
-
-can_check()
-{
- cman_running || {
- error_report "cman is not running"
- return 2
- }
-
- [ "$override" = "1" ] && return 0
-
- cman_has_quorum || {
- error_report "node is not quorate"
- return 3
- }
-
- fence_domain || {
- error_report "node is not part of the fence domain"
- return 3
- }
-
- fence_master || {
- error_report "node is not fence master"
- return 3
- }
-
- fence_in_progress || {
- error_report "real fencing operation in progress"
- return 3
- }
-
- return 0
-}
-
-execute_check()
-{
- can_check || return $?
-
- vecho -n "Get node list: "
- nodelist="$(cman_tool nodes -F id,name |grep -v '^0' | awk '{print $2}')"
- vecho $nodelist
-
- ret=0
-
- for node in $nodelist; do
- vecho "Testing $node fencing"
-
- can_check
- canret=$?
-
- if [ "$canret" != 0 ]; then
- if [ "$ret" != "5" ]; then
- return $canret
- else
- return $ret
- fi
- fi
-
- vecho "Checking how many fencing methods are configured for node $node"
- for i in $(seq 1 8); do
- ccs_tool query \
- /cluster/clusternodes/clusternode[@name=\"$node\"]/fence/method[$i]/@name >/dev/null 2>&1 || break
- done
- nummethods=$((i - 1))
- vecho "Found $nummethods method(s) to test for node $node"
-
- for method in $(seq 1 $nummethods); do
- vecho "Testing $node method $method status"
- fenceres="$(fence_node $fencenodeopts -S $node -m $method 2>&1)"
- if [ "$?" != 0 ]; then
- ret=5
- lecho "Testing $node method $method: FAILED"
- if [ -z "$fencenodeopts" ]; then
- fenceres="$(echo "$fenceres" | tail -n 2 | head -n 1)"
- else
- fenceargs="$(echo "$fenceres" | tail -n 2 | head -n 1)"
- fenceres="$(echo "$fenceres" | tail -n 3 | head -n 1)"
- fi
- lecho "$fenceres"
- [ -n "$fenceargs" ] && lecho "$fenceargs"
- else
- lecho "Testing $node method $method: success"
- fi
- done
- done
- return $ret
-}
-
-(
- lecho "fence_check run at $(date) pid: $BASHPID"
-
- flock --nonblock --exclusive 200 || {
- lecho "Another process ($(cat $vardir/fence_check.pid)) is holding the lock"
- exit 4
- }
-
- echo $BASHPID > $vardir/fence_check.pid
-
- execute_check
- cleanup $?
-
-) 200>>$vardir/fence_check.pid
diff --git a/fence/fence_node/Makefile b/fence/fence_node/Makefile
deleted file mode 100644
index 9b79449..0000000
--- a/fence/fence_node/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-TARGET = fence_node
-
-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= fence_node.o
-
-CFLAGS += -D_FILE_OFFSET_BITS=64
-
-CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${logtincdir}
-CFLAGS += -I${fenceincdir} -I${fencedincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${ccslibdir} -L${cmanlibdir} -lccs -lcman
-LDFLAGS += -L${fencelibdir} -L${fencedlibdir} -lfence -lfenced
-LDFLAGS += -L${logtlibdir} -llogthread
-LDFLAGS += -L${libdir}
-
-${TARGET}: ${OBJS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-depends:
- $(MAKE) -C ../libfence
- $(MAKE) -C ../libfenced
-
-clean: generalclean
-
--include $(OBJS:.o=.d)
diff --git a/fence/fence_node/fence_node.c b/fence/fence_node/fence_node.c
deleted file mode 100644
index f926825..0000000
--- a/fence/fence_node/fence_node.c
+++ /dev/null
@@ -1,306 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <string.h>
-#include <liblogthread.h>
-#include <libcman.h>
-
-#include "libfence.h"
-#include "libfenced.h"
-#include "copyright.cf"
-
-static char *prog_name;
-static char our_name[CMAN_MAX_NODENAME_LEN+1];
-static int verbose;
-static int unfence;
-static int status;
-static int call_fenced = 1;
-static int use_method_num;
-
-#define FL_SIZE 32
-static struct fence_log flog[FL_SIZE];
-static int flog_count;
-static const char *action = "fence";
-
-#define OPTION_STRING "UvhVSe:m:"
-
-#define die(fmt, args...) \
-do \
-{ \
- fprintf(stderr, "%s: ", prog_name); \
- fprintf(stderr, fmt "\n", ##args); \
- exit(EXIT_FAILURE); \
-} \
-while (0)
-
-static void print_usage(void)
-{
- printf("Usage:\n");
- printf("\n");
- printf("%s [options] node_name\n", prog_name);
- printf("\n");
- printf("Options:\n");
- printf("\n");
- printf(" -U Unfence the node, default local node name\n");
- printf(" -S Run status on node name\n");
- printf(" -v Show fence agent results, -vv for agent args\n");
- printf(" -h Print this help, then exit\n");
- printf(" -V Print program version information, then exit\n");
- printf(" -e 0|1 Enable/disable fenced_external notification\n");
- printf(" -m <num> Method number, starting from 1\n");
- printf("\n");
-}
-
-static int setup_cman(void)
-{
- cman_handle_t ch;
- cman_node_t node;
- int active = 0;
- int rv;
-
- ch = cman_init(NULL);
- if (!ch)
- return -1;
-
- retry_active:
- rv = cman_is_active(ch);
- if (!rv) {
- if (active++ < 2) {
- sleep(1);
- goto retry_active;
- }
- cman_finish(ch);
- return -1;
- }
-
- memset(&node, 0, sizeof(node));
- rv = cman_get_node(ch, CMAN_NODEID_US, &node);
- if (rv < 0) {
- cman_finish(ch);
- return -1;
- }
-
- memset(our_name, 0, sizeof(our_name));
- strncpy(our_name, node.cn_name, CMAN_MAX_NODENAME_LEN);
- cman_finish(ch);
- return 0;
-}
-
-static const char *fe_str(int r)
-{
- switch (r) {
- case FE_AGENT_SUCCESS:
- return "success";
- case FE_AGENT_ERROR:
- return "error from agent";
- case FE_AGENT_FORK:
- return "error from fork";
- case FE_NO_CONFIG:
- return "error from ccs";
- case FE_NO_METHOD:
- return "error no method";
- case FE_NO_DEVICE:
- return "error no device";
- case FE_READ_AGENT:
- return "error config agent";
- case FE_READ_ARGS:
- return "error config args";
- case FE_READ_METHOD:
- return "error config method";
- case FE_READ_DEVICE:
- return "error config device";
- case FE_NUM_METHOD:
- return "error method number";
- case FE_AGENT_STATUS_ON:
- return "status on";
- case FE_AGENT_STATUS_OFF:
- return "status off";
- case FE_AGENT_STATUS_ERROR:
- return "status error";
- default:
- return "error unknown";
- }
-}
-
-int main(int argc, char *argv[])
-{
- char *victim = NULL;
- int cont = 1, optchar, error, rv, i, c;
-
- prog_name = argv[0];
-
- while (cont) {
- optchar = getopt(argc, argv, OPTION_STRING);
-
- switch (optchar) {
-
- case 'U':
- unfence = 1;
- action = "unfence";
- break;
-
- case 'S':
- status = 1;
- action = "status";
- break;
-
- case 'e':
- call_fenced = atoi(optarg);
- break;
-
- case 'm':
- use_method_num = atoi(optarg);
- break;
-
- case 'v':
- verbose++;
- break;
-
- case 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case 'V':
- printf("%s %s (built %s %s)\n", prog_name,
- RELEASE_VERSION, __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- break;
-
- case ':':
- case '?':
- fprintf(stderr, "Please use '-h' for usage.\n");
- exit(EXIT_FAILURE);
- break;
-
- case EOF:
- cont = 0;
- break;
-
- default:
- die("unknown option: %c", optchar);
- break;
- };
- }
-
- while (optind < argc) {
- if (victim)
- die("unknown option %s", argv[optind]);
- victim = argv[optind];
- optind++;
- }
-
- if (!victim && !unfence)
- die("no node name specified");
-
- error = setup_cman();
- if (error)
- die("cannot connect to cman");
-
- if (!victim && unfence)
- victim = our_name;
-
- memset(&flog, 0, sizeof(flog));
- flog_count = 0;
-
- if (status)
- error = fence_node_status(victim, flog, FL_SIZE, &flog_count,
- use_method_num);
- else if (unfence)
- error = unfence_node(victim, flog, FL_SIZE, &flog_count);
- else
- error = fence_node(victim, flog, FL_SIZE, &flog_count);
-
- if (status && !verbose && error < 0)
- verbose = 1;
-
- if (!verbose)
- goto skip;
-
- if (flog_count > FL_SIZE) {
- fprintf(stderr, "%s_node log overflow %d", action, flog_count);
- flog_count = FL_SIZE;
- }
-
- for (i = 0; i < flog_count; i++) {
- fprintf(stderr, "%s %s dev %d.%d agent %s result: %s\n",
- action, victim, flog[i].method_num, flog[i].device_num,
- flog[i].agent_name[0] ? flog[i].agent_name : "none",
- fe_str(flog[i].error));
-
- if (verbose < 2)
- continue;
-
- for (c = 0; c < strlen(flog[i].agent_args); c++) {
- if (flog[i].agent_args[c] == '\n')
- flog[i].agent_args[c] = ' ';
- }
- fprintf(stderr, "agent args: %s\n", flog[i].agent_args);
- }
-
- skip:
- logt_init("fence_node", LOG_MODE_OUTPUT_SYSLOG, SYSLOGFACILITY,
- SYSLOGLEVEL, 0, NULL);
-
- if (status) {
- if (error == -2) {
- fprintf(stderr, "status %s undefined\n", victim);
- rv = 2;
- } else if (error < 0) {
- fprintf(stderr, "status %s failed %d\n", victim, error);
- logt_print(LOG_ERR, "status %s failed %d\n", victim, error);
- rv = EXIT_FAILURE;
- } else if (error == 2) {
- fprintf(stderr, "status %s success off\n", victim);
- logt_print(LOG_ERR, "status %s success off\n", victim);
- rv = EXIT_SUCCESS;
- } else if (!error) {
- fprintf(stderr, "status %s success on\n", victim);
- logt_print(LOG_ERR, "status %s success on\n", victim);
- rv = EXIT_SUCCESS;
- } else {
- fprintf(stderr, "status %s failed invalid %d\n", victim, error);
- logt_print(LOG_ERR, "status %s failed invalid %d\n", victim, error);
- rv = EXIT_FAILURE;
- }
- } else if (unfence) {
- if (error == -2) {
- fprintf(stderr, "unfence %s undefined\n", victim);
- rv = 2;
- } else if (error) {
- fprintf(stderr, "unfence %s failed\n", victim);
- logt_print(LOG_ERR, "unfence %s failed\n", victim);
- rv = EXIT_FAILURE;
- } else {
- fprintf(stderr, "unfence %s success\n", victim);
- logt_print(LOG_ERR, "unfence %s success\n", victim);
- rv = EXIT_SUCCESS;
- }
- } else {
- if (error == -2) {
- fprintf(stderr, "fence %s undefined\n", victim);
- logt_print(LOG_ERR, "fence %s undefined\n", victim);
- rv = 2;
- } else if (error) {
- fprintf(stderr, "fence %s failed\n", victim);
- logt_print(LOG_ERR, "fence %s failed\n", victim);
- rv = EXIT_FAILURE;
- } else {
- fprintf(stderr, "fence %s success\n", victim);
- logt_print(LOG_ERR, "fence %s success\n", victim);
- rv = EXIT_SUCCESS;
-
- /* Tell fenced what we've done so that it can avoid
- fencing this node again if the fence_node() rebooted
- it. */
- if (call_fenced)
- fenced_external(victim);
- }
- }
-
- logt_exit();
- exit(rv);
-}
-
diff --git a/fence/fence_tool/Makefile b/fence/fence_tool/Makefile
deleted file mode 100644
index dab3e8f..0000000
--- a/fence/fence_tool/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-TARGET = fence_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=fence_tool.o
-
-CFLAGS += -D_FILE_OFFSET_BITS=64
-CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${fencedincdir}
-CFLAGS += -I$(S)/../include
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${ccslibdir} -L${cmanlibdir} -lccs -lcman
-LDFLAGS += -L${fencedlibdir} -lfenced
-LDFLAGS += -L${libdir}
-
-${TARGET}: ${OBJS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-depends:
- $(MAKE) -C ../libfenced
-
-clean: generalclean
-
--include $(OBJS:.o=.d)
diff --git a/fence/fence_tool/fence_tool.c b/fence/fence_tool/fence_tool.c
deleted file mode 100644
index 91155f2..0000000
--- a/fence/fence_tool/fence_tool.c
+++ /dev/null
@@ -1,737 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <signal.h>
-#include <string.h>
-#include <stdint.h>
-#include <dirent.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <errno.h>
-#include <libgen.h>
-
-#include "ccs.h"
-#include "copyright.cf"
-#include "libcman.h"
-#include "libfenced.h"
-
-#define OP_JOIN 1
-#define OP_LEAVE 2
-#define OP_LIST 3
-#define OP_DUMP 4
-
-#define MAX_NODES 128
-
-int all_nodeids[MAX_NODES];
-int all_nodeids_count;
-cman_handle_t ch;
-cman_node_t cman_nodes[MAX_NODES];
-int cman_nodes_count;
-struct fenced_node nodes[MAX_NODES];
-char *prog_name;
-int operation;
-
-#define DEFAULT_RETRY_CMAN 0 /* fail immediately if we can't connect to cman */
-#define DEFAULT_DELAY_QUORUM 0
-#define DEFAULT_DELAY_MEMBERS 0
-#define DEFAULT_WAIT_JOINLEAVE 0
-
-int opt_all_nodes = 0;
-int opt_retry_cman = DEFAULT_RETRY_CMAN;
-int opt_delay_quorum = DEFAULT_DELAY_QUORUM;
-int opt_delay_members = DEFAULT_DELAY_MEMBERS;
-int opt_wait_joinleave = DEFAULT_WAIT_JOINLEAVE;
-
-
-#define die(fmt, args...) \
-do { \
- fprintf(stderr, "%s: ", prog_name); \
- fprintf(stderr, fmt "\n", ##args); \
- exit(EXIT_FAILURE); \
-} while (0)
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, (char *)buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0)
- return rv;
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-#define LOCKFILE_NAME "/var/run/fenced.pid"
-
-static void check_fenced_running(void)
-{
- struct flock lock;
- int fd, rv;
-
- fd = open(LOCKFILE_NAME, O_RDONLY);
- if (fd < 0)
- die("fenced not running, no lockfile");
-
- lock.l_type = F_RDLCK;
- lock.l_start = 0;
- lock.l_whence= SEEK_SET;
- lock.l_len = 0;
-
- rv = fcntl(fd, F_GETLK, &lock);
- if (rv < 0)
- die("fenced not running, get lockfile");
-
- if (lock.l_type == F_UNLCK)
- die("fenced not running, unlocked lockfile");
-
- close(fd);
-}
-
-static int check_gfs(void)
-{
- FILE *file;
- char line[PATH_MAX];
- char device[PATH_MAX];
- char path[PATH_MAX];
- char type[PATH_MAX];
- int count = 0;
-
- file = fopen("/proc/mounts", "r");
- if (!file)
- return 0;
-
- while (fgets(line, PATH_MAX, file)) {
- if (sscanf(line, "%s %s %s", device, path, type) != 3)
- continue;
- if (!strcmp(type, "gfs") || !strcmp(type, "gfs2")) {
- fprintf(stderr, "found %s file system mounted from %s on %s\n",
- type, device, path);
- count++;
- }
- }
-
- fclose(file);
- return count;
-}
-
-static int check_controlled_dir(const char *path)
-{
- DIR *d;
- struct dirent *de;
- int count = 0;
-
- d = opendir(path);
- if (!d)
- return 0;
-
- while ((de = readdir(d))) {
- if (de->d_name[0] == '.')
- continue;
-
-#if 0
- if (strstr(path, "fs/gfs") && ignore_nolock(path, de->d_name))
- continue;
-#endif
-
- fprintf(stderr, "found dlm lockspace %s/%s\n", path, de->d_name);
- count++;
- }
-
- closedir(d);
- return count;
-}
-
-/* Copying fenced's check_uncontrolled_entries()/check_controlled_dir()
- in part here.
- We could also use check_controlled_dir to detect gfs file systems intead
- of looking at /proc/mounts... /proc/mounts gives us more info (mountpoint)
- to report about the offending fs */
-
-static void check_controlled_systems(void)
-{
- int count = 0;
-
- count += check_gfs();
- count += check_controlled_dir("/sys/kernel/dlm");
-
- if (count)
- die("cannot leave due to active systems");
-}
-
-static int we_are_in_fence_domain(void)
-{
- struct fenced_node nodeinfo;
- int rv;
-
- memset(&nodeinfo, 0, sizeof(nodeinfo));
-
- rv = fenced_node_info(FENCED_NODEID_US, &nodeinfo);
- if (rv < 0)
- return 0;
-
- if (nodeinfo.member)
- return 1;
- return 0;
-}
-
-static void wait_domain(int joining)
-{
- int in, tries = 0;
-
- while (1) {
- if (joining)
- check_fenced_running();
-
- in = we_are_in_fence_domain();
-
- if (joining && in)
- break;
-
- if (!joining && !in)
- break;
-
- tries++;
-
- if (opt_wait_joinleave < 0)
- goto retry_domain;
-
- if (!opt_wait_joinleave || tries >= opt_wait_joinleave) {
- fprintf(stderr, "%s: %s not complete\n",
- prog_name, joining ? "join" : "leave");
- break;
- }
- retry_domain:
- if (!(tries % 10))
- fprintf(stderr, "%s: waiting for fenced to %s the fence group.\n",
- prog_name, joining ? "join" : "leave");
-
- sleep(1);
- }
-
- return;
-}
-
-static void read_ccs_nodeids(int cd)
-{
- char path[PATH_MAX];
- char *nodeid_str;
- int i, error;
-
- memset(all_nodeids, 0, sizeof(all_nodeids));
- all_nodeids_count = 0;
-
- for (i = 1; ; i++) {
- nodeid_str = NULL;
- memset(path, 0, sizeof(path));
- sprintf(path, "/cluster/clusternodes/clusternode[%d]/@nodeid", i);
-
- error = ccs_get(cd, path, &nodeid_str);
- if (error || !nodeid_str)
- break;
-
- all_nodeids[all_nodeids_count++] = atoi(nodeid_str);
- free(nodeid_str);
- }
-}
-
-static int all_nodeids_are_members(void)
-{
- int i, j, rv, found;
-
- memset(&cman_nodes, 0, sizeof(cman_nodes));
- cman_nodes_count = 0;
-
- rv = cman_get_nodes(ch, MAX_NODES, &cman_nodes_count, cman_nodes);
- if (rv < 0)
- return -1;
-
- for (i = 0; i < all_nodeids_count; i++) {
- found = 0;
-
- for (j = 0; j < cman_nodes_count; j++) {
- if (cman_nodes[j].cn_nodeid == all_nodeids[i] &&
- cman_nodes[j].cn_member) {
- found = 1;
- break;
- }
- }
-
- if (!found)
- return 0;
- }
- return 1;
-}
-
-static int connect_cman(void)
-{
- int rv, tries = 0;
-
- while (1) {
- ch = cman_init(NULL);
- if (ch)
- break;
-
- tries++;
-
- if (opt_retry_cman < 0)
- goto retry_init;
-
- if (!opt_retry_cman || tries >= opt_retry_cman)
- return -1;
- retry_init:
- if (!(tries % 10))
- fprintf(stderr, "%s: retrying cman connection\n", prog_name);
- sleep(1);
- }
-
- while (1) {
- rv = cman_is_active(ch);
- if (rv)
- break;
-
- tries++;
-
- if (opt_retry_cman < 0)
- goto retry_active;
-
- if (!opt_retry_cman || tries >= opt_retry_cman) {
- cman_finish(ch);
- return -1;
- }
- retry_active:
- if (!(tries % 10))
- fprintf(stderr, "%s: retrying cman active check\n", prog_name);
- sleep(1);
- }
-
- return 0;
-}
-
-static void delay_quorum(void)
-{
- int rv, tries = 0;
-
- while (1) {
- rv = cman_is_quorate(ch);
- if (rv)
- break;
-
- rv = cman_is_active(ch);
- if (!rv) {
- cman_finish(ch);
- die("lost cman connection");
- }
-
- tries++;
-
- if (opt_delay_quorum < 0)
- goto retry_quorum;
-
- if (!opt_delay_quorum || tries >= opt_delay_quorum) {
- fprintf(stderr, "%s: continuing without quorum\n", prog_name);
- break;
- }
- retry_quorum:
- if (!(tries % 10))
- fprintf(stderr, "%s: delaying for quorum\n", prog_name);
-
- sleep(1);
- }
-
- return;
-}
-
-static void delay_members(void)
-{
- int rv, tries = 0;
- int cd;
-
- cd = ccs_connect();
- if (cd < 0) {
- cman_finish(ch);
- die("lost cman/ccs connection");
- }
-
- read_ccs_nodeids(cd);
-
- while (1) {
- rv = all_nodeids_are_members();
- if (rv < 0) {
- ccs_disconnect(cd);
- cman_finish(ch);
- die("lost cman connection");
- }
- if (rv)
- break;
-
- tries++;
-
- if (opt_delay_members < 0)
- goto retry_members;
-
- if (!opt_delay_members || tries > opt_delay_members) {
- fprintf(stderr, "%s: continuing without all members\n", prog_name);
- break;
- }
- retry_members:
- if (!(tries % 10))
- fprintf(stderr, "%s: delaying for members\n", prog_name);
-
- sleep(1);
- }
-
- ccs_disconnect(cd);
- return;
-}
-
-static void do_join(int argc, char *argv[])
-{
- int rv, tries = 0;
-
- rv = connect_cman();
- if (rv < 0)
- die("can't connect to cman");
-
- /* if delay_quorum() or delay_members() fail on any cman/ccs
- connection or operation, they call cman_finish() and exit
- with failure */
-
- if (opt_delay_quorum)
- delay_quorum();
-
- if (opt_delay_members)
- delay_members();
-
- cman_finish(ch);
-
- /* This loop deals with the case where fenced is slow enough starting
- up that fenced_join fails. Do we also want to add a delay here to
- deal with the case where fenced is so slow starting up that it hasn't
- locked its lockfile yet, causing check_fenced_running to fail? */
-
- while (1) {
- rv = fenced_join();
- if (!rv)
- break;
-
- check_fenced_running();
-
- tries++;
- if (!(tries % 10))
- fprintf(stderr, "%s: retrying join\n", prog_name);
- sleep(1);
- }
-
- if (opt_wait_joinleave)
- wait_domain(1);
-
- exit(EXIT_SUCCESS);
-}
-
-static void do_leave(void)
-{
- int rv;
-
- check_controlled_systems();
-
- rv = fenced_leave();
- if (rv < 0)
- die("leave: can't communicate with fenced");
-
- if (opt_wait_joinleave)
- wait_domain(0);
-
- exit(EXIT_SUCCESS);
-}
-
-static void do_dump(void)
-{
- char buf[FENCED_DUMP_SIZE];
- int rv;
-
- rv = fenced_dump_debug(buf);
- if (rv < 0)
- die("dump: can't communicate with fenced");
-
- do_write(STDOUT_FILENO, buf, strlen(buf));
-
- exit(EXIT_SUCCESS);
-}
-
-static int node_compare(const void *va, const void *vb)
-{
- const struct fenced_node *a = va;
- const struct fenced_node *b = vb;
-
- return a->nodeid - b->nodeid;
-}
-
-/* copied from fence/fenced/fd.h, should probably be in libfenced.h */
-#define CGST_WAIT_CONDITIONS 1
-#define CGST_WAIT_MESSAGES 2
-#define CGST_WAIT_FENCING 3
-
-static const char *wait_str(int state)
-{
- switch (state) {
- case 0:
- return "none";
- case CGST_WAIT_CONDITIONS:
- return "quorum";
- case CGST_WAIT_MESSAGES:
- return "messages";
- case CGST_WAIT_FENCING:
- return "fencing";
- }
- return "unknown";
-}
-
-/* copied from fence/fenced/fd.h, should probably be in libfenced.h */
-#define VIC_DONE_AGENT 1
-#define VIC_DONE_MEMBER 2
-#define VIC_DONE_OVERRIDE 3
-#define VIC_DONE_EXTERNAL 4
-
-static const char *how_str(int how)
-{
- switch (how) {
- case 0:
- return "none";
- case VIC_DONE_AGENT:
- return "agent";
- case VIC_DONE_MEMBER:
- return "member";
- case VIC_DONE_OVERRIDE:
- return "override";
- case VIC_DONE_EXTERNAL:
- return "external";
- }
- return "unknown";
-}
-
-static int do_list(void)
-{
- struct fenced_domain d;
- struct fenced_node *np;
- int node_count;
- int rv, i;
-
- rv = fenced_domain_info(&d);
- if (rv < 0)
- exit(EXIT_FAILURE); /* fenced probably not running */
-
- printf("fence domain\n");
- printf("member count %d\n", d.member_count);
- printf("victim count %d\n", d.victim_count);
- printf("victim now %d\n", d.current_victim);
- printf("master nodeid %d\n", d.master_nodeid);
- printf("wait state %s\n", wait_str(d.state));
- printf("members ");
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
-
- rv = fenced_domain_nodes(FENCED_NODES_MEMBERS, MAX_NODES,
- &node_count, nodes);
- if (rv < 0) {
- printf("error\n");
- goto fail;
- }
-
- qsort(&nodes, node_count, sizeof(struct fenced_node), node_compare);
-
- np = nodes;
- for (i = 0; i < node_count; i++) {
- printf("%d ", np->nodeid);
- np++;
- }
- printf("\n");
-
- if (!opt_all_nodes) {
- printf("\n");
- exit(EXIT_SUCCESS);
- }
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
-
- rv = fenced_domain_nodes(FENCED_NODES_ALL, MAX_NODES,
- &node_count, nodes);
- if (rv < 0)
- goto fail;
-
- qsort(&nodes, node_count, sizeof(struct fenced_node), node_compare);
-
- printf("all nodes\n");
-
- np = nodes;
- for (i = 0; i < node_count; i++) {
- printf("nodeid %d member %d victim %d last fence master %d how %s\n",
- np->nodeid,
- np->member,
- np->victim,
- np->last_fenced_master,
- how_str(np->last_fenced_how));
- np++;
- }
- printf("\n");
- exit(EXIT_SUCCESS);
- fail:
- fprintf(stderr, "fenced query error %d\n", rv);
- printf("\n");
- exit(EXIT_FAILURE);
-}
-
-static void print_usage(void)
-{
- printf("Usage:\n");
- printf("\n");
- printf("%s <ls|join|leave|dump> [options]\n", prog_name);
- printf("\n");
- printf("Actions:\n");
- printf(" ls List nodes status\n");
- printf(" join Join the default fence domain\n");
- printf(" leave Leave default fence domain\n");
- printf(" dump Dump debug buffer from fenced\n");
- printf("\n");
- printf("Options:\n");
- printf(" -n Show all node information in ls\n");
-
- printf(" -t <seconds> Retry cman connection for <seconds>.\n");
- printf(" Default %d. 0 no retry, -1 indefinite retry.\n",
- DEFAULT_RETRY_CMAN);
-
- printf(" -q <seconds> Delay join up to <seconds> for the cluster to have quorum.\n");
- printf(" Default %d. 0 no delay, -1 indefinite delay.\n",
- DEFAULT_DELAY_QUORUM);
-
- printf(" -m <seconds> Delay join up to <seconds> for all nodes in cluster.conf\n");
- printf(" to be cluster members.\n");
- printf(" Default %d. 0 no delay, -1 indefinite delay\n",
- DEFAULT_DELAY_MEMBERS);
-
- printf(" -w <seconds> Wait up to <seconds> for join or leave result.\n");
- printf(" Default %d. 0 no wait, -1 indefinite wait.\n",
- DEFAULT_WAIT_JOINLEAVE);
-
- printf(" -V Print program version information, then exit\n");
- printf(" -h Print this help, then exit\n");
- printf("\n");
-}
-
-#define OPTION_STRING "nt:q:m:w:Vh"
-
-static void decode_arguments(int argc, char *argv[])
-{
- int cont = 1;
- int optchar;
-
- while (cont) {
- optchar = getopt(argc, argv, OPTION_STRING);
-
- switch (optchar) {
-
- case 'n':
- opt_all_nodes = 1;
- break;
-
- case 't':
- opt_retry_cman = atoi(optarg);
- break;
-
- case 'q':
- opt_delay_quorum = atoi(optarg);
- break;
-
- case 'm':
- opt_delay_members = atoi(optarg);
- break;
-
- case 'w':
- opt_wait_joinleave = atoi(optarg);
- break;
-
- case 'V':
- printf("fence_tool %s (built %s %s)\n",
- RELEASE_VERSION, __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- break;
-
- case 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case ':':
- case '?':
- fprintf(stderr, "Please use '-h' for usage.\n");
- exit(EXIT_FAILURE);
- break;
-
- case EOF:
- cont = 0;
- break;
-
- default:
- die("unknown option: %c\n", optchar);
- break;
- }
- }
-
- while (optind < argc) {
- if (strcmp(argv[optind], "join") == 0) {
- operation = OP_JOIN;
- } else if (strcmp(argv[optind], "leave") == 0) {
- operation = OP_LEAVE;
- } else if (strcmp(argv[optind], "dump") == 0) {
- operation = OP_DUMP;
- } else if (strcmp(argv[optind], "ls") == 0) {
- operation = OP_LIST;
- } else
- die("unknown option %s\n", argv[optind]);
- optind++;
- }
-
- if (!operation)
- die("no operation specified\n");
-}
-
-int main(int argc, char *argv[])
-{
- prog_name = basename(argv[0]);
-
- decode_arguments(argc, argv);
-
- switch (operation) {
- case OP_JOIN:
- do_join(argc, argv);
- break;
- case OP_LEAVE:
- do_leave();
- break;
- case OP_DUMP:
- do_dump();
- break;
- case OP_LIST:
- do_list();
- break;
- }
-
- return EXIT_FAILURE;
-}
-
diff --git a/fence/fenced/Makefile b/fence/fenced/Makefile
deleted file mode 100644
index 902c299..0000000
--- a/fence/fenced/Makefile
+++ /dev/null
@@ -1,49 +0,0 @@
-TARGET = fenced
-
-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= config.o \
- cpg.o \
- group.o \
- main.o \
- member_cman.o \
- recover.o \
- logging.o \
- dbus.o
-
-CFLAGS += -D_FILE_OFFSET_BITS=64
-CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${logtincdir} -I${corosyncincdir}
-CFLAGS += -I${fenceincdir} -I${fencedincdir}
-CFLAGS += -I$(S) -I$(S)/../include -I$(SRCDIR)/group/lib
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${ccslibdir} -L${cmanlibdir} -lccs -lcman
-LDFLAGS += -L${logtlibdir} -L${fencelibdir} -llogthread -lfence
-LDFLAGS += -L${corosynclibdir} -lcpg -lpthread
-LDFLAGS += -L../../group/lib -l group
-LDFLAGS += -L${libdir}
-
-ifndef disable_dbus
-CFLAGS += $(shell pkg-config --cflags dbus-1) -DDBUS
-LDFLAGS += $(shell pkg-config --libs dbus-1)
-endif
-
-LDDEPS += ../../group/lib/libgroup.a
-
-${TARGET}: ${OBJS} ${LDDEPS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-depends:
- $(MAKE) -C ../libfence
-
-clean: generalclean
-
--include $(OBJS:.o=.d)
diff --git a/fence/fenced/config.c b/fence/fenced/config.c
deleted file mode 100644
index 1b9a3e0..0000000
--- a/fence/fenced/config.c
+++ /dev/null
@@ -1,226 +0,0 @@
-#include "fd.h"
-#include "config.h"
-#include "ccs.h"
-
-int ccs_handle;
-
-/* was a config value set on command line?, 0 or 1. */
-
-int optd_groupd_compat;
-int optd_debug_logfile;
-int optd_clean_start;
-int optd_disable_dbus;
-int optd_skip_undefined;
-int optd_post_join_delay;
-int optd_post_fail_delay;
-int optd_fence_check_delay;
-int optd_override_time;
-int optd_override_path;
-
-/* actual config value from command line, cluster.conf, or default. */
-
-int cfgd_groupd_compat = DEFAULT_GROUPD_COMPAT;
-int cfgd_debug_logfile = DEFAULT_DEBUG_LOGFILE;
-int cfgd_clean_start = DEFAULT_CLEAN_START;
-int cfgd_disable_dbus = DEFAULT_DISABLE_DBUS;
-int cfgd_skip_undefined = DEFAULT_SKIP_UNDEFINED;
-int cfgd_post_join_delay = DEFAULT_POST_JOIN_DELAY;
-int cfgd_post_fail_delay = DEFAULT_POST_FAIL_DELAY;
-int cfgd_fence_check_delay = DEFAULT_FENCE_CHECK_DELAY;
-int cfgd_override_time = DEFAULT_OVERRIDE_TIME;
-const char *cfgd_override_path = DEFAULT_OVERRIDE_PATH;
-
-void read_ccs_name(const char *path, char *name)
-{
- char *str;
- int error;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return;
-
- strcpy(name, str);
-
- free(str);
-}
-
-void read_ccs_yesno(const char *path, int *yes, int *no)
-{
- char *str;
- int error;
-
- *yes = 0;
- *no = 0;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return;
-
- if (!strcmp(str, "yes"))
- *yes = 1;
-
- else if (!strcmp(str, "no"))
- *no = 1;
-
- free(str);
-}
-
-void read_ccs_int(const char *path, int *config_val)
-{
- char *str;
- int val;
- int error;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return;
-
- val = atoi(str);
-
- if (val < 0) {
- log_error("ignore invalid value %d for %s", val, path);
- return;
- }
-
- *config_val = val;
- log_debug("%s is %u", path, val);
- free(str);
-}
-
-#define GROUPD_COMPAT_PATH "/cluster/group/@groupd_compat"
-#define CLEAN_START_PATH "/cluster/fence_daemon/@clean_start"
-#define POST_JOIN_DELAY_PATH "/cluster/fence_daemon/@post_join_delay"
-#define POST_FAIL_DELAY_PATH "/cluster/fence_daemon/@post_fail_delay"
-#define FENCE_CHECK_DELAY_PATH "/cluster/fence_daemon/@fence_check_delay"
-#define OVERRIDE_PATH_PATH "/cluster/fence_daemon/@override_path"
-#define OVERRIDE_TIME_PATH "/cluster/fence_daemon/@override_time"
-#define METHOD_NAME_PATH "/cluster/clusternodes/clusternode[@name=\"%s\"]/fence/method[%d]/@name"
-#define TWO_NODE_PATH "/cluster/cman/@two_node"
-
-static int count_methods(char *victim)
-{
- char path[PATH_MAX], *name;
- int error, i;
-
- for (i = 0; i < 2; i++) {
- memset(path, 0, sizeof(path));
- sprintf(path, METHOD_NAME_PATH, victim, i+1);
-
- error = ccs_get(ccs_handle, path, &name);
- if (error)
- break;
- free(name);
- }
- return i;
-}
-
-/* These are the options that can be changed while running. */
-
-void reread_ccs(void)
-{
- if (!optd_post_join_delay)
- read_ccs_int(POST_JOIN_DELAY_PATH, &cfgd_post_join_delay);
- if (!optd_post_fail_delay)
- read_ccs_int(POST_FAIL_DELAY_PATH, &cfgd_post_fail_delay);
- if (!optd_fence_check_delay)
- read_ccs_int(FENCE_CHECK_DELAY_PATH, &cfgd_fence_check_delay);
- if (!optd_override_time)
- read_ccs_int(OVERRIDE_TIME_PATH, &cfgd_override_time);
-}
-
-/* called when the domain is joined, not when the daemon starts */
-
-int read_ccs(struct fd *fd)
-{
- char path[PATH_MAX];
- char *str, *name;
- int error, i = 0, count = 0;
- int num_methods;
-
- if (!optd_clean_start)
- read_ccs_int(CLEAN_START_PATH, &cfgd_clean_start);
-
- read_ccs_int(TWO_NODE_PATH, &two_node_mode);
-
- reread_ccs();
-
- if (!optd_override_path) {
- str = NULL;
- memset(path, 0, sizeof(path));
- sprintf(path, OVERRIDE_PATH_PATH);
-
- error = ccs_get(ccs_handle, path, &str);
- if (!error && str)
- cfgd_override_path = strdup(str);
- if (str)
- free(str);
- }
-
- if (cfgd_clean_start) {
- log_debug("clean start, skipping initial nodes");
- goto out;
- }
-
- for (i = 1; ; i++) {
- str = NULL;
- memset(path, 0, sizeof(path));
- sprintf(path, "/cluster/clusternodes/clusternode[%d]/@nodeid", i);
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- break;
-
- name = NULL;
- memset(path, 0, sizeof(path));
- sprintf(path, "/cluster/clusternodes/clusternode[%d]/@name", i);
-
- error = ccs_get(ccs_handle, path, &name);
- if (error || !name) {
- log_error("node name query failed for num %d nodeid %s",
- i, str);
- break;
- }
-
- num_methods = count_methods(name);
-
- /* the libcpg code only uses the fd->complete list for
- determining initial victims; the libgroup code uses
- fd->complete more extensively */
-
- if (cfgd_skip_undefined && !num_methods)
- log_debug("skip %s with zero methods", name);
- else
- add_complete_node(fd, atoi(str));
-
- free(str);
- free(name);
- count++;
- }
-
- log_debug("added %d nodes from ccs", count);
- out:
- return 0;
-}
-
-int setup_ccs(void)
-{
- int cd;
-
- cd = ccs_connect();
- if (cd < 0) {
- log_error("ccs_connect error %d %d", cd, errno);
- return -1;
- }
- ccs_handle = cd;
-
- if (!optd_groupd_compat)
- read_ccs_int(GROUPD_COMPAT_PATH, &cfgd_groupd_compat);
-
- return 0;
-}
-
-void close_ccs(void)
-{
- ccs_disconnect(ccs_handle);
-}
-
diff --git a/fence/fenced/config.h b/fence/fenced/config.h
deleted file mode 100644
index 5f42dea..0000000
--- a/fence/fenced/config.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef __CONFIG_DOT_H__
-#define __CONFIG_DOT_H__
-
-#define DEFAULT_GROUPD_COMPAT 0
-#define DEFAULT_DEBUG_LOGFILE 0
-#define DEFAULT_CLEAN_START 0
-#define DEFAULT_DISABLE_DBUS 0
-#define DEFAULT_SKIP_UNDEFINED 0
-#define DEFAULT_POST_JOIN_DELAY 6
-#define DEFAULT_POST_FAIL_DELAY 0
-#define DEFAULT_FENCE_CHECK_DELAY 5
-#define DEFAULT_OVERRIDE_TIME 3
-#define DEFAULT_OVERRIDE_PATH "/var/run/cluster/fenced_override"
-#define DEFAULT_FENCE_CHECK_PID_PATH "/var/run/fence_check.pid"
-
-extern int optd_groupd_compat;
-extern int optd_debug_logfile;
-extern int optd_clean_start;
-extern int optd_disable_dbus;
-extern int optd_skip_undefined;
-extern int optd_post_join_delay;
-extern int optd_post_fail_delay;
-extern int optd_fence_check_delay;
-extern int optd_override_time;
-extern int optd_override_path;
-
-extern int cfgd_groupd_compat;
-extern int cfgd_debug_logfile;
-extern int cfgd_clean_start;
-extern int cfgd_disable_dbus;
-extern int cfgd_skip_undefined;
-extern int cfgd_post_join_delay;
-extern int cfgd_post_fail_delay;
-extern int cfgd_fence_check_delay;
-extern int cfgd_override_time;
-extern const char *cfgd_override_path;
-
-#endif
-
diff --git a/fence/fenced/cpg.c b/fence/fenced/cpg.c
deleted file mode 100644
index a5a4208..0000000
--- a/fence/fenced/cpg.c
+++ /dev/null
@@ -1,2510 +0,0 @@
-#include "fd.h"
-#include "config.h"
-
-#define PV_STATEFUL 0x0001
-
-struct protocol_version {
- uint16_t major;
- uint16_t minor;
- uint16_t patch;
- uint16_t flags;
-};
-
-struct protocol {
- union {
- struct protocol_version dm_ver;
- uint16_t daemon_max[4];
- };
- union {
- struct protocol_version dr_ver;
- uint16_t daemon_run[4];
- };
-};
-
-struct node_daemon {
- struct list_head list;
- int nodeid;
- int is_member;
- int killed;
- uint64_t join_time;
- uint64_t left_time;
- struct protocol proto;
-};
-
-struct member {
- struct list_head list;
- int nodeid;
- int start; /* 1 if we received a start message for this change */
- int added; /* 1 if added by this change */
- int failed; /* 1 if failed in this change */
- int disallowed;
- uint32_t start_flags;
-};
-
-/* fd_info and id_info: for syncing state in start message */
-
-struct fd_info {
- uint32_t fd_info_size;
- uint32_t id_info_size;
- uint32_t id_info_count;
-
- uint32_t started_count;
-
- int member_count;
- int joined_count;
- int remove_count;
- int failed_count;
-};
-
-#define IDI_NODEID_IS_MEMBER 0x00000001
-
-struct id_info {
- int nodeid;
- uint32_t flags;
-
- /* the following syncs info to make queries useful from all nodes */
-
- int fence_external_node;
- int fence_master;
- int fence_how;
- int pad;
- uint64_t fence_time;
- uint64_t fence_external_time;
-};
-
-static cpg_handle_t cpg_handle_daemon;
-static cpg_handle_t cpg_handle_domain;
-static struct cpg_name group_name_daemon;
-static struct cpg_name group_name_domain;
-static int cpg_fd_daemon;
-static int cpg_fd_domain;
-static struct protocol our_protocol;
-static struct list_head daemon_nodes;
-static struct cpg_address daemon_member[MAX_NODES];
-static int daemon_member_count;
-
-static void log_config(const struct cpg_name *group_name,
- const struct cpg_address *member_list,
- size_t member_list_entries,
- const struct cpg_address *left_list,
- size_t left_list_entries,
- const struct cpg_address *joined_list,
- size_t joined_list_entries)
-{
- char m_buf[128];
- char j_buf[32];
- char l_buf[32];
- size_t i, len, pos;
- int ret;
-
- memset(m_buf, 0, sizeof(m_buf));
- memset(j_buf, 0, sizeof(j_buf));
- memset(l_buf, 0, sizeof(l_buf));
-
- len = sizeof(m_buf);
- pos = 0;
- for (i = 0; i < member_list_entries; i++) {
- ret = snprintf(m_buf + pos, len - pos, " %d",
- member_list[i].nodeid);
- if (ret >= len - pos)
- break;
- pos += ret;
- }
-
- len = sizeof(j_buf);
- pos = 0;
- for (i = 0; i < joined_list_entries; i++) {
- ret = snprintf(j_buf + pos, len - pos, " %d",
- joined_list[i].nodeid);
- if (ret >= len - pos)
- break;
- pos += ret;
- }
-
- len = sizeof(l_buf);
- pos = 0;
- for (i = 0; i < left_list_entries; i++) {
- ret = snprintf(l_buf + pos, len - pos, " %d",
- left_list[i].nodeid);
- if (ret >= len - pos)
- break;
- pos += ret;
- }
-
- log_debug("%s conf %zu %zu %zu memb%s join%s left%s", group_name->value,
- member_list_entries, joined_list_entries, left_list_entries,
- m_buf, j_buf, l_buf);
-}
-
-static void log_ringid(cpg_handle_t handle,
- struct cpg_ring_id *ringid,
- const uint32_t *member_list,
- size_t member_list_entries)
-{
- char m_buf[128];
- size_t i, len, pos;
- int ret;
- const char *name = "unknown";
-
- if (handle == cpg_handle_domain)
- name = group_name_domain.value;
- else if (handle == cpg_handle_daemon)
- name = group_name_daemon.value;
-
- memset(m_buf, 0, sizeof(m_buf));
-
- len = sizeof(m_buf);
- pos = 0;
- for (i = 0; i < member_list_entries; i++) {
- ret = snprintf(m_buf + pos, len - pos, " %u",
- member_list[i]);
- if (ret >= len - pos)
- break;
- pos += ret;
- }
-
- log_debug("%s ring %u:%llu %zu memb%s",
- name, ringid->nodeid, (unsigned long long)ringid->seq,
- member_list_entries, m_buf);
-}
-
-static void fd_info_in(struct fd_info *fi)
-{
- fi->fd_info_size = le32_to_cpu(fi->fd_info_size);
- fi->id_info_size = le32_to_cpu(fi->id_info_size);
- fi->id_info_count = le32_to_cpu(fi->id_info_count);
- fi->started_count = le32_to_cpu(fi->started_count);
- fi->member_count = le32_to_cpu(fi->member_count);
- fi->joined_count = le32_to_cpu(fi->joined_count);
- fi->remove_count = le32_to_cpu(fi->remove_count);
- fi->failed_count = le32_to_cpu(fi->failed_count);
-}
-
-static void id_info_in(struct id_info *id)
-{
- id->nodeid = le32_to_cpu(id->nodeid);
- id->flags = le32_to_cpu(id->flags);
- id->fence_external_node = le32_to_cpu(id->fence_external_node);
- id->fence_master = le32_to_cpu(id->fence_master);
- id->fence_how = le32_to_cpu(id->fence_how);
- id->fence_time = le64_to_cpu(id->fence_time);
- id->fence_external_time = le64_to_cpu(id->fence_external_time);
-}
-
-static void ids_in(struct fd_info *fi, struct id_info *ids)
-{
- struct id_info *id;
- int i;
-
- id = ids;
- for (i = 0; i < fi->id_info_count; i++) {
- id_info_in(id);
- id = (struct id_info *)((char *)id + fi->id_info_size);
- }
-}
-
-static const char *msg_name(int type)
-{
- switch (type) {
- case FD_MSG_PROTOCOL:
- return "protocol";
- case FD_MSG_START:
- return "start";
- case FD_MSG_VICTIM_DONE:
- return "victim_done";
- case FD_MSG_COMPLETE:
- return "complete";
- case FD_MSG_EXTERNAL:
- return "external";
- default:
- return "unknown";
- }
-}
-
-static int _send_message(cpg_handle_t h, void *buf, int len, int type)
-{
- struct iovec iov;
- cpg_error_t error;
- int retries = 0;
-
- iov.iov_base = buf;
- iov.iov_len = len;
-
- retry:
- error = cpg_mcast_joined(h, CPG_TYPE_AGREED, &iov, 1);
- if (error == CPG_ERR_TRY_AGAIN) {
- retries++;
- usleep(1000);
- if (!(retries % 100))
- log_error("cpg_mcast_joined retry %d %s",
- retries, msg_name(type));
- goto retry;
- }
- if (error != CPG_OK) {
- log_error("cpg_mcast_joined error %d handle %llx %s",
- error, (unsigned long long)h, msg_name(type));
- return -1;
- }
-
- if (retries)
- log_debug("cpg_mcast_joined retried %d %s",
- retries, msg_name(type));
-
- return 0;
-}
-
-/* header fields caller needs to set: type, to_nodeid, flags, msgdata */
-
-static void fd_send_message(struct fd *fd, char *buf, int len)
-{
- struct fd_header *hd = (struct fd_header *) buf;
- int type = hd->type;
-
- hd->version[0] = cpu_to_le16(our_protocol.daemon_run[0]);
- hd->version[1] = cpu_to_le16(our_protocol.daemon_run[1]);
- hd->version[2] = cpu_to_le16(our_protocol.daemon_run[2]);
- hd->type = cpu_to_le16(hd->type);
- hd->nodeid = cpu_to_le32(our_nodeid);
- hd->to_nodeid = cpu_to_le32(hd->to_nodeid);
- hd->flags = cpu_to_le32(hd->flags);
- hd->msgdata = cpu_to_le32(hd->msgdata);
-
- _send_message(fd->cpg_handle, buf, len, type);
-}
-
-static struct member *find_memb(struct change *cg, int nodeid)
-{
- struct member *memb;
-
- list_for_each_entry(memb, &cg->members, list) {
- if (memb->nodeid == nodeid)
- return memb;
- }
- return NULL;
-}
-
-static struct fd *find_fd_handle(cpg_handle_t h)
-{
- struct fd *fd;
-
- list_for_each_entry(fd, &domains, list) {
- if (fd->cpg_handle == h)
- return fd;
- }
- return NULL;
-}
-
-static struct fd *find_fd_ci(int ci)
-{
- struct fd *fd;
-
- list_for_each_entry(fd, &domains, list) {
- if (fd->cpg_client == ci)
- return fd;
- }
- return NULL;
-}
-
-void free_cg(struct change *cg)
-{
- struct member *memb, *safe;
-
- list_for_each_entry_safe(memb, safe, &cg->members, list) {
- list_del(&memb->list);
- free(memb);
- }
- list_for_each_entry_safe(memb, safe, &cg->removed, list) {
- list_del(&memb->list);
- free(memb);
- }
- free(cg);
-}
-
-static struct node *get_node_victim(struct fd *fd, int nodeid)
-{
- struct node *node;
-
- list_for_each_entry(node, &fd->victims, list) {
- if (node->nodeid == nodeid)
- return node;
- }
- return NULL;
-}
-
-static struct node_history *get_node_history(struct fd *fd, int nodeid)
-{
- struct node_history *node;
-
- list_for_each_entry(node, &fd->node_history, list) {
- if (node->nodeid == nodeid)
- return node;
- }
- return NULL;
-}
-
-void node_history_init(struct fd *fd, int nodeid)
-{
- struct node_history *node;
-
- node = get_node_history(fd, nodeid);
- if (node)
- return;
-
- node = malloc(sizeof(struct node_history));
- if (!node)
- return;
- memset(node, 0, sizeof(struct node_history));
-
- node->nodeid = nodeid;
- list_add_tail(&node->list, &fd->node_history);
-}
-
-void node_history_cluster_add(int nodeid)
-{
- struct fd *fd;
- struct node_history *node;
-
- list_for_each_entry(fd, &domains, list) {
- node_history_init(fd, nodeid);
-
- node = get_node_history(fd, nodeid);
- if (!node) {
- log_error("node_history_cluster_add no nodeid %d",
- nodeid);
- return;
- }
-
- node->cluster_add_time = time(NULL);
- }
-}
-
-void node_history_cluster_remove(int nodeid)
-{
- struct fd *fd;
- struct node_history *node;
-
- list_for_each_entry(fd, &domains, list) {
- node = get_node_history(fd, nodeid);
- if (!node) {
- log_error("node_history_cluster_remove no nodeid %d",
- nodeid);
- return;
- }
-
- node->cluster_remove_time = time(NULL);
- }
-}
-
-static void node_history_start(struct fd *fd, int nodeid)
-{
- struct node_history *node;
-
- node = get_node_history(fd, nodeid);
- if (!node) {
- log_error("node_history_start no nodeid %d", nodeid);
- return;
- }
-
- node->add_time = time(NULL);
-}
-
-static void node_history_left(struct fd *fd, int nodeid, uint32_t seq)
-{
- struct node_history *node;
-
- node = get_node_history(fd, nodeid);
- if (!node) {
- log_error("node_history_left no nodeid %d", nodeid);
- return;
- }
-
- node->left_time = time(NULL);
- node->left_seq = seq;
-}
-
-static void node_history_fail(struct fd *fd, int nodeid, uint32_t seq)
-{
- struct node_history *node;
-
- node = get_node_history(fd, nodeid);
- if (!node) {
- log_error("node_history_fail no nodeid %d", nodeid);
- return;
- }
-
- node->fail_time = time(NULL);
- node->fail_seq = seq;
-
- node->check_quorum = 1;
-}
-
-/* The master node updates this info when it fences the victim, the other
- domain members update it when they receive the status message from the
- master. */
-
-void node_history_fence(struct fd *fd, int victim, int master, int how,
- uint64_t mastertime)
-{
- struct node_history *node;
-
- node = get_node_history(fd, victim);
- if (!node) {
- log_error("node_history_fence no nodeid %d", victim);
- return;
- }
-
- node->fence_master = master;
- node->fence_time = mastertime;
- node->fence_how = how;
-}
-
-/* When the fence_node command is run on a machine, it will first call
- libfence:fence_node(victim) to do the fencing. Afterward, it should call
- libfenced:fence_external(victim) to tell fenced what it's done, so fenced
- can avoid fencing the node a second time. This will result in a message
- being sent to all domain members which will update their node_history entry
- for the victim. The recover.c:fence_victims() code can check whether
- a victim has been externally fenced since the last add_time, and if so
- skip the fencing. This won't always work perfectly; a node might in some
- circumstances be fenced a second time by fenced. */
-
-static void node_history_fence_external(struct fd *fd, int nodeid, int from)
-{
- struct node_history *node;
-
- node = get_node_history(fd, nodeid);
- if (!node) {
- log_error("node_history_fence_external no nodeid %d", nodeid);
- return;
- }
-
- node->fence_external_time = time(NULL);
- node->fence_external_node = from;
-}
-
-static void save_history(struct fd *fd, struct fd_info *fi, struct id_info *ids)
-{
- struct node_history *node;
- struct id_info *id;
- int i;
-
- id = ids;
-
- for (i = 0; i < fi->id_info_count; i++) {
- /* create history entries for nodes that were domain members
- prior to our joining the domain */
- node_history_init(fd, id->nodeid);
-
- node = get_node_history(fd, id->nodeid);
- if (!node) {
- log_error("save_history no nodeid %d", id->nodeid);
- goto next;
- }
-
- if (!node->fence_time && id->fence_time) {
- node->fence_master = id->fence_master;
- node->fence_time = id->fence_time;
- node->fence_how = id->fence_how;
- log_debug("save_history %d master %d time %llu how %d",
- node->nodeid, node->fence_master,
- (unsigned long long)node->fence_time,
- node->fence_how);
- }
-
- if (!node->fence_external_time && id->fence_external_time) {
- node->fence_external_time = id->fence_external_time;
- node->fence_external_node = id->fence_external_node;
- log_debug("save_history %d ext node %d ext time %llu",
- node->nodeid, node->fence_external_node,
- (unsigned long long)node->fence_external_time);
- }
- next:
- id = (struct id_info *)((char *)id + fi->id_info_size);
- }
-}
-
-/* call this from libfenced:fenced_external() */
-
-void send_external(struct fd *fd, int victim)
-{
- struct fd_header *hd;
- char *buf;
- int len;
-
- len = sizeof(struct fd_header);
-
- buf = malloc(len);
- if (!buf) {
- log_error("send_external no mem len %d", len);
- return;
- }
- memset(buf, 0, len);
-
- hd = (struct fd_header *)buf;
- hd->type = FD_MSG_EXTERNAL;
- hd->msgdata = victim;
-
- log_debug("send_external victim nodeid %u", victim);
-
- fd_send_message(fd, buf, len);
-
- free(buf);
-}
-
-/* now, if the victim dies and the fence domain sees it fail,
- it will be added as an fd victim, but fence_victims() will
- call is_fenced_external() which will see that it's already
- fenced and bypass fencing it again */
-
-static void receive_external(struct fd *fd, struct fd_header *hd, int len)
-{
- log_debug("receive_external from %d len %d victim nodeid %d",
- hd->nodeid, len, hd->msgdata);
-
- node_history_fence_external(fd, hd->msgdata, hd->nodeid);
-}
-
-int is_fenced_external(struct fd *fd, int nodeid)
-{
- struct node_history *node;
-
- node = get_node_history(fd, nodeid);
- if (!node) {
- log_error("is_fenced_external no nodeid %d", nodeid);
- return 0;
- }
-
- if (node->fence_external_time > node->add_time)
- return 1;
- return 0;
-}
-
-/* completed victim must be removed from victims list before calling this
- because we count the number of entries on the victims list for remaining */
-
-void send_victim_done(struct fd *fd, int victim)
-{
- struct change *cg = list_first_entry(&fd->changes, struct change, list);
- struct fd_header *hd;
- struct id_info *id;
- struct node_history *node;
- char *buf;
- int len;
-
- len = sizeof(struct fd_header) + sizeof(struct id_info);
-
- buf = malloc(len);
- if (!buf) {
- log_error("send_victim_done no mem len %d", len);
- return;
- }
- memset(buf, 0, len);
-
- hd = (struct fd_header *)buf;
- hd->type = FD_MSG_VICTIM_DONE;
- hd->msgdata = cg->seq;
-
- if (fd->init_complete || fd->local_init_complete)
- hd->flags |= FD_MFLG_COMPLETE;
-
- node = get_node_history(fd, victim);
- if (!node) {
- log_error("send_victim_done no nodeid %d", victim);
- return;
- }
-
- id = (struct id_info *)(buf + sizeof(struct fd_header));
- id->nodeid = cpu_to_le32(victim);
- id->fence_master = cpu_to_le32(our_nodeid);
- id->fence_time = cpu_to_le64(node->fence_time);
- id->fence_how = cpu_to_le32(node->fence_how);
-
- log_debug("send_victim_done cg %u flags %x victim nodeid %d",
- cg->seq, hd->flags, victim);
-
- fd_send_message(fd, buf, len);
-
- free(buf);
-}
-
-/* The master needs to remove the victim upon receiving its own victim_done
- message, just like everyone else. Otherwise, when a partitioned node is
- remerged and then killed, the others will see it's already a victim, but
- the master won't see that confchg until after it's done fencing the
- victim for the initial partition. So when the master sees the second
- failure (due to the kill), the node won't be a victim already so it'll
- become a victim again. */
-
-static void receive_victim_done(struct fd *fd, struct fd_header *hd, int len)
-{
- struct node *node;
- struct node_history *nodeh;
- uint32_t seq = hd->msgdata;
- struct id_info *id;
-
- log_debug("receive_victim_done %d:%u flags %x len %d", hd->nodeid, seq,
- hd->flags, len);
-
- /* check that hd->nodeids is fd->master ? */
-
- id = (struct id_info *)((char *)hd + sizeof(struct fd_header));
- id_info_in(id);
-
- node = get_node_victim(fd, id->nodeid);
- if (!node) {
- /* see comment below about no node */
- log_debug("receive_victim_done %d:%u no victim nodeid %d",
- hd->nodeid, seq, id->nodeid);
- }
-
- log_debug("receive_victim_done %d:%u remove victim %d time %llu how %d",
- hd->nodeid, seq, id->nodeid,
- (unsigned long long)id->fence_time, id->fence_how);
-
- nodeh = get_node_history(fd, id->nodeid);
- if (!nodeh)
- log_error("receive_victim_done no node history %d", id->nodeid);
- else
- nodeh->fence_time_local = time(NULL);
-
- if (hd->nodeid == our_nodeid) {
- /* sanity check, I don't think this should happen;
- see comment in fence_victims() */
- if (node) {
- if (!node->local_victim_done)
- log_error("expect local_victim_done");
- node->local_victim_done = 0;
- }
- } else {
- /* save details of fencing operation from master, which
- master saves at the time it completes it */
- node_history_fence(fd, id->nodeid, id->fence_master,
- id->fence_how, id->fence_time);
- }
-
- /* we can have no node when reduce_victims() removes it, bz 678704 */
-
- if (node) {
- list_del(&node->list);
- free(node);
- }
-}
-
-/* we know that the quorum value here is consistent with the cpg events
- because the ringid's are in sync per the previous check_ringid_done */
-
-static int check_quorum_done(struct fd *fd)
-{
- if (!cluster_quorate) {
- log_debug("check_quorum not quorate");
- return 0;
- }
-
- log_debug("check_quorum done");
- return 1;
-}
-
-/* wait for cman ringid and cpg ringid to be the same so we know our
- information from each service is based on the same node state */
-
-static int check_ringid_done(struct fd *fd)
-{
- if (cluster_ringid_seq != (uint32_t)fd->cpg_ringid.seq) {
- log_debug("check_ringid cluster %u cpg %u:%llu",
- cluster_ringid_seq, fd->cpg_ringid.nodeid,
- (unsigned long long)fd->cpg_ringid.seq);
- return 0;
- }
-
- log_debug("check_ringid done cluster %u cpg %u:%llu",
- cluster_ringid_seq, fd->cpg_ringid.nodeid,
- (unsigned long long)fd->cpg_ringid.seq);
- return 1;
-}
-
-static int wait_conditions_done(struct fd *fd)
-{
- if (!check_ringid_done(fd))
- return 0;
- if (!check_quorum_done(fd))
- return 0;
- return 1;
-}
-
-static int wait_messages_done(struct fd *fd)
-{
- struct change *cg = list_first_entry(&fd->changes, struct change, list);
- struct member *memb;
- int need = 0, total = 0;
-
- list_for_each_entry(memb, &cg->members, list) {
- if (!memb->start)
- need++;
- total++;
- }
-
- if (need) {
- log_debug("wait_messages cg %u need %d of %d",
- cg->seq, need, total);
- return 0;
- }
-
- log_debug("wait_messages cg %u got all %d", cg->seq, total);
- return 1;
-}
-
-static void cleanup_changes(struct fd *fd)
-{
- struct change *cg = list_first_entry(&fd->changes, struct change, list);
- struct change *safe;
-
- list_del(&cg->list);
- if (fd->started_change)
- free_cg(fd->started_change);
- fd->started_change = cg;
-
- /* zero started_count means "never started" */
-
- fd->started_count++;
- if (!fd->started_count)
- fd->started_count++;
-
- list_for_each_entry_safe(cg, safe, &fd->changes, list) {
- list_del(&cg->list);
- free_cg(cg);
- }
-}
-
-static void set_master(struct fd *fd)
-{
- struct change *cg = list_first_entry(&fd->changes, struct change, list);
- struct member *memb;
- int low = 0, complete = 0;
-
- list_for_each_entry(memb, &cg->members, list) {
- if (!low || memb->nodeid < low)
- low = memb->nodeid;
-
- if (!(memb->start_flags & FD_MFLG_COMPLETE))
- continue;
-
- if (!complete || memb->nodeid < complete)
- complete = memb->nodeid;
- }
-
- log_debug("set_master from %d to %s node %d", fd->master,
- complete ? "complete" : "low",
- complete ? complete : low);
-
- fd->master = complete ? complete : low;
-}
-
-static struct id_info *get_id_struct(struct id_info *ids, int count, int size,
- int nodeid)
-{
- struct id_info *id = ids;
- int i;
-
- for (i = 0; i < count; i++) {
- if (id->nodeid == nodeid)
- return id;
- id = (struct id_info *)((char *)id + size);
- }
- return NULL;
-}
-
-/* do the change details in the message match the details of the given change */
-
-static int match_change(struct fd *fd, struct change *cg, struct fd_header *hd,
- struct fd_info *fi, struct id_info *ids)
-{
- struct id_info *id;
- struct member *memb;
- struct node_history *node;
- uint32_t seq = hd->msgdata;
- int i, members_mismatch;
-
- /* We can ignore messages if we're not in the list of members.
- The one known time this will happen is after we've joined
- the cpg, we can get messages for changes prior to the change
- in which we're added. */
-
- id = get_id_struct(ids, fi->id_info_count, fi->id_info_size,our_nodeid);
-
- if (!id || !(id->flags & IDI_NODEID_IS_MEMBER)) {
- log_debug("match_change %d:%u skip cg %u we are not in members",
- hd->nodeid, seq, cg->seq);
- return 0;
- }
-
- memb = find_memb(cg, hd->nodeid);
- if (!memb) {
- log_debug("match_change %d:%u skip cg %u sender not member",
- hd->nodeid, seq, cg->seq);
- return 0;
- }
-
- if (memb->start) {
- log_debug("match_change %d:%u skip cg %u already start",
- hd->nodeid, seq, cg->seq);
- return 0;
- }
-
- /* a node's start can't match a change if the node joined the cluster
- more recently than the change was created */
-
- node = get_node_history(fd, hd->nodeid);
- if (!node) {
- log_debug("match_change %d:%u skip cg %u no node history",
- hd->nodeid, seq, cg->seq);
- return 0;
- }
-
- if (node->cluster_add_time > cg->create_time) {
- log_debug("match_change %d:%u skip cg %u created %llu "
- "cluster add %llu", hd->nodeid, seq, cg->seq,
- (unsigned long long)cg->create_time,
- (unsigned long long)node->cluster_add_time);
- return 0;
- }
-
- /* this start message couldn't have been sent for a cg preceding
- a confchg when the sending node failed or left */
-
- if ((node->fail_seq > cg->seq) || (node->left_seq > cg->seq)) {
- log_debug("match_change %d:%u skip cg %u fail cg %u left cg %u",
- hd->nodeid, seq, cg->seq,
- node->fail_seq, node->left_seq);
- return 0;
- }
-
- /* if we matched the last start message from this node against our
- cg N, then don't match this stsart message against an earlier cg */
-
- if (node->last_match_seq > cg->seq) {
- log_debug("match_change %d:%u skip cg %u last matched cg %u",
- hd->nodeid, seq, cg->seq, node->last_match_seq);
- return 0;
- }
-
- /* verify this is the right change by matching the counts
- and the nodeids of the current members */
-
- if (fi->member_count != cg->member_count ||
- fi->joined_count != cg->joined_count ||
- fi->remove_count != cg->remove_count ||
- fi->failed_count != cg->failed_count) {
- log_debug("match_change %d:%u skip cg %u expect counts "
- "%d %d %d %d", hd->nodeid, seq, cg->seq,
- cg->member_count, cg->joined_count,
- cg->remove_count, cg->failed_count);
- return 0;
- }
-
- members_mismatch = 0;
- id = ids;
-
- for (i = 0; i < fi->id_info_count; i++) {
- if (id->flags & IDI_NODEID_IS_MEMBER) {
- memb = find_memb(cg, id->nodeid);
- if (!memb) {
- log_debug("match_change %d:%u skip cg %u "
- "no memb %d", hd->nodeid, seq,
- cg->seq, id->nodeid);
- members_mismatch = 1;
- break;
- }
- }
- id = (struct id_info *)((char *)id + fi->id_info_size);
- }
-
- if (members_mismatch)
- return 0;
-
- node->last_match_seq = cg->seq;
-
- log_debug("match_change %d:%u matches cg %u", hd->nodeid, seq, cg->seq);
- return 1;
-}
-
-/* Unfortunately, there's no really simple way to match a message with the
- specific change that it was sent for. We hope that by passing all the
- details of the change in the message, we will be able to uniquely match the
- it to the correct change. */
-
-/* A start message will usually be for the first (current) change on our list.
- In some cases it will be for a non-current change, and we can ignore it:
-
- 1. A,B,C get confchg1 adding C
- 2. C sends start for confchg1
- 3. A,B,C get confchg2 adding D
- 4. A,B,C,D recv start from C for confchg1 - ignored
- 5. C,D send start for confchg2
- 6. A,B send start for confchg2
- 7. A,B,C,D recv all start messages for confchg2, and start kernel
-
- In step 4, how do the nodes know whether the start message from C is
- for confchg1 or confchg2? Hopefully by comparing the counts and members. */
-
-/* fails to handle partition, merge, kill, failing/manual fence, rejoin.
- a. m=A,B,C,D
- b. m=A/B,C,D partition, node B fencing node A, manual, or agent failing
- c. m=A,B,C,D merge, nodes B,C,D kill cman on node A
- d. m=B,C,D
- e. m=A,B,C,D clean rejoin by node A
- f. node B quits fencing retries on node A and sends victim_done/MEMBER/A
-
- The problem is that node A in step e receives node B's start message
- from step c and wrongly thinks it's for step e (member and join lists
- are the same m=A,B,C,D j=A). Node B sends the start message for step c
- so late because it was busy retrying fencing until node A cleanly rejoined
- in step e, then moved on to process cpg events c, d and e.
-
- Second problem with this test (not related to change matching) is node B
- gets stuck on cman is_member checks for the failure of node A due to the
- kill. It's waiting for B to become a non-member in cman due to the failure,
- but B has rejoined since that past failure and won't go away again.
-
- Possible solution to both problmes:
- Wait for cpg and cman to be in sync with each other (matching ringid's
- from both api's?) in wait_conditions.
-
- a) To replace quorum_done check. (it would be ok for cman ringid to
- be > cpg ringid for this check but not for other). This ensures that
- cman is not lagging behind cpg. Waits for cman to catch up with cpg.
-
- b) To avoid sending start for an old cpg confchg. If cman ringid
- is > cpg ringid, then return 0 for conditions_done so we won't send
- start and will wait until the most recent cpg confchg (matching the
- current cman one) to send a start. Waits for cpg to catch up with cman.
-
- Final solution is the patch adding check_ringid_done() that waits for
- cman and cpg to both be on the same ringid before going ahead to check
- quorum and send starts.
-*/
-
-static struct change *find_change(struct fd *fd, struct fd_header *hd,
- struct fd_info *fi, struct id_info *ids)
-{
- struct change *cg;
- struct change *cg1 = NULL, *cg2 = NULL;
-
- list_for_each_entry_reverse(cg, &fd->changes, list) {
- if (!match_change(fd, cg, hd, fi, ids))
- continue;
-
- if (!(hd->flags & FD_MFLG_DUPLICATE_CG))
- return cg;
-
- /* this start message is for the second of two matching cg's */
-
- if (!cg1) {
- cg1 = cg;
- log_debug("find_change %d:%u match1 %u look for dup",
- hd->nodeid, hd->msgdata, cg1->seq);
- continue;
- } else {
- cg2 = cg;
- log_debug("find_change %d:%u match1 %u match2 %u",
- hd->nodeid, hd->msgdata, cg1->seq, cg2->seq);
- break;
- }
- }
-
- if (cg1 && cg2)
- return cg2;
- if (cg1)
- return cg1;
-
- log_debug("find_change %d:%u no match", hd->nodeid, hd->msgdata);
- return NULL;
-}
-
-static int is_added(struct fd *fd, int nodeid)
-{
- struct change *cg;
- struct member *memb;
-
- list_for_each_entry(cg, &fd->changes, list) {
- memb = find_memb(cg, nodeid);
- if (memb && memb->added)
- return 1;
- }
- return 0;
-}
-
-static void receive_start(struct fd *fd, struct fd_header *hd, int len)
-{
- struct change *cg;
- struct member *memb;
- struct fd_info *fi;
- struct id_info *ids;
- uint32_t seq = hd->msgdata;
- int added;
-
- log_debug("receive_start %d:%u len %d", hd->nodeid, seq, len);
-
- fi = (struct fd_info *)((char *)hd + sizeof(struct fd_header));
- ids = (struct id_info *)((char *)fi + sizeof(struct fd_info));
-
- fd_info_in(fi);
- ids_in(fi, ids);
-
- cg = find_change(fd, hd, fi, ids);
- if (!cg)
- return;
-
- memb = find_memb(cg, hd->nodeid);
- if (!memb) {
- /* this should never happen since match_change checks it */
- log_error("receive_start no member %d", hd->nodeid);
- return;
- }
-
- memb->start_flags = hd->flags;
-
- added = is_added(fd, hd->nodeid);
-
- if (added && fi->started_count && fd->started_count) {
- log_error("receive_start %d:%u add node with started_count %u",
- hd->nodeid, seq, fi->started_count);
-
- /* This is how we deal with cpg's that are partitioned and
- then merge back together. When the merge happens, the
- cpg on each side will see nodes from the other side being
- added, and neither side will have zero started_count. So,
- both sides will ignore start messages from the other side.
- This causes the the domain on each side to continue waiting
- for the missing start messages indefinately. To unblock
- things, all nodes from one side of the former partition
- need to fail. */
-
- /* This method of detecting a merge of a partitioned cpg
- assumes a joining node won't ever see an existing node
- as "added" under normal circumstances. */
-
- /* The fd->started_count condition is needed for the case
- where a node begins partitioned, has never started, and then
- is merged with other nodes that have started. We don't
- want this unstarted node to reject the started ones even
- though it sees them as "added". */
-
- memb->disallowed = 1;
- return;
- }
-
- node_history_start(fd, hd->nodeid);
- memb->start = 1;
-
- /* save any fencing history from this message that we don't have */
- save_history(fd, fi, ids);
-}
-
-static void receive_complete(struct fd *fd, struct fd_header *hd, int len)
-{
- struct fd_info *fi;
- struct id_info *ids, *id;
- uint32_t seq = hd->msgdata;
- struct node *node, *safe;
-
- log_debug("receive_complete %d:%u len %d", hd->nodeid, seq, len);
-
- if (fd->init_complete)
- return;
-
- fi = (struct fd_info *)((char *)hd + sizeof(struct fd_header));
- ids = (struct id_info *)((char *)fi + sizeof(struct fd_info));
-
- fd_info_in(fi);
- ids_in(fi, ids);
-
- id = get_id_struct(ids, fi->id_info_count, fi->id_info_size,our_nodeid);
-
- if (!id || !(id->flags & IDI_NODEID_IS_MEMBER)) {
- log_debug("receive_complete %d:%u we are not in members",
- hd->nodeid, seq);
- return;
- }
-
- fd->init_complete = 1;
-
- /* we may have victims from init which we can clear now */
- list_for_each_entry_safe(node, safe, &fd->victims, list) {
- log_debug("receive_complete clear victim nodeid %d init %d",
- node->nodeid, node->init_victim);
-
- if (node->init_victim) {
- list_del(&node->list);
- free(node);
- }
- }
-}
-
-static int count_ids(struct fd *fd)
-{
- struct node_history *node;
- int count = 0;
-
- list_for_each_entry(node, &fd->node_history, list)
- count++;
-
- return count;
-}
-
-static void send_info(struct fd *fd, struct change *cg, int type,
- uint32_t flags)
-{
- struct fd_header *hd;
- struct fd_info *fi;
- struct id_info *id;
- struct node_history *node;
- char *buf;
- uint32_t idflags;
- int len, id_count;
-
- id_count = count_ids(fd);
-
- len = sizeof(struct fd_header) + sizeof(struct fd_info) +
- id_count * sizeof(struct id_info);
-
- buf = malloc(len);
- if (!buf) {
- log_error("send_info len %d no mem", len);
- return;
- }
- memset(buf, 0, len);
-
- hd = (struct fd_header *)buf;
- fi = (struct fd_info *)(buf + sizeof(*hd));
- id = (struct id_info *)(buf + sizeof(*hd) + sizeof(*fi));
-
- /* fill in header (fd_send_message handles part of header) */
-
- hd->type = type;
- hd->msgdata = cg->seq;
- hd->flags = flags;
-
- if (cg->we_joined)
- hd->flags |= FD_MFLG_JOINING;
- if (fd->init_complete || fd->local_init_complete)
- hd->flags |= FD_MFLG_COMPLETE;
-
- /* fill in fd_info */
-
- fi->fd_info_size = cpu_to_le32(sizeof(struct fd_info));
- fi->id_info_size = cpu_to_le32(sizeof(struct id_info));
- fi->id_info_count = cpu_to_le32(id_count);
- fi->started_count = cpu_to_le32(fd->started_count);
- fi->member_count = cpu_to_le32(cg->member_count);
- fi->joined_count = cpu_to_le32(cg->joined_count);
- fi->remove_count = cpu_to_le32(cg->remove_count);
- fi->failed_count = cpu_to_le32(cg->failed_count);
-
- /* fill in id_info entries */
-
- list_for_each_entry(node, &fd->node_history, list) {
- idflags = 0;
- if (find_memb(cg, node->nodeid))
- idflags = IDI_NODEID_IS_MEMBER;
-
- id->flags = cpu_to_le32(idflags);
- id->nodeid = cpu_to_le32(node->nodeid);
- id->fence_external_node= cpu_to_le32(node->fence_external_node);
- id->fence_master = cpu_to_le32(node->fence_master);
- id->fence_how = cpu_to_le32(node->fence_how);
- id->fence_time = cpu_to_le64(node->fence_time);
- id->fence_external_time= cpu_to_le64(node->fence_external_time);
- id++;
- }
-
- log_debug("send_%s %d:%u flags %x started %u m %d j %d r %d f %d",
- type == FD_MSG_START ? "start" : "complete", our_nodeid,
- cg->seq, hd->flags, fd->started_count, cg->member_count,
- cg->joined_count, cg->remove_count, cg->failed_count);
-
- fd_send_message(fd, buf, len);
-
- free(buf);
-}
-
-static int same_members(struct change *cg1, struct change *cg2)
-{
- struct member *memb;
-
- list_for_each_entry(memb, &cg1->members, list) {
- if (!find_memb(cg2, memb->nodeid))
- return 0;
- }
- return 1;
-}
-
-static void send_start(struct fd *fd)
-{
- struct change *cg = list_first_entry(&fd->changes, struct change, list);
- struct change *cgtmp;
- uint32_t flags = 0;
-
- /* look for a previous matching cg that we don't want others to
- confuse for this one */
-
- list_for_each_entry(cgtmp, &fd->changes, list) {
- if (cgtmp->sent_start)
- continue;
-
- if (cgtmp->seq < cg->seq &&
- cgtmp->member_count == cg->member_count &&
- cgtmp->joined_count == cg->joined_count &&
- cgtmp->remove_count == cg->remove_count &&
- cgtmp->failed_count == cg->failed_count &&
- same_members(cgtmp, cg)) {
- log_debug("duplicate old cg %u new cg %u",
- cgtmp->seq, cg->seq);
- flags = FD_MFLG_DUPLICATE_CG;
- }
- }
-
- cg->sent_start = 1;
-
- send_info(fd, cg, FD_MSG_START, flags);
-}
-
-/* same content as a start message, a new (incomplete) node will look for
- a complete message that shows it as a member, when it sees one it can
- clear any init_victims and set init_complete for future cycles */
-
-static void send_complete(struct fd *fd)
-{
- struct change *cg = list_first_entry(&fd->changes, struct change, list);
-
- send_info(fd, cg, FD_MSG_COMPLETE, 0);
-}
-
-/* FIXME: better to just look in victims list for any nodes with init_victim? */
-
-static int nodes_added(struct fd *fd)
-{
- struct change *cg;
-
- list_for_each_entry(cg, &fd->changes, list) {
- if (cg->joined_count)
- return 1;
- }
- return 0;
-}
-
-/* If we're being added by the current change, we'll have an empty victims
- list, while other previous members may already have nodes in their
- victims list. So, we need to assume that any node in cluster.conf that's
- not a cluster member when we're added to the fd is already a victim.
- We can go back on that assumption, and clear out any presumed victims, when
- we see a message from a previous member saying that are no current victims.*/
-
-static void add_victims(struct fd *fd, struct change *cg)
-{
- struct member *memb;
- struct node *node;
-
- list_for_each_entry(memb, &cg->removed, list) {
- if (!memb->failed)
- continue;
- if (is_victim(fd, memb->nodeid)) {
- /* Only one scenario I know of where this happens:
- when a partitioned cpg merges and then the
- disallowed node is killed. The original
- partition makes the node a victim, and killing
- it after a merge will find it already a victim. */
- log_debug("add_victims node %d already victim",
- memb->nodeid);
- continue;
- }
- node = get_new_node(fd, memb->nodeid);
- if (!node)
- return;
- list_add(&node->list, &fd->victims);
- log_debug("add_victims node %d", node->nodeid);
-
- /*
- * If we haven't completed a start cycle yet, set
- * init_victim on any failed node so that receive_complete
- * will clear it. This is a hack for one specific scenario:
- *
- * - node 2 joins domain, blocks in startup fencing
- * - node 1 joins domain, waiting for messages in start cycle
- * - partition between 1,2
- * - 1 adds victim 2
- * (and sets init_victim below since 1 hasn't completed
- * a start cycle yet)
- * - partition removed
- * - node 2 completes startup fencing
- * - 2 gets confchg for partition
- * - 2 adds victim 1 (due to partition)
- * - 2 gets confchg for merge
- * - 2 does join for 1 (due to merge), begins start cycle
- * - start cycle adding node 1 finishes, 2 sends complete
- * - 2 reduces victim 1
- * - 1 receives complete for its join start cycle,
- * and clears victim 2 because we've set init_victim here
- */
-
- if (!fd->started_count) {
- log_debug("add_victims node %d set init_victim",
- node->nodeid);
- node->init_victim = 1;
- }
- }
-}
-
-/* with start messages from all members, we can pick which one should be master
- and do the fencing (low nodeid with state, "COMPLETE"). as the master
- successfully fences each victim, it sends a status message such that all
- members remove the node from their victims list.
-
- after all victims have been dealt following a change (or set of changes),
- the master sends a complete message that indicates the members of the group
- for the change it has completed processing. when a joining node sees this
- complete message and sees itself as a member, it knows it can clear all
- init_victims from startup init, and it sets init_complete so it will
- volunteer to be master in the next round by setting COMPLETE flag.
-
- once the master begins fencing victims, it won't process any new changes
- until it's done. the non-master members will process changes while the
- master is fencing, but will wait for the master to catch up in
- WAIT_MESSAGES. if the master fails, the others will no longer wait for it.*/
-
-static void apply_changes(struct fd *fd)
-{
- struct change *cg;
-
- if (list_empty(&fd->changes))
- return;
- cg = list_first_entry(&fd->changes, struct change, list);
-
- switch (cg->state) {
-
- case CGST_WAIT_CONDITIONS:
- if (wait_conditions_done(fd)) {
- send_start(fd);
- cg->state = CGST_WAIT_MESSAGES;
- }
- break;
-
- case CGST_WAIT_MESSAGES:
- if (wait_messages_done(fd)) {
- our_protocol.dr_ver.flags |= PV_STATEFUL;
- set_master(fd);
- cg->state = CGST_WAIT_FENCING; /* for queries */
-
- if (fd->master == our_nodeid) {
- delay_fencing(fd, nodes_added(fd));
- fence_victims(fd);
- send_complete(fd);
- fd->local_init_complete = 1;
- } else {
- defer_fencing(fd);
- }
-
- cleanup_changes(fd);
- fd->joining_group = 0;
- }
- break;
-
- default:
- log_error("apply_changes invalid state %d", cg->state);
- }
-}
-
-void process_fd_changes(void)
-{
- struct fd *fd, *safe;
-
- list_for_each_entry_safe(fd, safe, &domains, list) {
- if (!list_empty(&fd->changes))
- apply_changes(fd);
- }
-}
-
-static int add_change(struct fd *fd,
- const struct cpg_address *member_list,
- size_t member_list_entries,
- const struct cpg_address *left_list,
- size_t left_list_entries,
- const struct cpg_address *joined_list,
- size_t joined_list_entries,
- struct change **cg_out)
-{
- struct change *cg;
- struct member *memb;
- int i, error;
-
- cg = malloc(sizeof(struct change));
- if (!cg)
- goto fail_nomem;
- memset(cg, 0, sizeof(struct change));
- INIT_LIST_HEAD(&cg->members);
- INIT_LIST_HEAD(&cg->removed);
- cg->seq = ++fd->change_seq;
- cg->state = CGST_WAIT_CONDITIONS;
- cg->create_time = time(NULL);
-
- cg->member_count = member_list_entries;
- cg->joined_count = joined_list_entries;
- cg->remove_count = left_list_entries;
-
- for (i = 0; i < member_list_entries; i++) {
- memb = malloc(sizeof(struct member));
- if (!memb)
- goto fail_nomem;
- memset(memb, 0, sizeof(struct member));
- memb->nodeid = member_list[i].nodeid;
- list_add_tail(&memb->list, &cg->members);
- }
-
- for (i = 0; i < left_list_entries; i++) {
- memb = malloc(sizeof(struct member));
- if (!memb)
- goto fail_nomem;
- memset(memb, 0, sizeof(struct member));
- memb->nodeid = left_list[i].nodeid;
- if (left_list[i].reason == CPG_REASON_NODEDOWN ||
- left_list[i].reason == CPG_REASON_PROCDOWN) {
- memb->failed = 1;
- cg->failed_count++;
- }
- list_add_tail(&memb->list, &cg->removed);
-
- if (memb->failed)
- node_history_fail(fd, memb->nodeid, cg->seq);
- else
- node_history_left(fd, memb->nodeid, cg->seq);
-
- log_debug("add_change cg %u remove nodeid %d reason %d",
- cg->seq, memb->nodeid, left_list[i].reason);
-
- if (left_list[i].reason == CPG_REASON_PROCDOWN)
- kick_node_from_cluster(memb->nodeid);
- }
-
- for (i = 0; i < joined_list_entries; i++) {
- memb = find_memb(cg, joined_list[i].nodeid);
- if (!memb) {
- log_error("no member %d", joined_list[i].nodeid);
- error = -ENOENT;
- goto fail;
- }
- memb->added = 1;
-
- if (memb->nodeid == our_nodeid)
- cg->we_joined = 1;
- else
- node_history_init(fd, memb->nodeid);
-
- log_debug("add_change cg %u joined nodeid %d", cg->seq,
- memb->nodeid);
- }
-
- if (cg->we_joined)
- list_for_each_entry(memb, &cg->members, list)
- node_history_init(fd, memb->nodeid);
-
- log_debug("add_change cg %u m %d j %d r %d f %d",
- cg->seq, cg->member_count, cg->joined_count,
- cg->remove_count, cg->failed_count);
-
- list_add(&cg->list, &fd->changes);
- *cg_out = cg;
- return 0;
-
- fail_nomem:
- log_error("no memory");
- error = -ENOMEM;
- fail:
- free_cg(cg);
- return error;
-}
-
-/* add a victim for each node in complete list (represents all nodes in
- cluster.conf) that is not a cman member (and not already a victim) */
-
-static void add_victims_init(struct fd *fd, struct change *cg)
-{
- struct node *node, *safe;
-
- list_for_each_entry_safe(node, safe, &fd->complete, list) {
- list_del(&node->list);
-
- if (!is_cluster_member_reread(node->nodeid) &&
- !find_memb(cg, node->nodeid) &&
- !is_victim(fd, node->nodeid)) {
- node->init_victim = 1;
- list_add(&node->list, &fd->victims);
- log_debug("add_victims_init nodeid %d", node->nodeid);
- } else {
- free(node);
- }
- }
-}
-
-static int we_left(const struct cpg_address *left_list,
- size_t left_list_entries)
-{
- int i;
-
- for (i = 0; i < left_list_entries; i++) {
- if (left_list[i].nodeid == our_nodeid)
- return 1;
- }
- return 0;
-}
-
-static void confchg_cb_domain(cpg_handle_t handle,
- const struct cpg_name *group_name,
- const struct cpg_address *member_list,
- size_t member_list_entries,
- const struct cpg_address *left_list,
- size_t left_list_entries,
- const struct cpg_address *joined_list,
- size_t joined_list_entries)
-{
- struct fd *fd;
- struct change *cg;
- int rv;
-
- log_config(group_name, member_list, member_list_entries,
- left_list, left_list_entries,
- joined_list, joined_list_entries);
-
- fd = find_fd_handle(handle);
- if (!fd) {
- log_error("confchg_cb no fence domain for cpg %s",
- group_name->value);
- return;
- }
-
- if (fd->leaving_group && we_left(left_list, left_list_entries)) {
- /* we called cpg_leave(), and this should be the final
- cpg callback we receive */
- log_debug("confchg for our leave");
- cpg_finalize(fd->cpg_handle);
- client_dead(fd->cpg_client);
- list_del(&fd->list);
- free_fd(fd);
- return;
- }
-
- rv = add_change(fd, member_list, member_list_entries,
- left_list, left_list_entries,
- joined_list, joined_list_entries, &cg);
- if (rv)
- return;
-
- /* failed nodes in this change become victims */
-
- add_victims(fd, cg);
-
- /* As a joining domain member with no previous state, we need to
- assume non-member nodes are already victims; these initial victims
- are cleared if we get a "complete" message from the master.
- But, if we're the master, we do end up fencing these init nodes. */
-
- if (cg->we_joined)
- add_victims_init(fd, cg);
-
- apply_changes(fd);
-}
-
-static void fd_header_in(struct fd_header *hd)
-{
- hd->version[0] = le16_to_cpu(hd->version[0]);
- hd->version[1] = le16_to_cpu(hd->version[1]);
- hd->version[2] = le16_to_cpu(hd->version[2]);
- hd->type = le16_to_cpu(hd->type);
- hd->nodeid = le32_to_cpu(hd->nodeid);
- hd->to_nodeid = le32_to_cpu(hd->to_nodeid);
- hd->global_id = le32_to_cpu(hd->global_id);
- hd->flags = le32_to_cpu(hd->flags);
- hd->msgdata = le32_to_cpu(hd->msgdata);
-}
-
-static void deliver_cb_domain(cpg_handle_t handle,
- const struct cpg_name *group_name,
- uint32_t nodeid, uint32_t pid,
- void *data, size_t len)
-{
- struct fd *fd;
- struct fd_header *hd;
-
- fd = find_fd_handle(handle);
- if (!fd) {
- log_error("deliver_cb no fd for cpg %s", group_name->value);
- return;
- }
-
- if (len < sizeof(*hd)) {
- log_error("deliver_cb short message %zd", len);
- return;
- }
-
- hd = (struct fd_header *)data;
- fd_header_in(hd);
-
- if (hd->version[0] != our_protocol.daemon_run[0] ||
- hd->version[1] != our_protocol.daemon_run[1]) {
- log_error("reject message from %d version %u.%u.%u vs %u.%u.%u",
- nodeid, hd->version[0], hd->version[1],
- hd->version[2], our_protocol.daemon_run[0],
- our_protocol.daemon_run[1],
- our_protocol.daemon_run[2]);
- return;
- }
-
- if (hd->nodeid != nodeid) {
- log_error("bad msg nodeid %d %d", hd->nodeid, nodeid);
- return;
- }
-
- switch (hd->type) {
- case FD_MSG_START:
- receive_start(fd, hd, len);
- break;
- case FD_MSG_VICTIM_DONE:
- receive_victim_done(fd, hd, len);
- break;
- case FD_MSG_COMPLETE:
- receive_complete(fd, hd, len);
- break;
- case FD_MSG_EXTERNAL:
- receive_external(fd, hd, len);
- break;
- default:
- log_error("unknown msg type %d", hd->type);
- }
-
- apply_changes(fd);
-}
-
-/* save ringid to compare with cman's.
- also save member_list to double check with cman's member list?
- they should match */
-
-static void totem_cb_domain(cpg_handle_t handle,
- struct cpg_ring_id ring_id,
- uint32_t member_list_entries,
- const uint32_t *member_list)
-{
- struct fd *fd;
-
- log_ringid(handle, &ring_id, member_list, member_list_entries);
-
- fd = find_fd_handle(handle);
- if (!fd) {
- log_error("totem_cb no fence domain for handle");
- return;
- }
-
- fd->cpg_ringid.nodeid = ring_id.nodeid;
- fd->cpg_ringid.seq = ring_id.seq;
-
- apply_changes(fd);
-}
-
-static cpg_model_v1_data_t cpg_callbacks_domain = {
- .cpg_deliver_fn = deliver_cb_domain,
- .cpg_confchg_fn = confchg_cb_domain,
- .cpg_totem_confchg_fn = totem_cb_domain,
- .flags = CPG_MODEL_V1_DELIVER_INITIAL_TOTEM_CONF,
-};
-
-static void process_cpg_domain(int ci)
-{
- struct fd *fd;
- cpg_error_t error;
-
- fd = find_fd_ci(ci);
- if (!fd) {
- log_error("process_cpg_domain no fence domain for ci %d", ci);
- return;
- }
-
- error = cpg_dispatch(fd->cpg_handle, CPG_DISPATCH_ALL);
- if (error != CPG_OK) {
- log_error("cpg_dispatch error %d", error);
- return;
- }
-}
-
-int fd_join(struct fd *fd)
-{
- cpg_error_t error;
- struct cpg_name name;
- int i = 0, ci;
-
- error = cpg_model_initialize(&cpg_handle_domain, CPG_MODEL_V1,
- (cpg_model_data_t *)&cpg_callbacks_domain,
- NULL);
- if (error != CPG_OK) {
- log_error("cpg_model_initialize error %d", error);
- goto fail_free;
- }
-
- cpg_fd_get(cpg_handle_domain, &cpg_fd_domain);
-
- ci = client_add(cpg_fd_domain, process_cpg_domain, cluster_dead);
-
- list_add(&fd->list, &domains);
- fd->cpg_handle = cpg_handle_domain;
- fd->cpg_client = ci;
- fd->cpg_fd = cpg_fd_domain;
- fd->joining_group = 1;
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "fenced:%s", fd->name);
- name.length = strlen(name.value) + 1;
- memcpy(&group_name_domain, &name, sizeof(struct cpg_name));
-
- log_debug("cpg_join %s ...", name.value);
- retry:
- error = cpg_join(cpg_handle_domain, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- sleep(1);
- if (!(++i % 10))
- log_error("cpg_join error retrying");
- goto retry;
- }
- if (error != CPG_OK) {
- log_error("cpg_join error %d", error);
- goto fail;
- }
-
- return 0;
-
- fail:
- list_del(&fd->list);
- client_dead(ci);
- cpg_finalize(cpg_handle_domain);
- fail_free:
- free(fd);
- return error;
-}
-
-int fd_leave(struct fd *fd)
-{
- cpg_error_t error;
- struct cpg_name name;
- int i = 0;
-
- fd->leaving_group = 1;
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "fenced:%s", fd->name);
- name.length = strlen(name.value) + 1;
-
- log_debug("cpg_leave %s ...", name.value);
- retry:
- error = cpg_leave(fd->cpg_handle, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- sleep(1);
- if (!(++i % 10))
- log_error("cpg_leave error retrying");
- goto retry;
- }
- if (error != CPG_OK)
- log_error("cpg_leave error %d", error);
-
- return 0;
-}
-
-static struct node_daemon *get_node_daemon(int nodeid)
-{
- struct node_daemon *node;
-
- list_for_each_entry(node, &daemon_nodes, list) {
- if (node->nodeid == nodeid)
- return node;
- }
- return NULL;
-}
-
-static void add_node_daemon(int nodeid)
-{
- struct node_daemon *node;
-
- if (get_node_daemon(nodeid))
- return;
-
- node = malloc(sizeof(struct node_daemon));
- if (!node) {
- log_error("add_node_daemon no mem");
- return;
- }
- memset(node, 0, sizeof(struct node_daemon));
- node->nodeid = nodeid;
- list_add_tail(&node->list, &daemon_nodes);
-}
-
-static void pv_in(struct protocol_version *pv)
-{
- pv->major = le16_to_cpu(pv->major);
- pv->minor = le16_to_cpu(pv->minor);
- pv->patch = le16_to_cpu(pv->patch);
- pv->flags = le16_to_cpu(pv->flags);
-}
-
-static void pv_out(struct protocol_version *pv)
-{
- pv->major = cpu_to_le16(pv->major);
- pv->minor = cpu_to_le16(pv->minor);
- pv->patch = cpu_to_le16(pv->patch);
- pv->flags = cpu_to_le16(pv->flags);
-}
-
-static void protocol_in(struct protocol *proto)
-{
- pv_in(&proto->dm_ver);
- pv_in(&proto->dr_ver);
-}
-
-static void protocol_out(struct protocol *proto)
-{
- pv_out(&proto->dm_ver);
- pv_out(&proto->dr_ver);
-}
-
-/* go through member list saved in last confchg, see if we have received a
- proto message from each */
-
-static int all_protocol_messages(void)
-{
- struct node_daemon *node;
- int i;
-
- if (!daemon_member_count)
- return 0;
-
- for (i = 0; i < daemon_member_count; i++) {
- node = get_node_daemon(daemon_member[i].nodeid);
- if (!node) {
- log_error("all_protocol_messages no node %d",
- daemon_member[i].nodeid);
- return 0;
- }
-
- if (!node->proto.daemon_max[0])
- return 0;
- }
- return 1;
-}
-
-static int pick_min_protocol(struct protocol *proto)
-{
- uint16_t mind[4];
- struct node_daemon *node;
- int i;
-
- memset(&mind, 0, sizeof(mind));
-
- /* first choose the minimum major */
-
- for (i = 0; i < daemon_member_count; i++) {
- node = get_node_daemon(daemon_member[i].nodeid);
- if (!node) {
- log_error("pick_min_protocol no node %d",
- daemon_member[i].nodeid);
- return -1;
- }
-
- if (!mind[0] || node->proto.daemon_max[0] < mind[0])
- mind[0] = node->proto.daemon_max[0];
- }
-
- if (!mind[0]) {
- log_error("pick_min_protocol zero major number");
- return -1;
- }
-
- /* second pick the minimum minor with the chosen major */
-
- for (i = 0; i < daemon_member_count; i++) {
- node = get_node_daemon(daemon_member[i].nodeid);
- if (!node)
- continue;
-
- if (mind[0] == node->proto.daemon_max[0]) {
- if (!mind[1] || node->proto.daemon_max[1] < mind[1])
- mind[1] = node->proto.daemon_max[1];
- }
- }
-
- if (!mind[1]) {
- log_error("pick_min_protocol zero minor number");
- return -1;
- }
-
- /* third pick the minimum patch with the chosen major.minor */
-
- for (i = 0; i < daemon_member_count; i++) {
- node = get_node_daemon(daemon_member[i].nodeid);
- if (!node)
- continue;
-
- if (mind[0] == node->proto.daemon_max[0] &&
- mind[1] == node->proto.daemon_max[1]) {
- if (!mind[2] || node->proto.daemon_max[2] < mind[2])
- mind[2] = node->proto.daemon_max[2];
- }
- }
-
- if (!mind[2]) {
- log_error("pick_min_protocol zero patch number");
- return -1;
- }
-
- memcpy(&proto->daemon_run, &mind, sizeof(mind));
- return 0;
-}
-
-static void receive_protocol(struct fd_header *hd, int len)
-{
- struct protocol *p;
- struct node_daemon *node;
-
- p = (struct protocol *)((char *)hd + sizeof(struct fd_header));
- protocol_in(p);
-
- if (len < sizeof(struct fd_header) + sizeof(struct protocol)) {
- log_error("receive_protocol invalid len %d from %d",
- len, hd->nodeid);
- return;
- }
-
- /* zero is an invalid version value */
-
- if (!p->daemon_max[0] || !p->daemon_max[1] || !p->daemon_max[2]) {
- log_error("receive_protocol invalid max value from %d "
- "daemon %u.%u.%u", hd->nodeid,
- p->daemon_max[0], p->daemon_max[1], p->daemon_max[2]);
- return;
- }
-
- /* the run values will be zero until a version is set, after
- which none of the run values can be zero */
-
- if (p->daemon_run[0] && (!p->daemon_run[1] || !p->daemon_run[2])) {
- log_error("receive_protocol invalid run value from %d "
- "daemon %u.%u.%u", hd->nodeid,
- p->daemon_run[0], p->daemon_run[1], p->daemon_run[2]);
- return;
- }
-
- /* save this node's proto so we can tell when we've got all, and
- use it to select a minimum protocol from all */
-
- node = get_node_daemon(hd->nodeid);
- if (!node) {
- log_error("receive_protocol no node %d", hd->nodeid);
- return;
- }
-
- if (!node->is_member) {
- log_error("receive_protocol node %d not member", hd->nodeid);
- return;
- }
-
- log_debug("receive_protocol from %d max %u.%u.%u.%x run %u.%u.%u.%x",
- hd->nodeid,
- p->daemon_max[0], p->daemon_max[1],
- p->daemon_max[2], p->daemon_max[3],
- p->daemon_run[0], p->daemon_run[1],
- p->daemon_run[2], p->daemon_run[3]);
- log_debug("daemon node %d max %u.%u.%u.%x run %u.%u.%u.%x",
- hd->nodeid,
- node->proto.daemon_max[0], node->proto.daemon_max[1],
- node->proto.daemon_max[2], node->proto.daemon_max[3],
- node->proto.daemon_run[0], node->proto.daemon_run[1],
- node->proto.daemon_run[2], node->proto.daemon_run[3]);
- log_debug("daemon node %d join %llu left %llu local quorum %llu",
- hd->nodeid,
- (unsigned long long)node->join_time,
- (unsigned long long)node->left_time,
- (unsigned long long)quorate_time);
-
- /* checking zero node->daemon_max[0] is a way to tell if we've received
- an acceptable (non-stateful) proto message from the node since we
- saw it join the daemon cpg */
-
- if (hd->nodeid != our_nodeid &&
- !node->proto.daemon_max[0] &&
- (p->dr_ver.flags & PV_STATEFUL) &&
- (our_protocol.dr_ver.flags & PV_STATEFUL)) {
-
- log_debug("daemon node %d stateful merge", hd->nodeid);
-
- if (cluster_quorate && node->left_time &&
- quorate_time < node->left_time) {
- log_debug("daemon node %d kill due to stateful merge",
- hd->nodeid);
- if (!node->killed)
- kick_node_from_cluster(hd->nodeid);
- node->killed = 1;
- }
-
- /* don't save p->proto into node->proto; we need to come
- through here based on zero daemon_max[0] for other proto
- messages like this one from the same node */
-
- return;
- }
-
- memcpy(&node->proto, p, sizeof(struct protocol));
-
- /* if we have zero run values, and this msg has non-zero run values,
- then adopt them as ours; otherwise save this proto message */
-
- if (our_protocol.daemon_run[0])
- return;
-
- if (p->daemon_run[0]) {
- our_protocol.daemon_run[0] = p->daemon_run[0];
- our_protocol.daemon_run[1] = p->daemon_run[1];
- our_protocol.daemon_run[2] = p->daemon_run[2];
- log_debug("run protocol from nodeid %d", hd->nodeid);
- }
-}
-
-static void send_protocol(struct protocol *proto)
-{
- struct fd_header *hd;
- struct protocol *pr;
- char *buf;
- int len;
-
- len = sizeof(struct fd_header) + sizeof(struct protocol);
- buf = malloc(len);
- if (!buf) {
- log_error("send_protocol no mem %d", len);
- return;
- }
- memset(buf, 0, len);
-
- hd = (struct fd_header *)buf;
- pr = (struct protocol *)(buf + sizeof(*hd));
-
- hd->type = cpu_to_le16(FD_MSG_PROTOCOL);
- hd->nodeid = cpu_to_le32(our_nodeid);
-
- memcpy(pr, proto, sizeof(struct protocol));
- protocol_out(pr);
-
- _send_message(cpg_handle_daemon, buf, len, FD_MSG_PROTOCOL);
-}
-
-int set_protocol(void)
-{
- struct protocol proto;
- struct pollfd pollfd;
- int sent_proposal = 0;
- int rv;
-
- memset(&pollfd, 0, sizeof(pollfd));
- pollfd.fd = cpg_fd_daemon;
- pollfd.events = POLLIN;
-
- while (1) {
- if (our_protocol.daemon_run[0])
- break;
-
- if (!sent_proposal && all_protocol_messages()) {
- /* propose a protocol; look through info from all
- nodes and pick the min and propose that */
-
- sent_proposal = 1;
-
- /* copy our max values */
- memcpy(&proto, &our_protocol, sizeof(struct protocol));
-
- rv = pick_min_protocol(&proto);
- if (rv < 0)
- return rv;
-
- log_debug("set_protocol member_count %d propose "
- "daemon %u.%u.%u", daemon_member_count,
- proto.daemon_run[0], proto.daemon_run[1],
- proto.daemon_run[2]);
-
- send_protocol(&proto);
- }
-
- /* only process messages/events from daemon cpg until protocol
- is established */
-
- rv = poll(&pollfd, 1, -1);
- if (rv == -1 && errno == EINTR) {
- if (daemon_quit)
- return -1;
- continue;
- }
- if (rv < 0) {
- log_error("set_protocol poll errno %d", errno);
- return -1;
- }
-
- if (pollfd.revents & POLLIN)
- process_cpg_daemon(0);
- if (pollfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
- log_error("set_protocol poll revents %u",
- pollfd.revents);
- return -1;
- }
- }
-
- if (our_protocol.daemon_run[0] != our_protocol.daemon_max[0] ||
- our_protocol.daemon_run[1] > our_protocol.daemon_max[1]) {
- log_error("incompatible daemon protocol run %u.%u.%u max %u.%u.%u",
- our_protocol.daemon_run[0],
- our_protocol.daemon_run[1],
- our_protocol.daemon_run[2],
- our_protocol.daemon_max[0],
- our_protocol.daemon_max[1],
- our_protocol.daemon_max[2]);
- return -1;
- }
-
- log_debug("daemon run %u.%u.%u max %u.%u.%u",
- our_protocol.daemon_run[0],
- our_protocol.daemon_run[1],
- our_protocol.daemon_run[2],
- our_protocol.daemon_max[0],
- our_protocol.daemon_max[1],
- our_protocol.daemon_max[2]);
-
- send_protocol(&our_protocol);
- return 0;
-}
-
-/* process_cpg_daemon(), setup_cpg_daemon(), close_cpg_daemon() are for the
- "daemon" cpg which tracks the presence of other daemons; it's not the
- fence domain cpg. Joining this cpg tells others that we don't have
- uncontrolled dlm/gfs kernel state and they can skip fencing us if we're
- a victim. (We have to check for that uncontrolled state before calling
- setup_cpg_daemon, obviously.) */
-
-static void deliver_cb_daemon(cpg_handle_t handle,
- const struct cpg_name *group_name,
- uint32_t nodeid, uint32_t pid,
- void *data, size_t len)
-{
- struct fd_header *hd;
-
- if (len < sizeof(*hd)) {
- log_error("deliver_cb short message %zd", len);
- return;
- }
-
- hd = (struct fd_header *)data;
- fd_header_in(hd);
-
- switch (hd->type) {
- case FD_MSG_PROTOCOL:
- receive_protocol(hd, len);
- break;
- default:
- log_error("deliver_cb_daemon unknown msg type %d", hd->type);
- }
-}
-
-static int in_daemon_member_list(int nodeid)
-{
- int i;
-
- for (i = 0; i < daemon_member_count; i++) {
- if (daemon_member[i].nodeid == nodeid)
- return 1;
- }
- return 0;
-}
-
-static void confchg_cb_daemon(cpg_handle_t handle,
- const struct cpg_name *group_name,
- const struct cpg_address *member_list,
- size_t member_list_entries,
- const struct cpg_address *left_list,
- size_t left_list_entries,
- const struct cpg_address *joined_list,
- size_t joined_list_entries)
-{
- struct node_daemon *node;
- int i;
-
- log_config(group_name, member_list, member_list_entries,
- left_list, left_list_entries,
- joined_list, joined_list_entries);
-
- if (joined_list_entries)
- send_protocol(&our_protocol);
-
- memset(&daemon_member, 0, sizeof(daemon_member));
- daemon_member_count = member_list_entries;
-
- for (i = 0; i < member_list_entries; i++) {
- daemon_member[i] = member_list[i];
- /* add struct for nodes we've not seen before */
- add_node_daemon(member_list[i].nodeid);
- }
-
- list_for_each_entry(node, &daemon_nodes, list) {
- if (in_daemon_member_list(node->nodeid)) {
- if (node->is_member)
- continue;
-
- /* node joined daemon cpg */
- node->is_member = 1;
- node->join_time = time(NULL);
- } else {
- if (!node->is_member)
- continue;
-
- /* node left daemon cpg */
- node->is_member = 0;
- node->killed = 0;
- memset(&node->proto, 0, sizeof(struct protocol));
- node->left_time = time(NULL);
- }
- }
-}
-
-static void totem_cb_daemon(cpg_handle_t handle,
- struct cpg_ring_id ring_id,
- uint32_t member_list_entries,
- const uint32_t *member_list)
-{
- log_ringid(handle, &ring_id, member_list, member_list_entries);
-}
-
-static cpg_model_v1_data_t cpg_callbacks_daemon = {
- .cpg_deliver_fn = deliver_cb_daemon,
- .cpg_confchg_fn = confchg_cb_daemon,
- .cpg_totem_confchg_fn = totem_cb_daemon,
- .flags = CPG_MODEL_V1_DELIVER_INITIAL_TOTEM_CONF,
-};
-
-void process_cpg_daemon(int ci)
-{
- cpg_error_t error;
-
- error = cpg_dispatch(cpg_handle_daemon, CPG_DISPATCH_ALL);
- if (error != CPG_OK)
- log_error("daemon cpg_dispatch error %d", error);
-}
-
-/* For a new properly started node, it will join the daemon cpg then send a
- proto message indicating it's not stateful. For a node merged after a
- partition, it will join the daemon cpg and then send a proto message
- indicating it's stateful. To skip fencing a node we need to know it's
- joining after starting cleanly, so we need to see the daemon cpg joined
- followed by a proto message without the STATEFUL flag. */
-
-int is_clean_daemon_member(int nodeid)
-{
- struct node_daemon *node;
-
- /* process confchg's and protocol messages for daemon cpg,
- need to dispatch here because this is called from fence_victims()
- outside the poll() loop */
-
- cpg_dispatch(cpg_handle_daemon, CPG_DISPATCH_ALL);
-
- node = get_node_daemon(nodeid);
- if (node && node->is_member) {
- /* have we received a non-stateful proto message from it?
- if so then daemon_max[0] will be non-zero */
- if (node->proto.daemon_max[0]) {
- /* assert !(node->proto.dr_ver.flags & PV_STATEFUL) ? */
- log_debug("daemon_member %d is clean", nodeid);
- return 1;
- } else {
- log_debug("daemon_member %d zero proto", nodeid);
- return 0;
- }
- }
- /* log_debug("daemon_member %d not member", nodeid); */
- return 0;
-}
-
-int setup_cpg_daemon(void)
-{
- cpg_error_t error;
- struct cpg_name name;
- int i = 0;
-
- INIT_LIST_HEAD(&daemon_nodes);
-
- memset(&our_protocol, 0, sizeof(our_protocol));
- our_protocol.daemon_max[0] = 1;
- our_protocol.daemon_max[1] = 1;
- our_protocol.daemon_max[2] = 1;
-
- error = cpg_model_initialize(&cpg_handle_daemon, CPG_MODEL_V1,
- (cpg_model_data_t *)&cpg_callbacks_daemon,
- NULL);
- if (error != CPG_OK) {
- log_error("daemon cpg_model_initialize error %d", error);
- goto ret;
- }
-
- cpg_fd_get(cpg_handle_daemon, &cpg_fd_daemon);
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "fenced:daemon");
- name.length = strlen(name.value) + 1;
- memcpy(&group_name_daemon, &name, sizeof(struct cpg_name));
-
- log_debug("cpg_join %s ...", name.value);
- retry:
- error = cpg_join(cpg_handle_daemon, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- sleep(1);
- if (!(++i % 10))
- log_error("daemon cpg_join error retrying");
- goto retry;
- }
- if (error != CPG_OK) {
- log_error("daemon cpg_join error %d", error);
- goto fail;
- }
-
- log_debug("setup_cpg_daemon %d", cpg_fd_daemon);
- return cpg_fd_daemon;
-
- fail:
- cpg_finalize(cpg_handle_daemon);
- ret:
- return -1;
-}
-
-void close_cpg_daemon(void)
-{
- struct fd *fd;
- cpg_error_t error;
- struct cpg_name name;
- int i = 0;
-
- if (!cpg_handle_daemon)
- return;
- if (cluster_down)
- goto fin;
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "fenced:daemon");
- name.length = strlen(name.value) + 1;
-
- log_debug("cpg_leave %s ...", name.value);
- retry:
- error = cpg_leave(cpg_handle_daemon, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- sleep(1);
- if (!(++i % 10))
- log_error("daemon cpg_leave error retrying");
- goto retry;
- }
- if (error != CPG_OK)
- log_error("daemon cpg_leave error %d", error);
- fin:
- list_for_each_entry(fd, &domains, list) {
- if (fd->cpg_handle)
- cpg_finalize(fd->cpg_handle);
- }
- cpg_finalize(cpg_handle_daemon);
-}
-
-int set_node_info(struct fd *fd, int nodeid, struct fenced_node *nodeinfo)
-{
- struct node_history *node;
- struct member *memb;
- struct change *cg;
-
- nodeinfo->nodeid = nodeid;
- nodeinfo->victim = is_victim(fd, nodeid);
-
- if (list_empty(&fd->changes))
- cg = fd->started_change;
- else
- cg = list_first_entry(&fd->changes, struct change, list);
-
- if (cg) {
- memb = find_memb(cg, nodeid);
- if (memb)
- nodeinfo->member = memb->disallowed ? -1 : 1;
- }
-
- node = get_node_history(fd, nodeid);
- if (node) {
- nodeinfo->last_fenced_master = node->fence_master;
- nodeinfo->last_fenced_how = node->fence_how;
- nodeinfo->last_fenced_time = node->fence_time_local;
- }
-
- return 0;
-}
-
-int set_domain_info(struct fd *fd, struct fenced_domain *domain)
-{
- struct change *cg;
-
- if (list_empty(&fd->changes)) {
- if (fd->started_change)
- domain->member_count = fd->started_change->member_count;
- } else {
- cg = list_first_entry(&fd->changes, struct change, list);
- domain->member_count = cg->member_count;
- domain->state = cg->state;
- }
-
- domain->master_nodeid = fd->master;
- domain->victim_count = list_count(&fd->victims);
- domain->current_victim = fd->current_victim;
-
- return 0;
-}
-
-int set_domain_nodes(struct fd *fd, int option, int *node_count,
- struct fenced_node **nodes_out)
-{
- struct change *cg = fd->started_change;
- struct fenced_node *nodes = NULL, *n;
- struct node_history *nh;
- struct member *memb;
- int count = 0;
-
- if (option == FENCED_NODES_MEMBERS) {
- if (!cg)
- goto out;
- count = cg->member_count;
-
- nodes = malloc(count * sizeof(struct fenced_node));
- if (!nodes)
- return -ENOMEM;
- memset(nodes, 0, count * sizeof(struct fenced_node));
-
- n = nodes;
- list_for_each_entry(memb, &cg->members, list)
- set_node_info(fd, memb->nodeid, n++);
- }
-
- else if (option == FENCED_NODES_ALL) {
- list_for_each_entry(nh, &fd->node_history, list)
- count++;
-
- nodes = malloc(count * sizeof(struct fenced_node));
- if (!nodes)
- return -ENOMEM;
- memset(nodes, 0, count * sizeof(struct fenced_node));
-
- n = nodes;
- list_for_each_entry(nh, &fd->node_history, list)
- set_node_info(fd, nh->nodeid, n++);
- }
- out:
- *node_count = count;
- *nodes_out = nodes;
- return 0;
-}
-
diff --git a/fence/fenced/dbus.c b/fence/fenced/dbus.c
deleted file mode 100644
index 9d7be2f..0000000
--- a/fence/fenced/dbus.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include "fd.h"
-#include "config.h"
-
-#ifdef DBUS
-#include <dbus/dbus.h>
-
-#define DBUS_FENCE_NAME "com.redhat.cluster.fence"
-#define DBUS_FENCE_IFACE "com.redhat.cluster.fence"
-#define DBUS_FENCE_PATH "/com/redhat/cluster/fence"
-
-static DBusConnection *bus = NULL;
-
-void fd_dbus_init(void)
-{
- if (!(bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL))) {
- log_debug("failed to get dbus connection");
- } else {
- log_debug("connected to dbus %s", dbus_bus_get_unique_name(bus));
- }
-}
-
-void fd_dbus_exit(void)
-{
- if (bus) {
- dbus_connection_close(bus);
- dbus_connection_unref(bus);
- }
- bus = NULL;
-}
-
-void fd_dbus_send(const char *nodename, int nodeid, int result)
-{
- DBusMessage *msg = NULL;
-
- if (bus && !dbus_connection_read_write(bus, 1)) {
- log_debug("disconnected from dbus");
- fd_dbus_exit();
- }
-
- if (!bus) {
- fd_dbus_init();
- }
-
- if (!bus) {
- goto out;
- }
-
- if (!(msg = dbus_message_new_signal(DBUS_FENCE_PATH,
- DBUS_FENCE_IFACE,
- "FenceNode"))) {
- log_error("failed to create dbus signal");
- goto out;
- }
-
- if (!dbus_message_append_args(msg,
- DBUS_TYPE_STRING, &nodename,
- DBUS_TYPE_INT32, &nodeid,
- DBUS_TYPE_INT32, &result,
- DBUS_TYPE_INVALID)) {
- log_error("failed to append args to dbus signal");
- goto out;
- }
-
- dbus_connection_send(bus, msg, NULL);
- dbus_connection_flush(bus);
-
-out:
- if (msg) {
- dbus_message_unref(msg);
- }
-}
-
-#else
-
-void fd_dbus_init(void)
-{
-}
-
-void fd_dbus_exit(void)
-{
-}
-
-void fd_dbus_send(const char *nodename, int nodeid, int result)
-{
-}
-
-#endif /* DBUS */
diff --git a/fence/fenced/fd.h b/fence/fenced/fd.h
deleted file mode 100644
index 34a6c7f..0000000
--- a/fence/fenced/fd.h
+++ /dev/null
@@ -1,299 +0,0 @@
-#ifndef __FD_DOT_H__
-#define __FD_DOT_H__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <signal.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <stdint.h>
-#include <time.h>
-#include <sched.h>
-#include <limits.h>
-#include <dirent.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/poll.h>
-#include <sys/select.h>
-#include <sys/time.h>
-#include <sys/file.h>
-
-#include <openais/saAis.h>
-#include <corosync/cpg.h>
-#include <liblogthread.h>
-
-#include "list.h"
-#include "linux_endian.h"
-#include "libfence.h"
-#include "libfenced.h"
-#include "fenced.h"
-
-/* Max name length for a group, pointless since we only ever create the
- "default" group. Regardless, set arbitrary max to match dlm's
- DLM_LOCKSPACE_LEN 64. The libcpg limit is larger at 128; we prefix
- the fence domain name with "fenced:" to create the cpg name. */
-
-#define MAX_GROUPNAME_LEN 64
-
-/* Max name length for a node. This should match libcman's
- CMAN_MAX_NODENAME_LEN which is 255. */
-
-#define MAX_NODENAME_LEN 255
-
-/* Maximum members of the fence domain, or cluster. Should match
- CPG_MEMBERS_MAX in openais/cpg.h. */
-
-#define MAX_NODES 128
-
-/* Max string length printed on a line, for debugging/dump output. */
-
-#define MAXLINE 256
-
-/* group_mode */
-
-#define GROUP_LIBGROUP 2
-#define GROUP_LIBCPG 3
-
-extern int daemon_debug_opt;
-extern int daemon_quit;
-extern int cluster_down;
-extern struct list_head domains;
-extern int cluster_quorate;
-extern int cluster_quorate_from_last_update;
-extern uint32_t cluster_ringid_seq;
-extern uint64_t quorate_time;
-extern int our_nodeid;
-extern char our_name[MAX_NODENAME_LEN+1];
-extern char daemon_debug_buf[256];
-extern char dump_buf[FENCED_DUMP_SIZE];
-extern int dump_point;
-extern int dump_wrap;
-extern int group_mode;
-extern int two_node_mode;
-
-extern void daemon_dump_save(void);
-
-#define log_level(lvl, fmt, args...) \
-do { \
- snprintf(daemon_debug_buf, 255, "%ld " fmt "\n", time(NULL), ##args); \
- daemon_dump_save(); \
- logt_print(lvl, fmt "\n", ##args); \
- if (daemon_debug_opt) \
- fprintf(stderr, "%s", daemon_debug_buf); \
-} while (0)
-
-#define log_debug(fmt, args...) log_level(LOG_DEBUG, fmt, ##args)
-#define log_error(fmt, args...) log_level(LOG_ERR, fmt, ##args)
-
-#define FD_MSG_PROTOCOL 1
-#define FD_MSG_START 2
-#define FD_MSG_VICTIM_DONE 3
-#define FD_MSG_COMPLETE 4
-#define FD_MSG_EXTERNAL 5
-
-#define FD_MFLG_JOINING 1 /* accompanies start, we are joining */
-#define FD_MFLG_COMPLETE 2 /* accompanies start, we have complete info */
-#define FD_MFLG_DUPLICATE_CG 4
-
-struct fd_header {
- uint16_t version[3];
- uint16_t type; /* FD_MSG_ */
- uint32_t nodeid; /* sender */
- uint32_t to_nodeid; /* recipient, 0 for all */
- uint32_t global_id; /* global unique id for this domain */
- uint32_t flags; /* FD_MFLG_ */
- uint32_t msgdata; /* in-header payload depends on MSG type */
- uint32_t pad1;
- uint64_t pad2;
-};
-
-#define CGST_WAIT_CONDITIONS 1
-#define CGST_WAIT_MESSAGES 2
-#define CGST_WAIT_FENCING 3 /* for queries */
-
-struct change {
- struct list_head list;
- struct list_head members;
- struct list_head removed; /* nodes removed by this change */
- int member_count;
- int joined_count;
- int remove_count;
- int failed_count;
- int state; /* CGST_ */
- int we_joined;
- int sent_start;
- uint32_t seq; /* just used as a reference when debugging */
- uint64_t create_time;
-};
-
-#define VIC_DONE_AGENT 1
-#define VIC_DONE_MEMBER 2
-#define VIC_DONE_OVERRIDE 3
-#define VIC_DONE_EXTERNAL 4
-
-struct node_history {
- struct list_head list;
- int nodeid;
- int check_quorum;
- uint64_t add_time;
- uint64_t left_time;
- uint64_t fail_time;
- uint64_t fence_time;
- uint64_t fence_time_local;
- uint64_t fence_external_time;
- uint64_t cluster_add_time;
- uint64_t cluster_remove_time;
- int fence_external_node;
- int fence_master;
- int fence_how; /* VIC_DONE_ */
- uint32_t last_match_seq;
- uint32_t fail_seq;
- uint32_t left_seq;
-};
-
-struct node {
- struct list_head list;
- int nodeid;
- int init_victim;
- int local_victim_done;
- char name[MAX_NODENAME_LEN+1];
-};
-
-struct fd {
- struct list_head list;
- char name[MAX_GROUPNAME_LEN+1];
-
- /* libcpg domain membership */
-
- cpg_handle_t cpg_handle;
- int cpg_client;
- int cpg_fd;
- uint32_t change_seq;
- uint32_t started_count;
- struct change *started_change;
- struct list_head changes;
- struct list_head node_history;
- int init_complete;
- int local_init_complete;
- struct cpg_ring_id cpg_ringid;
-
- /* general domain membership */
-
- int master;
- int joining_group;
- int leaving_group;
- int current_victim; /* for queries */
- struct list_head victims;
- struct list_head complete;
-
- /* libgroup domain membership */
-
- int last_stop;
- int last_start;
- int last_finish;
- int first_recovery;
- int prev_count;
- struct list_head prev;
- struct list_head leaving;
-};
-
-/* config.c */
-
-int setup_ccs(void);
-void close_ccs(void);
-void reread_ccs(void);
-void read_ccs_name(const char *path, char *name);
-void read_ccs_yesno(const char *path, int *yes, int *no);
-void read_ccs_int(const char *path, int *config_val);
-int read_ccs(struct fd *fd);
-
-/* cpg.c */
-
-void process_cpg_daemon(int ci);
-int setup_cpg_daemon(void);
-void close_cpg_daemon(void);
-int set_protocol(void);
-void free_cg(struct change *cg);
-void node_history_init(struct fd *fd, int nodeid);
-void node_history_fence(struct fd *fd, int victim, int master, int how,
- uint64_t mastertime);
-void send_external(struct fd *fd, int victim);
-int is_fenced_external(struct fd *fd, int nodeid);
-void send_victim_done(struct fd *fd, int victim);
-void process_fd_changes(void);
-int fd_join(struct fd *fd);
-int fd_leave(struct fd *fd);
-int set_node_info(struct fd *fd, int nodeid, struct fenced_node *node);
-int set_domain_info(struct fd *fd, struct fenced_domain *domain);
-int set_domain_nodes(struct fd *fd, int option, int *node_count,
- struct fenced_node **nodes);
-int is_clean_daemon_member(int nodeid);
-void node_history_cluster_add(int nodeid);
-void node_history_cluster_remove(int nodeid);
-
-/* group.c */
-
-void process_groupd(int ci);
-int setup_groupd(void);
-void close_groupd(void);
-int fd_join_group(struct fd *fd);
-int fd_leave_group(struct fd *fd);
-int set_node_info_group(struct fd *fd, int nodeid, struct fenced_node *node);
-int set_domain_info_group(struct fd *fd, struct fenced_domain *domain);
-int set_domain_nodes_group(struct fd *fd, int option, int *node_count,
- struct fenced_node **nodes);
-int set_group_mode(void);
-
-/* main.c */
-
-void client_dead(int ci);
-int client_add(int fd, void (*workfn)(int ci), void (*deadfn)(int ci));
-void free_fd(struct fd *fd);
-struct fd *find_fd(char *name);
-void query_lock(void);
-void query_unlock(void);
-void cluster_dead(int ci);
-
-/* member_cman.c */
-
-void process_cluster(int ci);
-int setup_cluster(void);
-void close_cluster(void);
-int is_cluster_member_reread(int nodeid);
-char *nodeid_to_name(int nodeid);
-int name_to_nodeid(char *name);
-struct node *get_new_node(struct fd *fd, int nodeid);
-void kick_node_from_cluster(int nodeid);
-void set_cman_dirty(void);
-int get_cman_fd(void);
-
-/* recover.c */
-
-void free_node_list(struct list_head *head);
-void add_complete_node(struct fd *fd, int nodeid);
-int list_count(struct list_head *head);
-int is_victim(struct fd *fd, int nodeid);
-void delay_fencing(struct fd *fd, int node_join);
-void defer_fencing(struct fd *fd);
-void fence_victims(struct fd *fd);
-
-/* logging.c */
-
-void init_logging(void);
-void setup_logging(void);
-void close_logging(void);
-
-/* dbus.c */
-
-void fd_dbus_init(void);
-void fd_dbus_exit(void);
-void fd_dbus_send(const char *nodename, int nodeid, int result);
-
-#endif /* __FD_DOT_H__ */
-
diff --git a/fence/fenced/fenced.h b/fence/fenced/fenced.h
deleted file mode 100644
index fb7d951..0000000
--- a/fence/fenced/fenced.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef __FENCED_DOT_H__
-#define __FENCED_DOT_H__
-
-/* This defines the interface between fenced and libfenced, and should
- only be used by libfenced. */
-
-/* should match the same in fd.h */
-#define MAX_NODENAME_LEN 255
-
-#define FENCED_SOCK_PATH "fenced_sock"
-#define FENCED_QUERY_SOCK_PATH "fenced_query_sock"
-
-#define FENCED_MAGIC 0x0FE11CED
-#define FENCED_VERSION 0x00010001
-
-#define FENCED_CMD_JOIN 1
-#define FENCED_CMD_LEAVE 2
-#define FENCED_CMD_DUMP_DEBUG 3
-#define FENCED_CMD_EXTERNAL 4
-#define FENCED_CMD_NODE_INFO 5
-#define FENCED_CMD_DOMAIN_INFO 6
-#define FENCED_CMD_DOMAIN_NODES 7
-
-struct fenced_header {
- unsigned int magic;
- unsigned int version;
- unsigned int command;
- unsigned int option;
- unsigned int len;
- int data; /* embedded command-specific data, for convenience */
- int unused1;
- int unsued2;
-};
-
-#endif
-
diff --git a/fence/fenced/group.c b/fence/fenced/group.c
deleted file mode 100644
index d9ddd4e..0000000
--- a/fence/fenced/group.c
+++ /dev/null
@@ -1,489 +0,0 @@
-#include "fd.h"
-#include "config.h"
-#include "libgroup.h"
-
-#define DO_STOP 1
-#define DO_START 2
-#define DO_FINISH 3
-#define DO_TERMINATE 4
-#define DO_SETID 5
-
-#define GROUPD_TIMEOUT 10 /* seconds */
-
-/* save all the params from callback functions here because we can't
- do the processing within the callback function itself */
-
-static group_handle_t gh;
-static int cb_action;
-static char cb_name[MAX_GROUPNAME_LEN+1];
-static int cb_event_nr;
-static int cb_id;
-static int cb_type;
-static int cb_member_count;
-static int cb_members[MAX_NODES];
-
-
-static void stop_cbfn(group_handle_t h, void *private, char *name)
-{
- cb_action = DO_STOP;
- strcpy(cb_name, name);
-}
-
-static void start_cbfn(group_handle_t h, void *private, char *name,
- int event_nr, int type, int member_count, int *members)
-{
- int i;
-
- cb_action = DO_START;
- strcpy(cb_name, name);
- cb_event_nr = event_nr;
- cb_type = type;
- cb_member_count = member_count;
-
- for (i = 0; i < member_count; i++)
- cb_members[i] = members[i];
-}
-
-static void finish_cbfn(group_handle_t h, void *private, char *name,
- int event_nr)
-{
- cb_action = DO_FINISH;
- strcpy(cb_name, name);
- cb_event_nr = event_nr;
-}
-
-static void terminate_cbfn(group_handle_t h, void *private, char *name)
-{
- cb_action = DO_TERMINATE;
- strcpy(cb_name, name);
-}
-
-static void setid_cbfn(group_handle_t h, void *private, char *name,
- int unsigned id)
-{
- cb_action = DO_SETID;
- strcpy(cb_name, name);
- cb_id = id;
-}
-
-group_callbacks_t callbacks = {
- stop_cbfn,
- start_cbfn,
- finish_cbfn,
- terminate_cbfn,
- setid_cbfn
-};
-
-static char *str_members(void)
-{
- static char mbuf[MAXLINE];
- int i, len = 0;
-
- memset(mbuf, 0, MAXLINE);
-
- for (i = 0; i < cb_member_count; i++)
- len += sprintf(mbuf+len, "%d ", cb_members[i]);
- return mbuf;
-}
-
-static int id_in_nodeids(int nodeid, int count, int *nodeids)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- if (nodeid == nodeids[i])
- return 1;
- }
- return 0;
-}
-
-static int next_complete_nodeid(struct fd *fd, int gt)
-{
- struct node *node;
- int low = -1;
-
- /* find lowest node id in fd_complete greater than gt,
- if none, return -1 */
-
- list_for_each_entry(node, &fd->complete, list) {
- if (node->nodeid <= gt)
- continue;
-
- if (low == -1)
- low = node->nodeid;
- else if (node->nodeid < low)
- low = node->nodeid;
- }
- return low;
-}
-
-static void set_master(struct fd *fd)
-{
- struct node *node;
- int low = -1;
-
- /* Find the lowest nodeid common to fd->fd_prev (newest member list)
- * and fd->fd_complete (last complete member list). */
-
- for (;;) {
- low = next_complete_nodeid(fd, low);
- if (low == -1)
- break;
-
- list_for_each_entry(node, &fd->prev, list) {
- if (low != node->nodeid)
- continue;
- goto out;
- }
- }
-
- /* Special case: we're the first and only FD member */
-
- if (fd->prev_count == 1)
- low = our_nodeid;
-
- /* We end up returning -1 when we're not the only node and we've just
- joined. Because we've just joined we weren't in the last complete
- domain group and won't be chosen as master. We defer to someone who
- _was_ in the last complete group. All we know is it isn't us. */
-
- out:
- fd->master = low;
-}
-
-static void new_prev_nodes(struct fd *fd, int member_count, int *nodeids)
-{
- struct node *node;
- int i;
-
- for (i = 0; i < member_count; i++) {
- node = get_new_node(fd, nodeids[i]);
- list_add(&node->list, &fd->prev);
- }
-
- fd->prev_count = member_count;
-}
-
-static void _add_first_victims(struct fd *fd)
-{
- struct node *prev_node, *safe;
-
- /* complete list initialised in init_nodes() to all nodes from ccs */
- if (list_empty(&fd->complete))
- log_debug("first complete list empty warning");
-
- list_for_each_entry_safe(prev_node, safe, &fd->complete, list) {
- if (!is_cluster_member_reread(prev_node->nodeid)) {
- list_del(&prev_node->list);
- list_add(&prev_node->list, &fd->victims);
- log_debug("add first victim %s", prev_node->name);
- prev_node->init_victim = 1;
- }
- }
-}
-
-static void _add_victims(struct fd *fd, int start_type, int member_count,
- int *nodeids)
-{
- struct node *node, *safe;
-
- /* nodes which haven't completed leaving when a failure restart happens
- * are dead (and need fencing) or are still members */
-
- if (start_type == GROUP_NODE_FAILED) {
- list_for_each_entry_safe(node, safe, &fd->leaving, list) {
- list_del(&node->list);
- if (id_in_nodeids(node->nodeid, member_count, nodeids))
- list_add(&node->list, &fd->complete);
- else {
- list_add(&node->list, &fd->victims);
- log_debug("add victim %u, was leaving",
- node->nodeid);
- }
- }
- }
-
- /* nodes in last completed group but missing from fr_nodeids are added
- * to victims list or leaving list, depending on the type of start. */
-
- if (list_empty(&fd->complete))
- log_debug("complete list empty warning");
-
- list_for_each_entry_safe(node, safe, &fd->complete, list) {
- if (!id_in_nodeids(node->nodeid, member_count, nodeids)) {
- list_del(&node->list);
-
- if (start_type == GROUP_NODE_FAILED)
- list_add(&node->list, &fd->victims);
- else
- list_add(&node->list, &fd->leaving);
-
- log_debug("add node %u to list %u", node->nodeid,
- start_type);
- }
- }
-}
-
-static void add_victims(struct fd *fd, int start_type, int member_count,
- int *nodeids)
-{
- /* Reset things when the last stop aborted our first
- * start, i.e. there was no finish; we got a
- * start/stop/start immediately upon joining. */
-
- if (!fd->last_finish && fd->last_stop) {
- log_debug("revert aborted first start");
- fd->last_stop = 0;
- fd->first_recovery = 0;
- free_node_list(&fd->prev);
- free_node_list(&fd->victims);
- free_node_list(&fd->leaving);
- }
-
- log_debug("add_victims stop %d start %d finish %d",
- fd->last_stop, fd->last_start, fd->last_finish);
-
- if (!fd->first_recovery) {
- fd->first_recovery = 1;
- _add_first_victims(fd);
- } else
- _add_victims(fd, start_type, member_count, nodeids);
-
- /* "prev" is just a temporary list of node structs matching the list of
- nodeids from the start; these nodes are moved to the "complete" list
- in the finish callback, and will be used to compare against the
- next set of started nodes */
-
- free_node_list(&fd->prev);
- new_prev_nodes(fd, member_count, nodeids);
-}
-
-static void clear_victims(struct fd *fd)
-{
- struct node *node, *safe;
-
- if (fd->last_finish == fd->last_start) {
- free_node_list(&fd->leaving);
- free_node_list(&fd->victims);
- }
-
- /* Save a copy of this set of nodes which constitutes the latest
- * complete group. Any of these nodes missing in the next start will
- * either be leaving or victims. For the next recovery, the lowest
- * remaining nodeid in this group will be the master. */
-
- free_node_list(&fd->complete);
- list_for_each_entry_safe(node, safe, &fd->prev, list) {
- list_del(&node->list);
- list_add(&node->list, &fd->complete);
- }
-}
-
-void process_groupd(int ci)
-{
- struct fd *fd;
- int error = -EINVAL;
-
- group_dispatch(gh);
-
- if (!cb_action)
- goto out;
-
- fd = find_fd(cb_name);
- if (!fd)
- goto out;
-
- switch (cb_action) {
- case DO_STOP:
- log_debug("stop %s", cb_name);
- fd->last_stop = fd->last_start;
- group_stop_done(gh, cb_name);
- break;
-
- case DO_START:
- log_debug("start %s %d members %s", cb_name, cb_event_nr,
- str_members());
- fd->last_start = cb_event_nr;
-
- /* we don't get a start callback until there's quorum */
-
- add_victims(fd, cb_type, cb_member_count, cb_members);
- set_master(fd);
- if (fd->master == our_nodeid) {
- delay_fencing(fd, cb_type == GROUP_NODE_JOIN);
- fence_victims(fd);
- } else {
- defer_fencing(fd);
- }
-
- group_start_done(gh, cb_name, cb_event_nr);
- fd->joining_group = 0;
- break;
-
- case DO_FINISH:
- log_debug("finish %s %d", cb_name, cb_event_nr);
- fd->last_finish = cb_event_nr;
-
- /* we get terminate callback when all have started, which means
- that the low node has successfully fenced all victims */
- clear_victims(fd);
-
- break;
-
- case DO_TERMINATE:
- log_debug("terminate %s", cb_name);
- if (!fd->leaving_group)
- log_error("process_groupd terminate not leaving");
- list_del(&fd->list);
- free_fd(fd);
- break;
-
- case DO_SETID:
- break;
- default:
- error = -EINVAL;
- }
-
- cb_action = 0;
- out:
- return;
-}
-
-int setup_groupd(void)
-{
- int rv;
-
- gh = group_init(NULL, "fence", 0, &callbacks, GROUPD_TIMEOUT);
- if (!gh) {
- log_error("group_init error %p %d", gh, errno);
- return -ENOTCONN;
- }
- rv = group_get_fd(gh);
- if (rv < 0)
- log_error("group_get_fd error %d %d", rv, errno);
- return rv;
-}
-
-void close_groupd(void)
-{
- group_exit(gh);
-}
-
-int fd_join_group(struct fd *fd)
-{
- int rv;
-
- list_add(&fd->list, &domains);
- fd->joining_group = 1;
-
- rv = group_join(gh, fd->name);
- if (rv) {
- log_error("group_join error %d", rv);
- list_del(&fd->list);
- free(fd);
- return rv;
- }
- set_cman_dirty();
- return 0;
-}
-
-int fd_leave_group(struct fd *fd)
-{
- int rv;
-
- fd->leaving_group = 1;
-
- rv = group_leave(gh, fd->name);
- if (rv)
- log_error("group_leave error %d", rv);
-
- return rv;
-}
-
-int set_node_info_group(struct fd *fd, int nodeid, struct fenced_node *nodeinfo)
-{
- nodeinfo->nodeid = nodeid;
- nodeinfo->victim = is_victim(fd, nodeid);
- nodeinfo->member = id_in_nodeids(nodeid, cb_member_count, cb_members);
-
- /* FIXME: we don't keep track of last_fenced_* in this libgroup code,
- maybe just leave it out */
-
- return 0;
-}
-
-int set_domain_info_group(struct fd *fd, struct fenced_domain *domain)
-{
- domain->master_nodeid = fd->master;
- domain->victim_count = list_count(&fd->victims);
- domain->member_count = cb_member_count;
- domain->state = cb_action;
- domain->current_victim = fd->current_victim;
- return 0;
-}
-
-int set_domain_nodes_group(struct fd *fd, int option, int *node_count,
- struct fenced_node **nodes_out)
-{
- struct fenced_node *nodes = NULL, *nodep;
- int i;
-
- if (!cb_member_count)
- goto out;
-
- nodes = malloc(cb_member_count * sizeof(struct fenced_node));
- if (!nodes)
- return -ENOMEM;
- memset(nodes, 0, sizeof(*nodes));
-
- nodep = nodes;
- for (i = 0; i < cb_member_count; i++) {
- set_node_info_group(fd, cb_members[i], nodep++);
- }
- out:
- *node_count = cb_member_count;
- *nodes_out = nodes;
- return 0;
-}
-
-int set_group_mode(void)
-{
- int i = 0, rv, version, limit;
-
- while (1) {
- rv = group_get_version(&version);
-
- if (rv || version < 0) {
- /* we expect to get version of -EAGAIN while groupd
- is detecting the mode of everyone; don't retry
- as long if we're not getting anything back from
- groupd */
-
- log_debug("set_group_mode get_version %d ver %d",
- rv, version);
-
- limit = (version == -EAGAIN) ? 30 : 5;
-
- if (i++ > limit) {
- log_error("cannot get groupd compatibility "
- "mode rv %d ver %d", rv, version);
- return -1;
- }
- sleep(1);
- continue;
- }
-
-
- if (version == GROUP_LIBGROUP) {
- group_mode = GROUP_LIBGROUP;
- return 0;
- } else if (version == GROUP_LIBCPG) {
- group_mode = GROUP_LIBCPG;
- return 0;
- } else {
- log_error("set_group_mode invalid ver %d", version);
- return -1;
- }
- }
-}
-
diff --git a/fence/fenced/logging.c b/fence/fenced/logging.c
deleted file mode 100644
index 56a7e08..0000000
--- a/fence/fenced/logging.c
+++ /dev/null
@@ -1,92 +0,0 @@
-#include "fd.h"
-#include "config.h"
-#include "ccs.h"
-
-extern int ccs_handle;
-
-#define DAEMON_NAME "fenced"
-#define DEFAULT_LOG_MODE LOG_MODE_OUTPUT_FILE|LOG_MODE_OUTPUT_SYSLOG
-#define DEFAULT_SYSLOG_FACILITY SYSLOGFACILITY
-#define DEFAULT_SYSLOG_PRIORITY SYSLOGLEVEL
-#define DEFAULT_LOGFILE_PRIORITY LOG_INFO /* ? */
-#define DEFAULT_LOGFILE LOGDIR "/" DAEMON_NAME ".log"
-
-static int log_mode;
-static int syslog_facility;
-static int syslog_priority;
-static int logfile_priority;
-static char logfile[PATH_MAX];
-
-void init_logging(void)
-{
- log_mode = DEFAULT_LOG_MODE;
- syslog_facility = DEFAULT_SYSLOG_FACILITY;
- syslog_priority = DEFAULT_SYSLOG_PRIORITY;
- logfile_priority = DEFAULT_LOGFILE_PRIORITY;
- strcpy(logfile, DEFAULT_LOGFILE);
-
- /* logfile_priority is the only one of these options that
- can be controlled from command line or environment variable */
-
- if (cfgd_debug_logfile)
- logfile_priority = LOG_DEBUG;
-
- log_debug("logging mode %d syslog f %d p %d logfile p %d %s",
- log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-
- logt_init(DAEMON_NAME, log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-}
-
-#define DEFAULT_LOGFILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
-
-void setup_logging(void)
-{
- struct stat buf;
- int rv;
-
- ccs_read_logging(ccs_handle, DAEMON_NAME,
- &cfgd_debug_logfile, &log_mode,
- &syslog_facility, &syslog_priority,
- &logfile_priority, logfile);
-
- log_debug("logging mode %d syslog f %d p %d logfile p %d %s",
- log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-
- logt_conf(DAEMON_NAME, log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-
- /*
- * Previously fenced.log was created with mode 666,
- * so fix it to be 644.
- */
-
- rv = stat(logfile, &buf);
- if (rv)
- return;
-
- log_debug("logfile cur mode %lo", (unsigned long)buf.st_mode);
-
- if ((buf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) == DEFAULT_LOGFILE_MODE)
- return;
-
- rv = chmod(logfile, DEFAULT_LOGFILE_MODE);
- if (rv) {
- log_error("chmod error %d", errno);
- return;
- }
-
- rv = stat(logfile, &buf);
- if (rv)
- return;
-
- log_debug("logfile new mode %lo", (unsigned long)buf.st_mode);
-}
-
-void close_logging(void)
-{
- logt_exit();
-}
-
diff --git a/fence/fenced/main.c b/fence/fenced/main.c
deleted file mode 100644
index 924b8c9..0000000
--- a/fence/fenced/main.c
+++ /dev/null
@@ -1,1105 +0,0 @@
-#include "fd.h"
-#include "config.h"
-#include <pthread.h>
-#include "copyright.cf"
-
-#define LOCKFILE_NAME "/var/run/fenced.pid"
-#define CLIENT_NALLOC 32
-
-static int client_maxi;
-static int client_size = 0;
-static struct client *client = NULL;
-static struct pollfd *pollfd = NULL;
-static pthread_t query_thread;
-static pthread_mutex_t query_mutex;
-static struct list_head controlled_entries;
-static char default_name[8];
-
-struct client {
- int fd;
- void *workfn;
- void *deadfn;
-};
-
-static int do_read(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- while (off < count) {
- rv = read(fd, (char *)buf + off, count - off);
- if (rv == 0)
- return -1;
- if (rv == -1 && errno == EINTR)
- continue;
- if (rv == -1)
- return -1;
- off += rv;
- }
- return 0;
-}
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, (char *)buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0) {
- return rv;
- }
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-static void client_alloc(void)
-{
- int i;
-
- if (!client) {
- client = malloc(CLIENT_NALLOC * sizeof(struct client));
- pollfd = malloc(CLIENT_NALLOC * sizeof(struct pollfd));
- } else {
- client = realloc(client, (client_size + CLIENT_NALLOC) *
- sizeof(struct client));
- pollfd = realloc(pollfd, (client_size + CLIENT_NALLOC) *
- sizeof(struct pollfd));
- if (!pollfd)
- log_error("can't alloc for pollfd");
- }
- if (!client || !pollfd)
- log_error("can't alloc for client array");
-
- for (i = client_size; i < client_size + CLIENT_NALLOC; i++) {
- client[i].workfn = NULL;
- client[i].deadfn = NULL;
- client[i].fd = -1;
- pollfd[i].fd = -1;
- pollfd[i].revents = 0;
- }
- client_size += CLIENT_NALLOC;
-}
-
-void client_dead(int ci)
-{
- close(client[ci].fd);
- client[ci].workfn = NULL;
- client[ci].fd = -1;
- pollfd[ci].fd = -1;
-}
-
-int client_add(int fd, void (*workfn)(int ci), void (*deadfn)(int ci))
-{
- int i;
-
- if (!client)
- client_alloc();
- again:
- for (i = 0; i < client_size; i++) {
- if (client[i].fd == -1) {
- client[i].workfn = workfn;
- if (deadfn)
- client[i].deadfn = deadfn;
- else
- client[i].deadfn = client_dead;
- client[i].fd = fd;
- pollfd[i].fd = fd;
- pollfd[i].events = POLLIN;
- if (i > client_maxi)
- client_maxi = i;
- return i;
- }
- }
-
- client_alloc();
- goto again;
-}
-
-static void sigterm_handler(int sig)
-{
- daemon_quit = 1;
-}
-
-static struct fd *create_fd(char *name)
-{
- struct fd *fd;
-
- if (strlen(name) > MAX_GROUPNAME_LEN)
- return NULL;
-
- fd = malloc(sizeof(struct fd));
- if (!fd)
- return NULL;
-
- memset(fd, 0, sizeof(struct fd));
- strcpy(fd->name, name);
-
- INIT_LIST_HEAD(&fd->changes);
- INIT_LIST_HEAD(&fd->node_history);
- INIT_LIST_HEAD(&fd->victims);
- INIT_LIST_HEAD(&fd->complete);
- INIT_LIST_HEAD(&fd->prev);
- INIT_LIST_HEAD(&fd->leaving);
-
- return fd;
-}
-
-void free_fd(struct fd *fd)
-{
- struct change *cg, *cg_safe;
- struct node_history *nodeh, *nodeh_safe;
-
- list_for_each_entry_safe(cg, cg_safe, &fd->changes, list) {
- list_del(&cg->list);
- free_cg(cg);
- }
- if (fd->started_change)
- free_cg(fd->started_change);
-
- list_for_each_entry_safe(nodeh, nodeh_safe, &fd->node_history, list) {
- list_del(&nodeh->list);
- free(nodeh);
- }
-
- free_node_list(&fd->victims);
- free_node_list(&fd->complete);
- free_node_list(&fd->prev);
- free_node_list(&fd->leaving);
-
- free(fd);
-}
-
-struct fd *find_fd(char *name)
-{
- struct fd *fd;
-
- list_for_each_entry(fd, &domains, list) {
- if (strlen(name) == strlen(fd->name) &&
- !strncmp(fd->name, name, strlen(name)))
- return fd;
- }
- return NULL;
-}
-
-/* We don't require cman dirty/disallowed to detect and handle cpg merges after
- a partition, because we already do that with started_count checks and our
- own disallowed flag. We also don't require cman dirty/disallowed to deal
- with correctly skipping victims that rejoin the cluster. If a victim
- joins the fenced:daemon cpg and sends a proto message without the STATEFUL
- flag, then we safely skip fencing it. This is what happens when the node
- starts cleanly. If a node is added back after a partition, we see it join
- the fenced:daemon cpg and it send a proto message with the STATEFUL flag set.
- In this case it remains a victim and we will continue with fencing it. */
-
-static int do_join(char *name)
-{
- struct fd *fd;
- int rv;
-
- fd = find_fd(name);
- if (fd) {
- log_debug("join error: domain %s exists", name);
- rv = -EEXIST;
- goto out;
- }
-
- fd = create_fd(name);
- if (!fd) {
- rv = -ENOMEM;
- goto out;
- }
-
- rv = read_ccs(fd);
- if (rv) {
- free(fd);
- goto out;
- }
-
- if (group_mode == GROUP_LIBGROUP)
- rv = fd_join_group(fd);
- else
- rv = fd_join(fd);
- out:
- return rv;
-}
-
-static int do_leave(char *name)
-{
- struct fd *fd;
- int rv;
-
- fd = find_fd(name);
- if (!fd)
- return -EINVAL;
-
- if (group_mode == GROUP_LIBGROUP)
- rv = fd_leave_group(fd);
- else
- rv = fd_leave(fd);
-
- return rv;
-}
-
-static int do_external(char *name, char *extra, int extra_len)
-{
- struct fd *fd;
- int rv = 0;
-
- fd = find_fd(name);
- if (!fd)
- return -EINVAL;
-
- if (group_mode == GROUP_LIBGROUP)
- rv = -ENOSYS;
- else
- send_external(fd, name_to_nodeid(extra));
-
- return rv;
-}
-
-static void init_header(struct fenced_header *h, int cmd, int result,
- int extra_len)
-{
- memset(h, 0, sizeof(struct fenced_header));
-
- h->magic = FENCED_MAGIC;
- h->version = FENCED_VERSION;
- h->len = sizeof(struct fenced_header) + extra_len;
- h->command = cmd;
- h->data = result;
-}
-
-/* combines a header and the data and sends it back to the client in
- a single do_write() call */
-
-static void do_reply(int f, int cmd, int result, char *buf, int buflen)
-{
- char *reply;
- int reply_len;
-
- reply_len = sizeof(struct fenced_header) + buflen;
- reply = malloc(reply_len);
- if (!reply)
- return;
- memset(reply, 0, reply_len);
-
- init_header((struct fenced_header *)reply, cmd, result, buflen);
-
- if (buf && buflen)
- memcpy(reply + sizeof(struct fenced_header), buf, buflen);
-
- do_write(f, reply, reply_len);
-
- free(reply);
-}
-
-static void query_dump_debug(int f)
-{
- struct fenced_header h;
- int extra_len;
- int len;
-
- /* in the case of dump_wrap, extra_len will go in two writes,
- first the log tail, then the log head */
- if (dump_wrap)
- extra_len = FENCED_DUMP_SIZE;
- else
- extra_len = dump_point;
-
- init_header(&h, FENCED_CMD_DUMP_DEBUG, 0, extra_len);
- do_write(f, &h, sizeof(h));
-
- if (dump_wrap) {
- len = FENCED_DUMP_SIZE - dump_point;
- do_write(f, dump_buf + dump_point, len);
- len = dump_point;
- } else
- len = dump_point;
-
- /* NUL terminate the debug string */
- dump_buf[dump_point] = '\0';
-
- do_write(f, dump_buf, len);
-}
-
-static void query_node_info(int f, int data_nodeid)
-{
- struct fd *fd;
- struct fenced_node node;
- int nodeid, rv;
-
- fd = find_fd(default_name);
- if (!fd) {
- rv = -ENOENT;
- goto out;
- }
-
- if (data_nodeid == FENCED_NODEID_US)
- nodeid = our_nodeid;
- else
- nodeid = data_nodeid;
-
- if (group_mode == GROUP_LIBGROUP)
- rv = set_node_info_group(fd, nodeid, &node);
- else
- rv = set_node_info(fd, nodeid, &node);
- out:
- do_reply(f, FENCED_CMD_NODE_INFO, rv, (char *)&node, sizeof(node));
-}
-
-static void query_domain_info(int f)
-{
- struct fd *fd;
- struct fenced_domain domain;
- int rv;
-
- fd = find_fd(default_name);
- if (!fd) {
- rv = -ENOENT;
- goto out;
- }
-
- memset(&domain, 0, sizeof(domain));
- domain.group_mode = group_mode;
-
- if (group_mode == GROUP_LIBGROUP)
- rv = set_domain_info_group(fd, &domain);
- else
- rv = set_domain_info(fd, &domain);
- out:
- do_reply(f, FENCED_CMD_DOMAIN_INFO, rv, (char *)&domain, sizeof(domain));
-}
-
-static void query_domain_nodes(int f, int option, int max)
-{
- struct fd *fd;
- int node_count = 0;
- struct fenced_node *nodes = NULL;
- int rv, result;
-
- fd = find_fd(default_name);
- if (!fd) {
- result = -ENOENT;
- node_count = 0;
- goto out;
- }
-
- if (group_mode == GROUP_LIBGROUP)
- rv = set_domain_nodes_group(fd, option, &node_count, &nodes);
- else
- rv = set_domain_nodes(fd, option, &node_count, &nodes);
-
- if (rv < 0) {
- result = rv;
- node_count = 0;
- goto out;
- }
-
- /* node_count is the number of structs copied/returned; the caller's
- max may be less than that, in which case we copy as many as they
- asked for and return -E2BIG */
-
- if (node_count > max) {
- result = -E2BIG;
- node_count = max;
- } else {
- result = node_count;
- }
- out:
- do_reply(f, FENCED_CMD_DOMAIN_NODES, result,
- (char *)nodes, node_count * sizeof(struct fenced_node));
-
- if (nodes)
- free(nodes);
-}
-
-static void process_connection(int ci)
-{
- struct fenced_header h;
- char *extra = NULL;
- int rv, extra_len;
-
-
- rv = do_read(client[ci].fd, &h, sizeof(h));
- if (rv < 0) {
- log_debug("connection %d read error %d", ci, rv);
- goto out;
- }
-
- if (h.magic != FENCED_MAGIC) {
- log_debug("connection %d magic error %x", ci, h.magic);
- goto out;
- }
-
- if ((h.version & 0xFFFF0000) != (FENCED_VERSION & 0xFFFF0000)) {
- log_debug("connection %d version error %x", ci, h.version);
- goto out;
- }
-
- if (h.len > sizeof(h)) {
- extra_len = h.len - sizeof(h);
- extra = malloc(extra_len);
- if (!extra) {
- log_error("process_connection no mem %d", extra_len);
- goto out;
- }
- memset(extra, 0, extra_len);
-
- rv = do_read(client[ci].fd, extra, extra_len);
- if (rv < 0) {
- log_debug("connection %d extra read error %d", ci, rv);
- goto out;
- }
- }
-
- switch (h.command) {
- case FENCED_CMD_JOIN:
- do_join(default_name);
- break;
- case FENCED_CMD_LEAVE:
- do_leave(default_name);
- break;
- case FENCED_CMD_EXTERNAL:
- do_external(default_name, extra, extra_len);
- break;
- case FENCED_CMD_DUMP_DEBUG:
- case FENCED_CMD_NODE_INFO:
- case FENCED_CMD_DOMAIN_INFO:
- case FENCED_CMD_DOMAIN_NODES:
- log_error("process_connection query on wrong socket");
- break;
- default:
- log_error("process_connection %d unknown command %d",
- ci, h.command);
- }
- out:
- if (extra)
- free(extra);
- client_dead(ci);
-}
-
-static void process_listener(int ci)
-{
- int fd, i;
-
- fd = accept(client[ci].fd, NULL, NULL);
- if (fd < 0) {
- log_error("process_listener: accept error %d %d", fd, errno);
- return;
- }
-
- i = client_add(fd, process_connection, NULL);
-
- log_debug("client connection %d fd %d", i, fd);
-}
-
-static int setup_listener(const char *sock_path)
-{
- struct sockaddr_un addr;
- socklen_t addrlen;
- int rv, s;
-
- /* we listen for new client connections on socket s */
-
- s = socket(AF_LOCAL, SOCK_STREAM, 0);
- if (s < 0) {
- log_error("socket error %d %d", s, errno);
- return s;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- strcpy(&addr.sun_path[1], sock_path);
- addrlen = sizeof(sa_family_t) + strlen(addr.sun_path+1) + 1;
-
- rv = bind(s, (struct sockaddr *) &addr, addrlen);
- if (rv < 0) {
- log_error("bind error %d %d", rv, errno);
- close(s);
- return rv;
- }
-
- rv = listen(s, 5);
- if (rv < 0) {
- log_error("listen error %d %d", rv, errno);
- close(s);
- return rv;
- }
- return s;
-}
-
-void query_lock(void)
-{
- pthread_mutex_lock(&query_mutex);
-}
-
-void query_unlock(void)
-{
- pthread_mutex_unlock(&query_mutex);
-}
-
-/* This is a thread, so we have to be careful, don't call log_ functions.
- We need a thread to process queries because the main thread will block
- for long periods when running fence agents. */
-
-static void *process_queries(void *arg)
-{
- struct fenced_header h;
- int f, rv, s;
-
- rv = setup_listener(FENCED_QUERY_SOCK_PATH);
- if (rv < 0)
- return NULL;
-
- s = rv;
-
- for (;;) {
- f = accept(s, NULL, NULL);
- if (f < 0)
- return NULL;
-
- rv = do_read(f, &h, sizeof(h));
- if (rv < 0) {
- goto out;
- }
-
- if (h.magic != FENCED_MAGIC) {
- goto out;
- }
-
- if ((h.version & 0xFFFF0000) != (FENCED_VERSION & 0xFFFF0000)) {
- goto out;
- }
-
- query_lock();
-
- switch (h.command) {
- case FENCED_CMD_DUMP_DEBUG:
- query_dump_debug(f);
- break;
- case FENCED_CMD_NODE_INFO:
- query_node_info(f, h.data);
- break;
- case FENCED_CMD_DOMAIN_INFO:
- query_domain_info(f);
- break;
- case FENCED_CMD_DOMAIN_NODES:
- query_domain_nodes(f, h.option, h.data);
- break;
- default:
- break;
- }
- query_unlock();
-
- out:
- close(f);
- }
-}
-
-static int setup_queries(void)
-{
- int rv;
-
- pthread_mutex_init(&query_mutex, NULL);
-
- rv = pthread_create(&query_thread, NULL, process_queries, NULL);
- if (rv < 0) {
- log_error("can't create query thread");
- return rv;
- }
- return 0;
-}
-
-struct controlled_entry {
- struct list_head list;
- char path[PATH_MAX+1];
-};
-
-static void register_controlled_dir(const char *path)
-{
- struct controlled_entry *ce;
-
- ce = malloc(sizeof(struct controlled_entry));
- if (!ce)
- return;
- memset(ce, 0, sizeof(struct controlled_entry));
- strncpy(ce->path, path, PATH_MAX);
- list_add(&ce->list, &controlled_entries);
-}
-
-static int ignore_nolock(char *sysfs_dir, char *table)
-{
- char path[PATH_MAX];
- char buf[32];
- int fd, rv;
-
- memset(path, 0, PATH_MAX);
-
- snprintf(path, PATH_MAX, "%s/%s/lock_module/proto_name",
- sysfs_dir, table);
-
- /* lock_nolock doesn't create the "lock_module" dir at all,
- so we'll fail to open this */
-
- fd = open(path, O_RDONLY);
- if (fd < 0)
- return 1;
-
- memset(buf, 0, sizeof(buf));
-
- rv = read(fd, buf, sizeof(buf));
- close(fd);
- if (rv < 0)
- return 1;
-
- if (!strncmp(buf, "lock_nolock", 11))
- return 1;
-
- return 0;
-}
-
-static int check_controlled_dir(char *path)
-{
- DIR *d;
- struct dirent *de;
- int count = 0;
-
- d = opendir(path);
- if (!d)
- return 0;
-
- while ((de = readdir(d))) {
- if (de->d_name[0] == '.')
- continue;
-
- if (strstr(path, "fs/gfs") && ignore_nolock(path, de->d_name))
- continue;
-
- log_error("found uncontrolled entry %s/%s", path, de->d_name);
- count++;
- }
- closedir(d);
-
- return count;
-}
-
-/* Joining the "fenced:daemon" cpg (in setup_cpg_daemon()) tells fenced on other
- nodes that we are in a "clean state", and don't need fencing. So, if
- we're a pending fence victim on another node, they'll skip fencing us
- once we start fenced and join the "daemon" cpg (it's not the fence domain
- cpg which we join when fence_tool join is run). This "daemon" cpg is just
- to notify others that we have no uncontrolled gfs/dlm objects.
- (Conceptually, we could use the fence domain cpg for this purpose instead,
- but that would require processing domain membership changes during
- fence_victims(), which would be a major change in the way the daemon works.)
-
- So, if we (the local node) are *not* in a clean state, we don't join the
- daemon cpg and we exit; we still need to be fenced. If we are starting
- up and find that instances of gfs/dlm in the kernel have been previously
- abandoned, that's an unclean, unreset state, and we still need fencing. */
-
-static int check_uncontrolled_entries(void)
-{
- struct controlled_entry *ce;
- int count = 0;
-
- list_for_each_entry(ce, &controlled_entries, list) {
- if (strncmp(ce->path, "-", 1))
- goto skip_default;
- }
-
- /* the default dirs to check */
- register_controlled_dir("/sys/kernel/dlm");
- register_controlled_dir("/sys/fs/gfs2");
- register_controlled_dir("/sys/fs/gfs");
-
- skip_default:
- list_for_each_entry(ce, &controlled_entries, list)
- count += check_controlled_dir(ce->path);
-
- if (count)
- return -1;
- return 0;
-}
-
-void cluster_dead(int ci)
-{
- if (!cluster_down)
- log_error("cluster is down, exiting");
- daemon_quit = 1;
- cluster_down = 1;
-}
-
-static void loop(void)
-{
- int rv, i;
- int cman_fd_pos;
- void (*workfn) (int ci);
- void (*deadfn) (int ci);
-
- rv = setup_queries();
- if (rv < 0)
- goto out;
-
- rv = setup_listener(FENCED_SOCK_PATH);
- if (rv < 0)
- goto out;
- client_add(rv, process_listener, NULL);
-
- rv = setup_cluster();
- if (rv < 0)
- goto out;
- cman_fd_pos = client_add(rv, process_cluster, cluster_dead);
-
- rv = setup_ccs();
- if (rv < 0)
- goto out;
-
- setup_logging();
-
- rv = check_uncontrolled_entries();
- if (rv < 0)
- goto out;
-
- rv = setup_cpg_daemon();
- if (rv < 0)
- goto out;
- client_add(rv, process_cpg_daemon, cluster_dead);
-
- group_mode = GROUP_LIBCPG;
-
- if (cfgd_groupd_compat) {
- rv = setup_groupd();
- if (rv < 0)
- goto out;
- client_add(rv, process_groupd, cluster_dead);
-
- switch (cfgd_groupd_compat) {
- case 1:
- group_mode = GROUP_LIBGROUP;
- rv = 0;
- break;
- case 2:
- rv = set_group_mode();
- break;
- default:
- log_error("inval groupd_compat %d", cfgd_groupd_compat);
- rv = -1;
- break;
- }
- if (rv < 0)
- goto out;
- }
- log_debug("group_mode %d compat %d", group_mode, cfgd_groupd_compat);
-
- if (group_mode == GROUP_LIBCPG) {
- rv = set_protocol();
- if (rv < 0)
- goto out;
- }
-
- for (;;) {
- /* We need to re-get the cman FD each time */
- pollfd[cman_fd_pos].fd = get_cman_fd();
- rv = poll(pollfd, client_maxi + 1, -1);
- if (rv == -1 && errno == EINTR) {
- if (daemon_quit && list_empty(&domains))
- goto out;
- daemon_quit = 0;
- continue;
- }
- if (rv < 0) {
- log_error("poll errno %d", errno);
- goto out;
- }
-
- query_lock();
-
- for (i = 0; i <= client_maxi; i++) {
- if (client[i].fd < 0)
- continue;
- if (pollfd[i].revents & POLLIN) {
- workfn = client[i].workfn;
- workfn(i);
- }
- if (pollfd[i].revents & (POLLERR | POLLHUP | POLLNVAL)) {
- deadfn = client[i].deadfn;
- deadfn(i);
- }
- }
- query_unlock();
-
- if (daemon_quit)
- break;
- }
- out:
- if (cfgd_groupd_compat)
- close_groupd();
- close_cpg_daemon();
- close_logging();
- close_ccs();
- close_cluster();
-
- if (!list_empty(&domains))
- log_error("domain abandoned");
-}
-
-static void lockfile(void)
-{
- int fd, error;
- struct flock lock;
- char buf[33];
-
- memset(buf, 0, 33);
-
- fd = open(LOCKFILE_NAME, O_CREAT|O_WRONLY,
- S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
- if (fd < 0) {
- 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, "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 print_usage(void)
-{
- printf("Usage:\n");
- printf("\n");
- printf("fenced [options]\n");
- printf("\n");
- printf("Options:\n");
- printf("\n");
- printf(" -D Enable debugging to stderr and don't fork\n");
- printf(" -L Enable debugging to log file\n");
- printf(" -g <num> groupd compatibility mode, 0 off, 1 on, 2 detect (default %d)\n", DEFAULT_GROUPD_COMPAT);
- printf(" 0: use libcpg, no backward compat, best performance\n");
- printf(" 1: use libgroup for compat with cluster2/rhel5\n");
- printf(" 2: use groupd to detect old, or mode 1, nodes that\n"
- " require compat, use libcpg if none found\n");
- printf(" -r <path> Register a directory that needs to be empty for\n");
- printf(" the daemon to start. \"-\" to skip default directories\n");
- printf(" /sys/fs/gfs, /sys/fs/gfs2, /sys/kernel/dlm\n");
- printf(" -c All nodes are in a clean state to start; do no startup fencing\n");
- printf(" -s Skip startup fencing of nodes with no defined fence methods\n");
- printf(" -j <secs> Post-join fencing delay (default %d)\n", DEFAULT_POST_JOIN_DELAY);
- printf(" -f <secs> Post-fail fencing delay (default %d)\n", DEFAULT_POST_FAIL_DELAY);
- printf(" -R <secs> Override time (default %d)\n", DEFAULT_OVERRIDE_TIME);
- printf(" -q Disable dbus signals\n");
- printf(" -O <path> Override path (default %s)\n", DEFAULT_OVERRIDE_PATH);
- printf(" -h Print this help, then exit\n");
- printf(" -V Print program version information, then exit\n");
- printf("\n");
- printf("Command line values override those in " DEFAULT_CONFIG_DIR "/" DEFAULT_CONFIG_FILE ".\n");
- printf("For an unbounded delay use <secs> value of -1.\n");
- printf("\n");
-}
-
-#define OPTION_STRING "Lg:cj:f:Dn:O:hVSse:r:q"
-
-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':
- daemon_debug_opt = 1;
- break;
-
- case 'L':
- optd_debug_logfile = 1;
- cfgd_debug_logfile = 1;
- break;
-
- case 'g':
- optd_groupd_compat = 1;
- cfgd_groupd_compat = atoi(optarg);
- break;
-
- case 'c':
- optd_clean_start = 1;
- cfgd_clean_start = 1;
- break;
-
- case 's':
- optd_skip_undefined = 1;
- cfgd_skip_undefined = 1;
- break;
-
- case 'j':
- optd_post_join_delay = 1;
- cfgd_post_join_delay = atoi(optarg);
- break;
-
- case 'f':
- optd_post_fail_delay = 1;
- cfgd_post_fail_delay = atoi(optarg);
- break;
-
- case 'R':
- optd_override_time = 1;
- cfgd_override_time = atoi(optarg);
- if (cfgd_override_time < 3)
- cfgd_override_time = 3;
- break;
-
- case 'O':
- optd_override_path = 1;
- cfgd_override_path = strdup(optarg);
- break;
-
- case 'q':
- optd_disable_dbus = 1;
- cfgd_disable_dbus = 1;
- break;
-
- case 'r':
- register_controlled_dir(optarg);
- break;
-
- case 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case 'V':
- printf("fenced %s (built %s %s)\n", RELEASE_VERSION,
- __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- break;
-
- case ':':
- case '?':
- fprintf(stderr, "Please use '-h' for usage.\n");
- exit(EXIT_FAILURE);
- break;
-
- case EOF:
- cont = 0;
- break;
-
- default:
- fprintf(stderr, "unknown option: %c", optchar);
- exit(EXIT_FAILURE);
- };
- }
-
- if (getenv("FENCED_DEBUG")) {
- optd_debug_logfile = 1;
- cfgd_debug_logfile = 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);
-}
-
-int main(int argc, char **argv)
-{
- INIT_LIST_HEAD(&domains);
- INIT_LIST_HEAD(&controlled_entries);
-
- strcpy(default_name, "default");
-
- read_arguments(argc, argv);
-
- if (!daemon_debug_opt) {
- if (daemon(0, 0) < 0) {
- perror("main: cannot fork");
- exit(EXIT_FAILURE);
- }
- }
- lockfile();
- init_logging();
- log_level(LOG_INFO, "fenced %s started", RELEASE_VERSION);
- signal(SIGTERM, sigterm_handler);
- set_oom_adj(-16);
-
- if (!cfgd_disable_dbus) {
- fd_dbus_init();
- }
-
- loop();
-
- fd_dbus_exit();
- unlink(LOCKFILE_NAME);
- return 0;
-}
-
-void daemon_dump_save(void)
-{
- int len, i;
-
- len = strlen(daemon_debug_buf);
-
- for (i = 0; i < len; i++) {
- dump_buf[dump_point++] = daemon_debug_buf[i];
-
- if (dump_point == FENCED_DUMP_SIZE) {
- dump_point = 0;
- dump_wrap = 1;
- }
- }
-}
-
-int daemon_debug_opt;
-int daemon_quit;
-int cluster_down;
-struct list_head domains;
-int cluster_quorate;
-int cluster_quorate_from_last_update;
-uint32_t cluster_ringid_seq;
-uint64_t quorate_time;
-int our_nodeid;
-char our_name[MAX_NODENAME_LEN+1];
-char daemon_debug_buf[256];
-char dump_buf[FENCED_DUMP_SIZE];
-int dump_point;
-int dump_wrap;
-int group_mode;
-int two_node_mode;
-
diff --git a/fence/fenced/member_cman.c b/fence/fenced/member_cman.c
deleted file mode 100644
index ced4272..0000000
--- a/fence/fenced/member_cman.c
+++ /dev/null
@@ -1,416 +0,0 @@
-#include "fd.h"
-#include "config.h"
-#include <arpa/inet.h>
-#include <libcman.h>
-
-#define BUFLEN MAX_NODENAME_LEN+1
-
-static cman_handle_t ch;
-static cman_handle_t ch_admin;
-static cman_node_t old_nodes[MAX_NODES];
-static int old_node_count;
-static cman_node_t cman_nodes[MAX_NODES];
-static int cman_node_count;
-
-int get_cman_fd(void)
-{
- return cman_get_fd(ch);
-}
-
-void set_cman_dirty(void)
-{
- int rv;
-
- rv = cman_set_dirty(ch_admin);
- if (rv)
- log_error("cman_set_dirty error %d", rv);
-}
-
-void kick_node_from_cluster(int nodeid)
-{
- if (!nodeid) {
- log_error("telling cman to shut down cluster locally");
- cman_shutdown(ch_admin, CMAN_SHUTDOWN_ANYWAY);
- } else {
-
- /* in a two_node cluster where both nodes maintain quorum
- * by themselves during a partition+merge, both will kick
- * the other, which can leave both dead and unfenced.
- * this delay should help */
-
- if (two_node_mode && our_nodeid > nodeid) {
- log_debug("kick_node_from_cluster %d delay", nodeid);
- sleep(5);
- }
-
- log_error("telling cman to remove nodeid %d from cluster",
- nodeid);
- cman_kill_node(ch_admin, nodeid);
- }
-}
-
-static cman_node_t *get_node(cman_node_t *node_list, int count, int nodeid)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- if (node_list[i].cn_nodeid == nodeid)
- return &node_list[i];
- }
- return NULL;
-}
-
-static int is_member(cman_node_t *node_list, int count, int nodeid)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- if (node_list[i].cn_nodeid == nodeid)
- return node_list[i].cn_member;
- }
- return 0;
-}
-
-static int is_old_member(int nodeid)
-{
- return is_member(old_nodes, old_node_count, nodeid);
-}
-
-static int is_cluster_member(int nodeid)
-{
- return is_member(cman_nodes, cman_node_count, nodeid);
-}
-
-static int name_equal(char *name1, char *name2)
-{
- char name3[BUFLEN], name4[BUFLEN];
- char addr1[INET6_ADDRSTRLEN];
- int i, len1, len2;
-
- len1 = strlen(name1);
- len2 = strlen(name2);
-
- if (len1 == len2 && !strncmp(name1, name2, len1))
- return 1;
-
- /*
- * If the names are IP addresses then don't compare
- * what is in front of the dots.
- */
- if (inet_pton(AF_INET, name1, addr1) == 0)
- return 0;
-
- if (inet_pton(AF_INET6, name1, addr1) == 0)
- return 0;
-
- memset(name3, 0, BUFLEN);
- memset(name4, 0, BUFLEN);
-
- for (i = 0; i < BUFLEN && i < len1; i++) {
- if (name1[i] != '.')
- name3[i] = name1[i];
- else
- break;
- }
-
- for (i = 0; i < BUFLEN && i < len2; i++) {
- if (name2[i] != '.')
- name4[i] = name2[i];
- else
- break;
- }
-
- len1 = strlen(name3);
- len2 = strlen(name4);
-
- if (len1 == len2 && !strncmp(name3, name4, len1))
- return 1;
-
- return 0;
-}
-
-static cman_node_t *find_cman_node_name(char *name)
-{
- int i;
-
- for (i = 0; i < cman_node_count; i++) {
- if (name_equal(cman_nodes[i].cn_name, name))
- return &cman_nodes[i];
- }
- return NULL;
-}
-
-static cman_node_t *find_cman_node(int nodeid)
-{
- int i;
-
- for (i = 0; i < cman_node_count; i++) {
- if (cman_nodes[i].cn_nodeid == nodeid)
- return &cman_nodes[i];
- }
- return NULL;
-}
-
-char *nodeid_to_name(int nodeid)
-{
- cman_node_t *cn;
-
- cn = find_cman_node(nodeid);
- if (cn)
- return cn->cn_name;
-
- return NULL;
-}
-
-int name_to_nodeid(char *name)
-{
- cman_node_t *cn;
-
- cn = find_cman_node_name(name);
- if (cn)
- return cn->cn_nodeid;
-
- return -1;
-}
-
-static void update_cluster(void)
-{
- cman_cluster_t info;
- cman_node_t *old;
- int quorate = cluster_quorate;
- int removed = 0, added = 0;
- int i, rv;
-
- rv = cman_get_cluster(ch, &info);
- if (rv < 0) {
- log_error("cman_get_cluster error %d %d", rv, errno);
- return;
- }
- cluster_ringid_seq = info.ci_generation;
-
- cluster_quorate = cman_is_quorate(ch);
-
- if (!quorate && cluster_quorate)
- quorate_time = time(NULL);
-
- old_node_count = cman_node_count;
- memcpy(&old_nodes, &cman_nodes, sizeof(old_nodes));
-
- cman_node_count = 0;
- memset(&cman_nodes, 0, sizeof(cman_nodes));
- rv = cman_get_nodes(ch, MAX_NODES, &cman_node_count, cman_nodes);
- if (rv < 0) {
- log_error("cman_get_nodes error %d %d", rv, errno);
- return;
- }
-
- for (i = 0; i < old_node_count; i++) {
- if (old_nodes[i].cn_member &&
- !is_cluster_member(old_nodes[i].cn_nodeid)) {
-
- log_debug("cluster node %d removed seq %u",
- old_nodes[i].cn_nodeid, cluster_ringid_seq);
-
- node_history_cluster_remove(old_nodes[i].cn_nodeid);
- removed++;
- }
- }
-
- for (i = 0; i < cman_node_count; i++) {
- if (cman_nodes[i].cn_member &&
- !is_old_member(cman_nodes[i].cn_nodeid)) {
-
- log_debug("cluster node %d added seq %u",
- cman_nodes[i].cn_nodeid, cluster_ringid_seq);
-
- node_history_cluster_add(cman_nodes[i].cn_nodeid);
- added++;
- } else {
- /* look for any nodes that were members of both
- * old and new but have a new incarnation number
- * from old to new, indicating they left and rejoined
- * in between */
-
- old = get_node(old_nodes, old_node_count, cman_nodes[i].cn_nodeid);
-
- if (!old)
- continue;
- if (cman_nodes[i].cn_incarnation == old->cn_incarnation)
- continue;
-
- log_debug("cluster node %d removed and added seq %u "
- "old %u new %u",
- cman_nodes[i].cn_nodeid, cluster_ringid_seq,
- old->cn_incarnation,
- cman_nodes[i].cn_incarnation);
-
- node_history_cluster_remove(cman_nodes[i].cn_nodeid);
- removed++;
-
- node_history_cluster_add(cman_nodes[i].cn_nodeid);
- added++;
- }
- }
-
- if (removed) {
- cluster_quorate_from_last_update = 0;
- } else if (added) {
- if (!quorate && cluster_quorate)
- cluster_quorate_from_last_update = 1;
- else
- cluster_quorate_from_last_update = 0;
- }
-}
-
-/* Note: in fence delay loop we aren't processing callbacks so won't
- have done an update_cluster() in response to a cman callback */
-
-int is_cluster_member_reread(int nodeid)
-{
- int rv;
-
- update_cluster();
-
- rv = is_cluster_member(nodeid);
- if (rv)
- return 1;
-
- /* log_debug("cman_member %d not member", nodeid); */
- return 0;
-}
-
-static void cman_callback(cman_handle_t h, void *private, int reason, int arg)
-{
- int quorate = cluster_quorate;
-
- switch (reason) {
- case CMAN_REASON_TRY_SHUTDOWN:
- if (list_empty(&domains))
- cman_replyto_shutdown(ch, 1);
- else {
- log_debug("no to cman shutdown");
- cman_replyto_shutdown(ch, 0);
- }
- break;
- case CMAN_REASON_STATECHANGE:
- update_cluster();
-
- /* domain may have been waiting for quorum */
- if (!quorate && cluster_quorate && (group_mode == GROUP_LIBCPG))
- process_fd_changes();
- break;
-
- case CMAN_REASON_CONFIG_UPDATE:
- setup_logging();
- reread_ccs();
- break;
- }
-}
-
-void process_cluster(int ci)
-{
- int rv;
-
- rv = cman_dispatch(ch, CMAN_DISPATCH_ALL);
- if (rv == -1 && errno == EHOSTDOWN)
- cluster_dead(0);
-}
-
-int setup_cluster(void)
-{
- cman_node_t node;
- int rv, fd;
- int init = 0, active = 0;
-
- retry_init:
- ch_admin = cman_admin_init(NULL);
- if (!ch_admin) {
- if (init++ < 2) {
- sleep(1);
- goto retry_init;
- }
- log_error("cman_admin_init error %d", errno);
- return -ENOTCONN;
- }
-
- ch = cman_init(NULL);
- if (!ch) {
- log_error("cman_init error %d", errno);
- cman_finish(ch_admin);
- return -ENOTCONN;
- }
-
- retry_active:
- rv = cman_is_active(ch);
- if (!rv) {
- if (active++ < 2) {
- sleep(1);
- goto retry_active;
- }
- log_error("cman_is_active error %d", errno);
- cman_finish(ch);
- cman_finish(ch_admin);
- return -ENOTCONN;
- }
-
- rv = cman_start_notification(ch, cman_callback);
- if (rv < 0) {
- log_error("cman_start_notification error %d %d", rv, errno);
- cman_finish(ch);
- cman_finish(ch_admin);
- return rv;
- }
-
- update_cluster();
-
- fd = cman_get_fd(ch);
-
- /* FIXME: wait here for us to be a member of the cluster */
- memset(&node, 0, sizeof(node));
- rv = cman_get_node(ch, CMAN_NODEID_US, &node);
- if (rv < 0) {
- log_error("cman_get_node us error %d %d", rv, errno);
- cman_finish(ch);
- cman_finish(ch_admin);
- fd = rv;
- goto out;
- }
-
- memset(our_name, 0, sizeof(our_name));
- strncpy(our_name, node.cn_name, CMAN_MAX_NODENAME_LEN);
- our_nodeid = node.cn_nodeid;
-
- log_debug("our_nodeid %d our_name %s", our_nodeid, our_name);
- out:
- return fd;
-}
-
-void close_cluster(void)
-{
- cman_finish(ch);
- cman_finish(ch_admin);
-}
-
-struct node *get_new_node(struct fd *fd, int nodeid)
-{
- cman_node_t cn;
- struct node *node;
- int rv;
-
- node = malloc(sizeof(*node));
- if (!node)
- return NULL;
- memset(node, 0, sizeof(struct node));
-
- node->nodeid = nodeid;
-
- memset(&cn, 0, sizeof(cn));
- rv = cman_get_node(ch, nodeid, &cn);
- if (rv < 0)
- log_debug("get_new_node %d no cman node %d", nodeid, rv);
- else
- strncpy(node->name, cn.cn_name, MAX_NODENAME_LEN);
-
- return node;
-}
-
diff --git a/fence/fenced/recover.c b/fence/fenced/recover.c
deleted file mode 100644
index c9786fe..0000000
--- a/fence/fenced/recover.c
+++ /dev/null
@@ -1,476 +0,0 @@
-#include "fd.h"
-#include "config.h"
-
-
-void free_node_list(struct list_head *head)
-{
- struct node *node;
-
- while (!list_empty(head)) {
- node = list_entry(head->next, struct node, list);
- list_del(&node->list);
- free(node);
- }
-}
-
-void add_complete_node(struct fd *fd, int nodeid)
-{
- struct node *node;
-
- node = get_new_node(fd, nodeid);
- list_add(&node->list, &fd->complete);
-
- if (group_mode == GROUP_LIBGROUP)
- return;
-
- node_history_init(fd, nodeid);
-}
-
-int list_count(struct list_head *head)
-{
- struct list_head *tmp;
- int count = 0;
-
- list_for_each(tmp, head)
- count++;
- return count;
-}
-
-int is_victim(struct fd *fd, int nodeid)
-{
- struct node *node;
-
- list_for_each_entry(node, &fd->victims, list) {
- if (node->nodeid == nodeid)
- return 1;
- }
- return 0;
-}
-
-static void victim_done(struct fd *fd, int victim, int how)
-{
- if (group_mode == GROUP_LIBGROUP)
- return;
-
- node_history_fence(fd, victim, our_nodeid, how, time(NULL));
- send_victim_done(fd, victim);
-}
-
-/* This routine should probe other indicators to check if victims
- can be reduced. Right now we just check if the victim has rejoined the
- cluster. */
-
-static int reduce_victims(struct fd *fd)
-{
- struct node *node, *safe;
- int num_victims;
-
- num_victims = list_count(&fd->victims);
-
- list_for_each_entry_safe(node, safe, &fd->victims, list) {
- if (is_cluster_member_reread(node->nodeid) &&
- is_clean_daemon_member(node->nodeid)) {
- log_debug("reduce victim %s", node->name);
- victim_done(fd, node->nodeid, VIC_DONE_MEMBER);
- list_del(&node->list);
- free(node);
- num_victims--;
- }
- }
-
- return num_victims;
-}
-
-static inline void close_override(int fd, const char *path)
-{
- unlink(path);
- if (fd >= 0)
- close(fd);
-}
-
-static int open_override(const char *path)
-{
- int ret;
- mode_t om;
-
- om = umask(077);
- ret = mkfifo(path, (S_IRUSR | S_IWUSR));
- umask(om);
-
- if (ret < 0)
- return -1;
- return open(path, O_RDONLY | O_NONBLOCK);
-}
-
-static int check_override(int ofd, char *nodename, int timeout)
-{
- char buf[128];
- fd_set rfds;
- struct timeval tv = {0, 0};
- int ret, x, rv;
-
- query_unlock();
-
- if (ofd < 0 || !nodename || !strlen(nodename)) {
- sleep(timeout);
- rv = 0;
- goto out;
- }
-
- FD_ZERO(&rfds);
- FD_SET(ofd, &rfds);
- tv.tv_usec = 0;
- tv.tv_sec = timeout;
-
- ret = select(ofd + 1, &rfds, NULL, NULL, &tv);
- if (ret < 0) {
- log_debug("check_override select: %s", strerror(errno));
- rv = -1;
- goto out;
- }
-
- if (ret == 0) {
- rv = 0;
- goto out;
- }
-
- memset(buf, 0, sizeof(buf));
- ret = read(ofd, buf, sizeof(buf) - 1);
- if (ret < 0) {
- log_debug("check_override read: %s", strerror(errno));
- rv = -1;
- goto out;
- }
-
- /* chop off control characters */
- for (x = 0; x < ret; x++) {
- if (buf[x] < 0x20) {
- buf[x] = 0;
- break;
- }
- }
-
- if (!strcasecmp(nodename, buf)) {
- /* Case insensitive, but not as nice as, say, name_equal
- in the other file... */
- rv = 1;
- goto out;
- }
-
- rv = 0;
- out:
- query_lock();
- return rv;
-}
-
-static int fence_check_pid(void)
-{
- char buf[16];
- int fd, rv, pid = 0;
-
- fd = open(DEFAULT_FENCE_CHECK_PID_PATH, O_RDONLY);
- if (fd < 0)
- return 0;
-
- rv = flock(fd, LOCK_EX | LOCK_NB);
- if (!rv) {
- flock(fd, LOCK_UN);
- goto out;
- }
-
- /* fence_check script is running, return its pid */
-
- memset(buf, 0, sizeof(buf));
-
- rv = read(fd, buf, sizeof(buf));
- if (rv <= 0)
- goto out;
-
- pid = atoi(buf);
- if (pid <= 0)
- pid = 0;
- out:
- close(fd);
- return pid;
-}
-
-/* If there are victims after a node has joined, it's a good indication that
- they may be joining the cluster shortly. If we delay a bit they might
- become members and we can avoid fencing them. This is only really an issue
- when the fencing method reboots the victims. Otherwise, the nodes should
- unfence themselves when they start up. */
-
-void delay_fencing(struct fd *fd, int node_join)
-{
- struct timeval first, last, start, now;
- int victim_count, last_count = 0, delay = 0, pid;
- struct node *node;
- const char *delay_type;
-
- if (list_empty(&fd->victims))
- return;
-
- gettimeofday(&first, NULL);
- gettimeofday(&start, NULL);
-
- if (cfgd_fence_check_delay) {
- for (;;) {
- pid = fence_check_pid();
- if (!pid)
- break;
-
- gettimeofday(&now, NULL);
- if (now.tv_sec - start.tv_sec >= cfgd_fence_check_delay)
- break;
-
- log_debug("delay fencing for fence_check_pid %d", pid);
- sleep(1);
- }
-
- if (pid) {
- kill(pid, SIGTERM);
- log_error("kill fence_check_pid %d delay %d",
- pid, cfgd_fence_check_delay);
- }
- }
-
- if (node_join || cluster_quorate_from_last_update) {
- delay = cfgd_post_join_delay;
- delay_type = "post_join_delay";
- } else {
- delay = cfgd_post_fail_delay;
- delay_type = "post_fail_delay";
- }
-
- log_debug("delay %s %d quorate_from_last_update %d",
- delay_type, delay, cluster_quorate_from_last_update);
-
- if (delay == 0)
- goto out;
-
- for (;;) {
- query_unlock();
- sleep(1);
- query_lock();
-
- victim_count = reduce_victims(fd);
-
- if (victim_count == 0)
- break;
-
- if (victim_count < last_count) {
- gettimeofday(&start, NULL);
- if (delay > 0 && cfgd_post_join_delay > delay) {
- delay = cfgd_post_join_delay;
- delay_type = "post_join_delay (modified)";
- }
- }
-
- last_count = victim_count;
-
- /* negative delay means wait forever */
- if (delay == -1)
- continue;
-
- gettimeofday(&now, NULL);
- if (now.tv_sec - start.tv_sec >= delay)
- break;
- }
-
- gettimeofday(&last, NULL);
-
- log_debug("delay of %ds leaves %d victims",
- (int) (last.tv_sec - first.tv_sec), victim_count);
- out:
- list_for_each_entry(node, &fd->victims, list) {
- log_debug("%s not a cluster member after %d sec %s",
- node->name, delay, delay_type);
- }
-}
-
-void defer_fencing(struct fd *fd)
-{
- char *master_name;
-
- if (list_empty(&fd->victims))
- return;
-
- master_name = nodeid_to_name(fd->master);
-
- log_level(LOG_INFO, "fencing deferred to %s",
- master_name ? master_name : "unknown");
-}
-
-static const char *fe_str(int r)
-{
- switch (r) {
- case FE_AGENT_SUCCESS:
- return "success";
- case FE_AGENT_ERROR:
- return "error from agent";
- case FE_AGENT_FORK:
- return "error from fork";
- case FE_NO_CONFIG:
- return "error from ccs";
- case FE_NO_METHOD:
- return "error no method";
- case FE_NO_DEVICE:
- return "error no device";
- case FE_READ_AGENT:
- return "error config agent";
- case FE_READ_ARGS:
- return "error config args";
- case FE_READ_METHOD:
- return "error config method";
- case FE_READ_DEVICE:
- return "error config device";
- default:
- return "error unknown";
- }
-}
-
-#define FL_SIZE 32
-static struct fence_log flog[FL_SIZE];
-static struct fence_log prev_flog[FL_SIZE];
-
-void fence_victims(struct fd *fd)
-{
- struct node *node;
- int error, i, ll, flog_count, prev_flog_count;
- int override_fd = -1;
- int cluster_member, cpg_member, ext;
- unsigned int limit, retries;
-
- list_for_each_entry(node, &fd->victims, list) {
- if (node->local_victim_done) {
- /* local_victim_done means we've successfully fenced
- this node and will remove it from victims list
- upon receipt of the victim_done message we sent */
-
- /* I don't believe fence_victims() can come across
- a node with local_victim_done set. That would
- mean: pass 1 through fence_victims() fences node A,
- send victim_done(A), return, process confchgs
- adding and removing A again, receive msgs for start
- cycle, but *not* receive victim_done(A) msg before
- coming through fence_victims() again. */
-
- log_error("skip local_victim_done node %d",
- node->nodeid);
- continue;
- }
-
- /* limit repeated logging of the same failure messages
- when retrying fencing */
-
- limit = 0;
- retries = 0;
- memset(&prev_flog, 0, sizeof(flog));
- prev_flog_count = 0;
-
- retry:
- if (retries > 2)
- limit = 1;
- if (limit && !(retries % 600))
- log_level(LOG_INFO, "fencing node %s still retrying",
- node->name);
-
- /* for queries */
- fd->current_victim = node->nodeid;
-
- cluster_member = is_cluster_member_reread(node->nodeid);
- cpg_member = is_clean_daemon_member(node->nodeid);
- if (group_mode == GROUP_LIBCPG)
- ext = is_fenced_external(fd, node->nodeid);
- else
- ext = 0;
-
- if ((cluster_member && cpg_member) || ext) {
- log_debug("averting fence of node %s "
- "cluster member %d cpg member %d external %d",
- node->name, cluster_member, cpg_member, ext);
-
- node->local_victim_done = 1;
- victim_done(fd, node->nodeid,
- ext ? VIC_DONE_EXTERNAL : VIC_DONE_MEMBER);
- continue;
- }
-
- memset(&flog, 0, sizeof(flog));
- flog_count = 0;
-
- if (!limit)
- log_level(LOG_INFO, "fencing node %s", node->name);
-
- if (override_fd == -1)
- override_fd = open_override(cfgd_override_path);
-
- query_unlock();
- error = fence_node(node->name, flog, FL_SIZE, &flog_count);
- query_lock();
-
- if (flog_count > FL_SIZE) {
- log_error("fence_node log overflow %d", flog_count);
- flog_count = FL_SIZE;
- }
-
- if (limit && error &&
- flog_count == prev_flog_count &&
- !memcmp(&flog, &prev_flog, sizeof(flog))) {
- goto skip_log_message;
- }
-
- memcpy(&prev_flog, &flog, sizeof(flog));
- prev_flog_count = flog_count;
-
- for (i = 0; i < flog_count; i++) {
- ll = (flog[i].error == FE_AGENT_SUCCESS) ? LOG_DEBUG:
- LOG_ERR;
- log_level(ll, "fence %s dev %d.%d agent %s result: %s",
- node->name,
- flog[i].method_num, flog[i].device_num,
- flog[i].agent_name[0] ?
- flog[i].agent_name : "none",
- fe_str(flog[i].error));
- }
-
- log_error("fence %s %s", node->name,
- error ? "failed" : "success");
-
- if (!cfgd_disable_dbus) {
- fd_dbus_send(node->name, node->nodeid, error);
- }
-
- skip_log_message:
- if (!error) {
- node->local_victim_done = 1;
- victim_done(fd, node->nodeid, VIC_DONE_AGENT);
- continue;
- }
-
- if (!cfgd_override_path || (override_fd == -1)) {
- query_unlock();
- sleep(5);
- query_lock();
- retries++;
- goto retry;
- }
-
- /* Check for manual intervention */
- if (check_override(override_fd, node->name, cfgd_override_time) > 0) {
- log_level(LOG_WARNING, "fence %s overridden by administrator intervention", node->name);
- node->local_victim_done = 1;
- victim_done(fd, node->nodeid, VIC_DONE_OVERRIDE);
- continue;
- } else {
- retries++;
- goto retry;
- }
- }
-
- fd->current_victim = 0;
-
- if (override_fd >= 0)
- close_override(override_fd, cfgd_override_path);
-}
-
diff --git a/fence/include/linux_endian.h b/fence/include/linux_endian.h
deleted file mode 100644
index 43089d2..0000000
--- a/fence/include/linux_endian.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef __LINUX_ENDIAN_DOT_H__
-#define __LINUX_ENDIAN_DOT_H__
-
-
-#include <endian.h>
-#include <byteswap.h>
-
-
-/* I'm not sure which versions of alpha glibc/gcc are broken,
- so fix all of them. */
-#ifdef __alpha__
-#undef bswap_64
-static __inline__ unsigned long bswap_64(unsigned long x)
-{
- unsigned int h = x >> 32;
- unsigned int l = x;
-
- h = bswap_32(h);
- l = bswap_32(l);
-
- return ((unsigned long)l << 32) | h;
-}
-#endif /* __alpha__ */
-
-
-#if __BYTE_ORDER == __BIG_ENDIAN
-
-#define be16_to_cpu(x) (x)
-#define be32_to_cpu(x) (x)
-#define be64_to_cpu(x) (x)
-
-#define cpu_to_be16(x) (x)
-#define cpu_to_be32(x) (x)
-#define cpu_to_be64(x) (x)
-
-#define le16_to_cpu(x) (bswap_16((x)))
-#define le32_to_cpu(x) (bswap_32((x)))
-#define le64_to_cpu(x) (bswap_64((x)))
-
-#define cpu_to_le16(x) (bswap_16((x)))
-#define cpu_to_le32(x) (bswap_32((x)))
-#define cpu_to_le64(x) (bswap_64((x)))
-
-#endif /* __BYTE_ORDER == __BIG_ENDIAN */
-
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-
-#define be16_to_cpu(x) (bswap_16((x)))
-#define be32_to_cpu(x) (bswap_32((x)))
-#define be64_to_cpu(x) (bswap_64((x)))
-
-#define cpu_to_be16(x) (bswap_16((x)))
-#define cpu_to_be32(x) (bswap_32((x)))
-#define cpu_to_be64(x) (bswap_64((x)))
-
-#define le16_to_cpu(x) (x)
-#define le32_to_cpu(x) (x)
-#define le64_to_cpu(x) (x)
-
-#define cpu_to_le16(x) (x)
-#define cpu_to_le32(x) (x)
-#define cpu_to_le64(x) (x)
-
-#endif /* __BYTE_ORDER == __LITTLE_ENDIAN */
-
-
-#endif /* __LINUX_ENDIAN_DOT_H__ */
diff --git a/fence/include/list.h b/fence/include/list.h
deleted file mode 100644
index 8100cbc..0000000
--- a/fence/include/list.h
+++ /dev/null
@@ -1,336 +0,0 @@
-/* Copied from include/linux/list.h */
-
-#ifndef _LINUX_LIST_H
-#define _LINUX_LIST_H
-
-/**
- * container_of - cast a member of a structure out to the containing structure
- *
- * @ptr: the pointer to the member.
- * @type: the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-
-
-/*
- * These are non-NULL pointers that will result in page faults
- * under normal circumstances, used to verify that nobody uses
- * non-initialized list entries.
- */
-#define LIST_POISON1 ((void *) 0x00100100)
-#define LIST_POISON2 ((void *) 0x00200200)
-
-/*
- * Simple doubly linked list implementation.
- *
- * Some of the internal functions ("__xxx") are useful when
- * manipulating whole lists rather than single entries, as
- * sometimes we already know the next/prev entries and we can
- * generate better code by using them directly rather than
- * using the generic single-entry routines.
- */
-
-struct list_head {
- struct list_head *next, *prev;
-};
-
-#define LIST_HEAD_INIT(name) { &(name), &(name) }
-
-#define LIST_HEAD(name) \
- struct list_head name = LIST_HEAD_INIT(name)
-
-#define INIT_LIST_HEAD(ptr) do { \
- (ptr)->next = (ptr); (ptr)->prev = (ptr); \
-} while (0)
-
-/*
- * Insert a new entry between two known consecutive entries.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_add(struct list_head *new,
- struct list_head *prev,
- struct list_head *next)
-{
- next->prev = new;
- new->next = next;
- new->prev = prev;
- prev->next = new;
-}
-
-/**
- * list_add - add a new entry
- * @new: new entry to be added
- * @head: list head to add it after
- *
- * Insert a new entry after the specified head.
- * This is good for implementing stacks.
- */
-static inline void list_add(struct list_head *new, struct list_head *head)
-{
- __list_add(new, head, head->next);
-}
-
-/**
- * list_add_tail - add a new entry
- * @new: new entry to be added
- * @head: list head to add it before
- *
- * Insert a new entry before the specified head.
- * This is useful for implementing queues.
- */
-static inline void list_add_tail(struct list_head *new, struct list_head *head)
-{
- __list_add(new, head->prev, head);
-}
-
-/*
- * Delete a list entry by making the prev/next entries
- * point to each other.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_del(struct list_head * prev, struct list_head * next)
-{
- next->prev = prev;
- prev->next = next;
-}
-
-/**
- * list_del - deletes entry from list.
- * @entry: the element to delete from the list.
- * Note: list_empty on entry does not return true after this, the entry is
- * in an undefined state.
- */
-static inline void list_del(struct list_head *entry)
-{
- __list_del(entry->prev, entry->next);
- entry->next = LIST_POISON1;
- entry->prev = LIST_POISON2;
-}
-
-/**
- * list_del_init - deletes entry from list and reinitialize it.
- * @entry: the element to delete from the list.
- */
-static inline void list_del_init(struct list_head *entry)
-{
- __list_del(entry->prev, entry->next);
- INIT_LIST_HEAD(entry);
-}
-
-/**
- * list_move - delete from one list and add as another's head
- * @list: the entry to move
- * @head: the head that will precede our entry
- */
-static inline void list_move(struct list_head *list, struct list_head *head)
-{
- __list_del(list->prev, list->next);
- list_add(list, head);
-}
-
-/**
- * list_move_tail - delete from one list and add as another's tail
- * @list: the entry to move
- * @head: the head that will follow our entry
- */
-static inline void list_move_tail(struct list_head *list,
- struct list_head *head)
-{
- __list_del(list->prev, list->next);
- list_add_tail(list, head);
-}
-
-/**
- * list_empty - tests whether a list is empty
- * @head: the list to test.
- */
-static inline int list_empty(const struct list_head *head)
-{
- return head->next == head;
-}
-
-/**
- * list_empty_careful - tests whether a list is
- * empty _and_ checks that no other CPU might be
- * in the process of still modifying either member
- *
- * NOTE: using list_empty_careful() without synchronization
- * can only be safe if the only activity that can happen
- * to the list entry is list_del_init(). Eg. it cannot be used
- * if another CPU could re-list_add() it.
- *
- * @head: the list to test.
- */
-static inline int list_empty_careful(const struct list_head *head)
-{
- struct list_head *next = head->next;
- return (next == head) && (next == head->prev);
-}
-
-static inline void __list_splice(struct list_head *list,
- struct list_head *head)
-{
- struct list_head *first = list->next;
- struct list_head *last = list->prev;
- struct list_head *at = head->next;
-
- first->prev = head;
- head->next = first;
-
- last->next = at;
- at->prev = last;
-}
-
-/**
- * list_splice - join two lists
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- */
-static inline void list_splice(struct list_head *list, struct list_head *head)
-{
- if (!list_empty(list))
- __list_splice(list, head);
-}
-
-/**
- * list_splice_init - join two lists and reinitialise the emptied list.
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- *
- * The list at @list is reinitialised
- */
-static inline void list_splice_init(struct list_head *list,
- struct list_head *head)
-{
- if (!list_empty(list)) {
- __list_splice(list, head);
- INIT_LIST_HEAD(list);
- }
-}
-
-/**
- * list_entry - get the struct for this entry
- * @ptr: the &struct list_head pointer.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_struct within the struct.
- */
-#define list_entry(ptr, type, member) \
- container_of(ptr, type, member)
-
-/**
- * list_first_entry - get the first element from a list
- * @ptr: the list head to take the element from.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_struct within the struct.
- *
- * Note, that list is expected to be not empty.
- */
-#define list_first_entry(ptr, type, member) \
- list_entry((ptr)->next, type, member)
-
-/**
- * list_for_each - iterate over a list
- * @pos: the &struct list_head to use as a loop counter.
- * @head: the head for your list.
- */
-#define list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * __list_for_each - iterate over a list
- * @pos: the &struct list_head to use as a loop counter.
- * @head: the head for your list.
- *
- * This variant differs from list_for_each() in that it's the
- * simplest possible list iteration code, no prefetching is done.
- * Use this for code that knows the list to be very short (empty
- * or 1 entry) most of the time.
- */
-#define __list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * list_for_each_prev - iterate over a list backwards
- * @pos: the &struct list_head to use as a loop counter.
- * @head: the head for your list.
- */
-#define list_for_each_prev(pos, head) \
- for (pos = (head)->prev; pos != (head); pos = pos->prev)
-
-/**
- * list_for_each_safe - iterate over a list safe against removal of list entry
- * @pos: the &struct list_head to use as a loop counter.
- * @n: another &struct list_head to use as temporary storage
- * @head: the head for your list.
- */
-#define list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
-
-/**
- * list_for_each_entry - iterate over list of given type
- * @pos: the type * to use as a loop counter.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry(pos, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_reverse - iterate backwards over list of given type.
- * @pos: the type * to use as a loop counter.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry_reverse(pos, head, member) \
- for (pos = list_entry((head)->prev, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.prev, typeof(*pos), member))
-
-/**
- * list_prepare_entry - prepare a pos entry for use as a start point in
- * list_for_each_entry_continue
- * @pos: the type * to use as a start point
- * @head: the head of the list
- * @member: the name of the list_struct within the struct.
- */
-#define list_prepare_entry(pos, head, member) \
- ((pos) ? : list_entry(head, typeof(*pos), member))
-
-/**
- * list_for_each_entry_continue - iterate over list of given type
- * continuing after existing point
- * @pos: the type * to use as a loop counter.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry_continue(pos, head, member) \
- for (pos = list_entry(pos->member.next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @pos: the type * to use as a loop counter.
- * @n: another type * to use as temporary storage
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry_safe(pos, n, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member), \
- n = list_entry(pos->member.next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-
-#endif
diff --git a/fence/libfence/Makefile b/fence/libfence/Makefile
deleted file mode 100644
index 93bf45c..0000000
--- a/fence/libfence/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-TARGET= libfence
-
-SOMAJOR=4
-SOMINOR=0
-
-OBJS= agent.o
-
-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${ccsincdir}
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${ccslibdir} -lccs
-LDFLAGS += -L${libdir}
diff --git a/fence/libfence/agent.c b/fence/libfence/agent.c
deleted file mode 100644
index fac6c92..0000000
--- a/fence/libfence/agent.c
+++ /dev/null
@@ -1,1142 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <string.h>
-#include <errno.h>
-#include <time.h>
-#include <limits.h>
-
-#include "libfence.h"
-#include "ccs.h"
-
-#define MAX_METHODS 8
-#define MAX_DEVICES 8
-
-#define METHOD_NAME_PATH "/cluster/clusternodes/clusternode[@name=\"%s\"]/fence/method[%d]/@name"
-#define DEVICE_NAME_PATH "/cluster/clusternodes/clusternode[@name=\"%s\"]/fence/method[@name=\"%s\"]/device[%d]/@name"
-#define NODE_FENCE_ARGS_PATH "/cluster/clusternodes/clusternode[@name=\"%s\"]/fence/method[@name=\"%s\"]/device[%d]/@*"
-#define AGENT_NAME_PATH "/cluster/fencedevices/fencedevice[@name=\"%s\"]/@agent"
-#define FENCE_DEVICE_ARGS_PATH "/cluster/fencedevices/fencedevice[@name=\"%s\"]/@*"
-
-
-
-static int run_agent(char *agent, char *args, int *agent_result)
-{
- int pid, status, len;
- int pr_fd, pw_fd; /* parent read/write file descriptors */
- int cr_fd, cw_fd; /* child read/write file descriptors */
- int fd1[2];
- int fd2[2];
-
- cr_fd = cw_fd = pr_fd = pw_fd = -1;
-
- if (args == NULL || agent == NULL)
- goto fail;
- len = strlen(args);
-
- if (pipe(fd1))
- goto fail;
- pr_fd = fd1[0];
- cw_fd = fd1[1];
-
- if (pipe(fd2))
- goto fail;
- cr_fd = fd2[0];
- pw_fd = fd2[1];
-
- pid = fork();
- if (pid < 0) {
- *agent_result = FE_AGENT_FORK;
- goto fail;
- }
-
- if (pid) {
- /* parent */
- int ret;
-
- fcntl(pr_fd, F_SETFL, fcntl(pr_fd, F_GETFL, 0) | O_NONBLOCK);
-
- do {
- ret = write(pw_fd, args, len);
- } while (ret < 0 && errno == EINTR);
-
- if (ret != len)
- goto fail;
-
- close(pw_fd);
- waitpid(pid, &status, 0);
-
- if (!WIFEXITED(status) || WEXITSTATUS(status)) {
- *agent_result = FE_AGENT_ERROR;
- goto fail;
- } else {
- *agent_result = FE_AGENT_SUCCESS;
- }
- } else {
- /* child */
-
- close(1);
- if (dup(cw_fd) < 0)
- goto fail;
- close(2);
- if (dup(cw_fd) < 0)
- goto fail;
- close(0);
- if (dup(cr_fd) < 0)
- goto fail;
- /* keep cw_fd open so parent can report all errors. */
- close(pr_fd);
- close(cr_fd);
- close(pw_fd);
-
- execlp(agent, agent, NULL);
- exit(EXIT_FAILURE);
- }
-
- close(pr_fd);
- close(cw_fd);
- close(cr_fd);
- close(pw_fd);
- return 0;
-
- fail:
- close(pr_fd);
- close(cw_fd);
- close(cr_fd);
- close(pw_fd);
- return -1;
-}
-
-static int make_args(int cd, char *victim, char *method, int d,
- char *device, char **args_out)
-{
- char path[PATH_MAX];
- char *args, *str;
- int error, ret, cnt = 0;
- size_t len, pos;
-
- args = malloc(FENCE_AGENT_ARGS_MAX);
- if (!args)
- return -ENOMEM;
- memset(args, 0, FENCE_AGENT_ARGS_MAX);
-
- len = FENCE_AGENT_ARGS_MAX - 1;
- pos = 0;
-
- /* node-specific args for victim */
-
- memset(path, 0, PATH_MAX);
- sprintf(path, NODE_FENCE_ARGS_PATH, victim, method, d+1);
-
- for (;;) {
- error = ccs_get_list(cd, path, &str);
- if (error || !str)
- break;
- ++cnt;
-
- if (!strncmp(str, "name=", 5)) {
- free(str);
- continue;
- }
-
- ret = snprintf(args + pos, len - pos, "%s\n", str);
-
- free(str);
-
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- /* add nodename of victim to args */
-
- if (!strstr(args, "nodename=")) {
- ret = snprintf(args + pos, len - pos, "nodename=%s\n", victim);
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- /* device-specific args */
-
- memset(path, 0, PATH_MAX);
- sprintf(path, FENCE_DEVICE_ARGS_PATH, device);
-
- for (;;) {
- error = ccs_get_list(cd, path, &str);
- if (error || !str)
- break;
- ++cnt;
-
- if (!strncmp(str, "name=", 5)) {
- free(str);
- continue;
- }
-
- ret = snprintf(args + pos, len - pos, "%s\n", str);
-
- free(str);
-
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- if (cnt)
- error = 0;
- out:
- if (error) {
- free(args);
- args = NULL;
- }
-
- *args_out = args;
- return error;
-}
-
-/* return name of m'th method for nodes/<victim>/fence/ */
-
-static int get_method(int cd, char *victim, int m, char **method)
-{
- char path[PATH_MAX], *str = NULL;
- int error;
-
- memset(path, 0, PATH_MAX);
- sprintf(path, METHOD_NAME_PATH, victim, m+1);
-
- error = ccs_get(cd, path, &str);
- *method = str;
- return error;
-}
-
-/* return name of d'th device under nodes/<victim>/fence/<method>/ */
-
-static int get_device(int cd, char *victim, char *method, int d, char **device)
-{
- char path[PATH_MAX], *str = NULL;
- int error;
-
- memset(path, 0, PATH_MAX);
- sprintf(path, DEVICE_NAME_PATH, victim, method, d+1);
-
- error = ccs_get(cd, path, &str);
- *device = str;
- return error;
-}
-
-static int count_methods(int cd, char *victim)
-{
- char path[PATH_MAX], *name;
- int error, i;
-
- for (i = 0; i < MAX_METHODS; i++) {
- memset(path, 0, PATH_MAX);
- sprintf(path, METHOD_NAME_PATH, victim, i+1);
-
- error = ccs_get(cd, path, &name);
- if (error)
- break;
- free(name);
- }
- return i;
-}
-
-static int count_devices(int cd, char *victim, char *method)
-{
- char path[PATH_MAX], *name;
- int error, i;
-
- for (i = 0; i < MAX_DEVICES; i++) {
- memset(path, 0, PATH_MAX);
- sprintf(path, DEVICE_NAME_PATH, victim, method, i+1);
-
- error = ccs_get(cd, path, &name);
- if (error)
- break;
- free(name);
- }
- return i;
-}
-
-static int use_device(int cd, char *victim, char *method, int d,
- char *device, struct fence_log *lp)
-{
- char path[PATH_MAX], *agent, *args = NULL;
- int error;
-
- memset(path, 0, PATH_MAX);
- sprintf(path, AGENT_NAME_PATH, device);
-
- error = ccs_get(cd, path, &agent);
- if (error) {
- lp->error = FE_READ_AGENT;
- goto out;
- }
-
- strncpy(lp->agent_name, agent, FENCE_AGENT_NAME_MAX-1);
-
- error = make_args(cd, victim, method, d, device, &args);
- if (error) {
- lp->error = FE_READ_ARGS;
- goto out_agent;
- }
-
- strncpy(lp->agent_args, args, FENCE_AGENT_ARGS_MAX-1);
-
- error = run_agent(agent, args, &lp->error);
-
- free(args);
- out_agent:
- free(agent);
- out:
- return error;
-}
-
-int fence_node(char *victim, struct fence_log *log, int log_size,
- int *log_count)
-{
- struct fence_log stub;
- struct fence_log *lp = log;
- char *method = NULL, *device = NULL;
- char *victim_nodename = NULL;
- int num_methods, num_devices, m, d, cd, rv;
- int left = log_size;
- int error = -1;
- int count = 0;
-
- cd = ccs_connect();
- if (cd < 0) {
- if (lp && left) {
- lp->error = FE_NO_CONFIG;
- lp++;
- left--;
- }
- count++;
- error = -1;
- goto ret;
- }
-
- if (ccs_lookup_nodename(cd, victim, &victim_nodename) == 0)
- victim = victim_nodename;
-
- num_methods = count_methods(cd, victim);
- if (!num_methods) {
- if (lp && left) {
- lp->error = FE_NO_METHOD;
- lp++;
- left--;
- }
- count++;
- error = -2; /* No fencing */
- goto out;
- }
-
- for (m = 0; m < num_methods; m++) {
-
- rv = get_method(cd, victim, m, &method);
- if (rv) {
- if (lp && left) {
- lp->error = FE_READ_METHOD;
- lp->method_num = m;
- lp++;
- left--;
- }
- count++;
- error = -1;
- continue;
- }
-
- num_devices = count_devices(cd, victim, method);
- if (!num_devices) {
- if (lp && left) {
- lp->error = FE_NO_DEVICE;
- lp->method_num = m;
- lp++;
- left--;
- }
- count++;
- error = -1;
- continue;
- }
-
- for (d = 0; d < num_devices; d++) {
- rv = get_device(cd, victim, method, d, &device);
- if (rv) {
- if (lp && left) {
- lp->error = FE_READ_DEVICE;
- lp->method_num = m;
- lp->device_num = d;
- lp++;
- left--;
- }
- count++;
- error = -1;
- break;
- }
-
- /* every call to use_device generates a log entry,
- whether success or fail */
-
- error = use_device(cd, victim, method, d, device,
- (lp && left) ? lp : &stub);
- count++;
- if (lp && left) {
- /* error, name, args already set */
- lp->method_num = m;
- lp->device_num = d;
- lp++;
- left--;
- }
-
- if (error)
- break;
-
- free(device);
- device = NULL;
- }
-
- if (device)
- free(device);
-
- free(method);
-
- /* we return 0 for fencing success when use_device has
- returned zero for each device in this method */
-
- if (!error)
- break;
- }
-
- if (victim_nodename)
- free(victim_nodename);
- out:
- ccs_disconnect(cd);
- ret:
- if (log_count)
- *log_count = count;
- return error;
-}
-
-#define UN_DEVICE_NAME_PATH "/cluster/clusternodes/clusternode[@name=\"%s\"]/unfence/device[%d]/@name"
-#define UN_NODE_FENCE_ARGS_PATH "/cluster/clusternodes/clusternode[@name=\"%s\"]/unfence/device[%d]/@*"
-
-static int make_args_unfence(int cd, char *victim, int d,
- char *device, char **args_out)
-{
- char path[PATH_MAX];
- char *args, *str;
- int error, ret, cnt = 0;
- size_t len, pos;
-
- args = malloc(FENCE_AGENT_ARGS_MAX);
- if (!args)
- return -ENOMEM;
- memset(args, 0, FENCE_AGENT_ARGS_MAX);
-
- len = FENCE_AGENT_ARGS_MAX - 1;
- pos = 0;
-
- /* node-specific args for victim */
-
- memset(path, 0, PATH_MAX);
- sprintf(path, UN_NODE_FENCE_ARGS_PATH, victim, d+1);
-
- for (;;) {
- error = ccs_get_list(cd, path, &str);
- if (error || !str)
- break;
- ++cnt;
-
- if (!strncmp(str, "name=", 5)) {
- free(str);
- continue;
- }
-
- ret = snprintf(args + pos, len - pos, "%s\n", str);
-
- free(str);
-
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- /* add nodename of victim to args */
-
- if (!strstr(args, "nodename=")) {
- ret = snprintf(args + pos, len - pos, "nodename=%s\n", victim);
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- /* device-specific args */
-
- memset(path, 0, PATH_MAX);
- sprintf(path, FENCE_DEVICE_ARGS_PATH, device);
-
- for (;;) {
- error = ccs_get_list(cd, path, &str);
- if (error || !str)
- break;
- ++cnt;
-
- if (!strncmp(str, "name=", 5)) {
- free(str);
- continue;
- }
-
- ret = snprintf(args + pos, len - pos, "%s\n", str);
-
- free(str);
-
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- if (cnt)
- error = 0;
- out:
- if (error) {
- free(args);
- args = NULL;
- }
-
- *args_out = args;
- return error;
-}
-
-/* return name of d'th device under nodes/<victim>/unfence/ */
-
-static int get_device_unfence(int cd, char *victim, int d, char **device)
-{
- char path[PATH_MAX], *str = NULL;
- int error;
-
- memset(path, 0, PATH_MAX);
- sprintf(path, UN_DEVICE_NAME_PATH, victim, d+1);
-
- error = ccs_get(cd, path, &str);
- *device = str;
- return error;
-}
-
-static int count_devices_unfence(int cd, char *victim)
-{
- char path[PATH_MAX], *name;
- int error, i;
-
- for (i = 0; i < MAX_DEVICES; i++) {
- memset(path, 0, PATH_MAX);
- sprintf(path, UN_DEVICE_NAME_PATH, victim, i+1);
-
- error = ccs_get(cd, path, &name);
- if (error)
- break;
- free(name);
- }
- return i;
-}
-
-static int use_device_unfence(int cd, char *victim, int d,
- char *device, struct fence_log *lp)
-{
- char path[PATH_MAX], *agent, *args = NULL;
- int error;
-
- memset(path, 0, PATH_MAX);
- sprintf(path, AGENT_NAME_PATH, device);
-
- error = ccs_get(cd, path, &agent);
- if (error) {
- lp->error = FE_READ_AGENT;
- goto out;
- }
-
- strncpy(lp->agent_name, agent, FENCE_AGENT_NAME_MAX-1);
-
- error = make_args_unfence(cd, victim, d, device, &args);
- if (error) {
- lp->error = FE_READ_ARGS;
- goto out_agent;
- }
-
- strncpy(lp->agent_args, args, FENCE_AGENT_ARGS_MAX);
-
- error = run_agent(agent, args, &lp->error);
-
- free(args);
- out_agent:
- free(agent);
- out:
- return error;
-}
-
-int unfence_node(char *victim, struct fence_log *log, int log_size,
- int *log_count)
-{
- struct fence_log stub;
- struct fence_log *lp = log;
- char *device = NULL;
- char *victim_nodename = NULL;
- int num_devices, d, cd, rv;
- int left = log_size;
- int error = -1;
- int count = 0;
-
- cd = ccs_connect();
- if (cd < 0) {
- if (lp && left) {
- lp->error = FE_NO_CONFIG;
- lp++;
- left--;
- }
- count++;
- error = -1;
- goto ret;
- }
-
- if (ccs_lookup_nodename(cd, victim, &victim_nodename) == 0)
- victim = victim_nodename;
-
- /* return -2 if unfencing fails because there's no unfencing
- defined for the node */
-
- num_devices = count_devices_unfence(cd, victim);
- if (!num_devices) {
- if (lp && left) {
- lp->error = FE_NO_DEVICE;
- lp++;
- left--;
- }
- count++;
- error = -2;
- goto out;
- }
-
- /* try to unfence all devices even if some of them fail,
- but the final return value is 0 only if all succeed */
-
- error = 0;
-
- for (d = 0; d < num_devices; d++) {
- rv = get_device_unfence(cd, victim, d, &device);
- if (rv) {
- if (lp && left) {
- lp->error = FE_READ_DEVICE;
- lp->device_num = d;
- lp++;
- left--;
- }
- count++;
- error = -1;
- continue;
- }
-
- /* every call to use_device generates a log entry,
- whether success or fail */
-
- rv = use_device_unfence(cd, victim, d, device,
- (lp && left) ? lp : &stub);
- count++;
- if (lp && left) {
- /* error, name, args already set */
- lp->device_num = d;
- lp++;
- left--;
- }
-
- if (rv)
- error = -1;
-
- free(device);
- device = NULL;
- }
-
- if (victim_nodename)
- free(victim_nodename);
- out:
- ccs_disconnect(cd);
- ret:
- if (log_count)
- *log_count = count;
- return error;
-}
-
-/*
- * Returns:
- * < 0: internal error
- * 0: agent exited with 0
- * 1: agent exited with 1
- * 2: agent exited with 2
- */
-
-static int run_agent_status(char *agent, char *args, int *agent_result)
-{
- int pid, status, len, rv;
- int pw_fd = -1; /* parent write file descriptor */
- int cr_fd = -1; /* child read file descriptor */
- int pfd[2];
-
- if (args == NULL || agent == NULL) {
- rv = -1;
- goto fail;
- }
- len = strlen(args);
-
- if (pipe(pfd)) {
- rv = -errno;
- goto fail;
- }
- cr_fd = pfd[0];
- pw_fd = pfd[1];
-
- pid = fork();
- if (pid < 0) {
- rv = -errno;
- *agent_result = FE_AGENT_FORK;
- goto fail;
- }
-
- if (pid) {
- /* parent */
- int ret;
-
- do {
- ret = write(pw_fd, args, len);
- } while (ret < 0 && errno == EINTR);
-
- if (ret != len) {
- rv = -1;
- goto fail;
- }
-
- close(cr_fd);
- close(pw_fd);
-
- rv = waitpid(pid, &status, 0);
-
- if (rv < 0) {
- /* shouldn't happen */
- rv = -errno;
- goto out;
- }
-
- if (rv != pid) {
- /* shouldn't happen */
- rv = -1;
- goto out;
- }
-
- if (WIFEXITED(status)) {
- /* pid exited properly with an exit code */
- rv = WEXITSTATUS(status);
-
- if (rv == 0)
- *agent_result = FE_AGENT_STATUS_ON;
- else if (rv == 2)
- *agent_result = FE_AGENT_STATUS_OFF;
- else
- *agent_result = FE_AGENT_STATUS_ERROR;
- } else if (WIFSIGNALED(status)) {
- /* pid terminated due to a signal */
- rv = -1;
- *agent_result = FE_AGENT_STATUS_ERROR;
- } else {
- /* something else happened, not sure what */
- rv = -1;
- *agent_result = FE_AGENT_STATUS_ERROR;
- }
- goto out;
-
- } else {
- /* child */
- int c_stdout, c_stderr;
-
- /* redirect agent stdout/stderr to /dev/null */
- close(1);
- c_stdout = open("/dev/null", O_WRONLY);
- if (c_stdout < 0) {
- rv = -1;
- goto fail;
- }
- close(2);
- c_stderr = open("/dev/null", O_WRONLY);
- if (c_stderr < 0) {
- rv = -1;
- goto fail;
- }
-
- /* redirect agent stdin from parent */
- close(0);
- if (dup(cr_fd) < 0) {
- rv = -errno;
- goto fail;
- }
-
- close(cr_fd);
- close(pw_fd);
-
- execlp(agent, agent, NULL);
- exit(EXIT_FAILURE);
- }
- fail:
- close(cr_fd);
- close(pw_fd);
- out:
- return rv;
-}
-
-static int make_args_status(int cd, char *victim, char *method, int d,
- char *device, char **args_out)
-{
- char path[PATH_MAX];
- char *args, *str;
- int error, ret, cnt = 0;
- size_t len, pos;
-
- args = malloc(FENCE_AGENT_ARGS_MAX);
- if (!args)
- return -ENOMEM;
- memset(args, 0, FENCE_AGENT_ARGS_MAX);
-
- len = FENCE_AGENT_ARGS_MAX - 1;
- pos = 0;
-
- /* node-specific args for victim */
-
- memset(path, 0, PATH_MAX);
- sprintf(path, NODE_FENCE_ARGS_PATH, victim, method, d+1);
-
- for (;;) {
- error = ccs_get_list(cd, path, &str);
- if (error || !str)
- break;
- ++cnt;
-
- if (!strncmp(str, "name=", 5)) {
- free(str);
- continue;
- }
-
- if (!strncmp(str, "action=", 7)) {
- free(str);
- continue;
- }
-
- ret = snprintf(args + pos, len - pos, "%s\n", str);
-
- free(str);
-
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- /* add nodename of victim to args */
-
- if (!strstr(args, "nodename=")) {
- ret = snprintf(args + pos, len - pos, "nodename=%s\n", victim);
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- /* add action=status to args */
-
- ret = snprintf(args + pos, len - pos, "action=status\n");
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
-
- /* device-specific args */
-
- memset(path, 0, PATH_MAX);
- sprintf(path, FENCE_DEVICE_ARGS_PATH, device);
-
- for (;;) {
- error = ccs_get_list(cd, path, &str);
- if (error || !str)
- break;
- ++cnt;
-
- if (!strncmp(str, "name=", 5)) {
- free(str);
- continue;
- }
-
- ret = snprintf(args + pos, len - pos, "%s\n", str);
-
- free(str);
-
- if (ret >= len - pos) {
- error = -E2BIG;
- goto out;
- }
- pos += ret;
- }
-
- if (cnt)
- error = 0;
- out:
- if (error) {
- free(args);
- args = NULL;
- }
-
- *args_out = args;
- return error;
-}
-
-static int use_device_status(int cd, char *victim, char *method, int d,
- char *device, struct fence_log *lp)
-{
- char path[PATH_MAX], *agent, *args = NULL;
- int error;
-
- memset(path, 0, PATH_MAX);
- sprintf(path, AGENT_NAME_PATH, device);
-
- error = ccs_get(cd, path, &agent);
- if (error) {
- lp->error = FE_READ_AGENT;
- goto out;
- }
-
- strncpy(lp->agent_name, agent, FENCE_AGENT_NAME_MAX-1);
-
- error = make_args_status(cd, victim, method, d, device, &args);
- if (error) {
- lp->error = FE_READ_ARGS;
- goto out_agent;
- }
-
- strncpy(lp->agent_args, args, FENCE_AGENT_ARGS_MAX-1);
-
- error = run_agent_status(agent, args, &lp->error);
-
- free(args);
- out_agent:
- free(agent);
- out:
- return error;
-}
-
-/* We want to run status on each device in each method, and we need all
- to succeed in order for status as a whole to succeed. Agent success
- for status is being either "on" (exit 0) or "off" (exit 2). Agent
- failure for status is when the on/off state is unknown (exit 1),
- i.e. the agent failed to run or ran and cannot connect, or cannot get
- the on/off state for some reason.
-
- As soon as any one device in any method fails, we can quit and report
- failure (rv < 0) for status as a whole. If status of all devices is
- "on", then status as a whole returns 0. If status of all devices are
- "off", then status as a whole returns 2. If the status of all devices
- are mixed on/off, then status as a whole returns 0. */
-
-int fence_node_status(char *victim, struct fence_log *log, int log_size,
- int *log_count, int use_method_num)
-{
- struct fence_log stub;
- struct fence_log *lp = log;
- char *method = NULL, *device = NULL;
- char *victim_nodename = NULL;
- int num_methods, num_devices, m, d, cd, rv;
- int on_count = 0, off_count = 0;
- int left = log_size;
- int error = -1;
- int count = 0;
-
- cd = ccs_connect();
- if (cd < 0) {
- if (lp && left) {
- lp->error = FE_NO_CONFIG;
- lp++;
- left--;
- }
- count++;
- error = -1;
- goto ret;
- }
-
- if (ccs_lookup_nodename(cd, victim, &victim_nodename) == 0)
- victim = victim_nodename;
-
- num_methods = count_methods(cd, victim);
- if (!num_methods) {
- if (lp && left) {
- lp->error = FE_NO_METHOD;
- lp++;
- left--;
- }
- count++;
- error = -2; /* No fencing */
- goto out;
- }
-
- if (use_method_num && (use_method_num > num_methods)) {
- if (lp && left) {
- lp->error = FE_NUM_METHOD;
- lp++;
- left--;
- }
- count++;
- error = -2; /* No fencing */
- goto out;
- }
-
- for (m = 0; m < num_methods; m++) {
-
- if (use_method_num && (m + 1 != use_method_num))
- continue;
-
- rv = get_method(cd, victim, m, &method);
- if (rv) {
- if (lp && left) {
- lp->error = FE_READ_METHOD;
- lp->method_num = m;
- lp++;
- left--;
- }
- count++;
- error = -1;
- break;
- }
-
- num_devices = count_devices(cd, victim, method);
- if (!num_devices) {
- if (lp && left) {
- lp->error = FE_NO_DEVICE;
- lp->method_num = m;
- lp++;
- left--;
- }
- count++;
- continue;
- }
-
- for (d = 0; d < num_devices; d++) {
- rv = get_device(cd, victim, method, d, &device);
- if (rv) {
- if (lp && left) {
- lp->error = FE_READ_DEVICE;
- lp->method_num = m;
- lp->device_num = d;
- lp++;
- left--;
- }
- count++;
- error = -1;
- break;
- }
-
- /* every call to use_device generates a log entry,
- whether success or fail */
-
- error = use_device_status(cd, victim, method, d, device,
- (lp && left) ? lp : &stub);
- count++;
- if (lp && left) {
- /* error, name, args already set */
- lp->method_num = m;
- lp->device_num = d;
- lp++;
- left--;
- }
-
- /*
- * error values:
- * < 0: internal error from use_device_status,
- * internal error from run_agent_status,
- * run_agent_status failed to fork agent
- * 0: agent exited with 0 (success, status is on)
- * 2: agent exited with 2 (success, status is off)
- * 1: agent exited with 1 (error, status is unknown)
- */
-
- /* internal error: status fail */
- if (error < 0)
- break;
-
- /* agent error: status fail */
- if (error == 1) {
- error = -1;
- break;
- }
-
- if (!error) {
- /* agent success "on": status success */
- on_count++;
- } else if (error == 2) {
- /* agent success "off": status success */
- error = 0;
- off_count++;
- } else {
- /* some other error */
- error = -1;
- break;
- }
-
- free(device);
- device = NULL;
- }
-
- if (device)
- free(device);
-
- free(method);
-
- /* if any device failed in this method, return failure
- for the status */
-
- if (error)
- break;
- }
-
- if (error < 0)
- goto out;
-
- /* All devices are either on or off, none are unknown/inaccessible,
- so status as a whole is a success. Decide which of the two
- success values to return: 2 if all devices are off, or 0 if
- all devices are on, 0 if mixed on/off. */
-
- if (!on_count)
- error = 2;
- else
- error = 0;
-
- out:
- if (victim_nodename)
- free(victim_nodename);
-
- ccs_disconnect(cd);
- ret:
- if (log_count)
- *log_count = count;
- return error;
-}
-
diff --git a/fence/libfence/libfence.h b/fence/libfence/libfence.h
deleted file mode 100644
index 10d00f0..0000000
--- a/fence/libfence/libfence.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef _LIBFENCE_H_
-#define _LIBFENCE_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define FE_AGENT_SUCCESS 1 /* agent exited with EXIT_SUCCESS */
-#define FE_AGENT_ERROR 2 /* agent exited with EXIT_FAILURE */
-#define FE_AGENT_FORK 3 /* error forking agent */
-#define FE_NO_CONFIG 4 /* ccs_connect error */
-#define FE_NO_METHOD 5 /* zero methods defined */
-#define FE_NO_DEVICE 6 /* zero devices defined in method */
-#define FE_READ_AGENT 7 /* read (ccs) error on agent path */
-#define FE_READ_ARGS 8 /* read (ccs) error on node/dev args */
-#define FE_READ_METHOD 9 /* read (ccs) error on method */
-#define FE_READ_DEVICE 10 /* read (ccs) error on method/device */
-#define FE_NUM_METHOD 11 /* method number does not exist */
-#define FE_AGENT_STATUS_ON 12
-#defin