Gitweb: http://git.fedorahosted.org/git/fence-agents.git?p=fence-agents.git;a=commi…
Commit: dbf856abb9f162c75a01ea3add308920434ef6c9
Parent: cca0e05d60dbdc4e7fd7389b8d0f6635038201e6
Author: Ryan O'Hara <rohara(a)redhat.com>
AuthorDate: Tue Mar 15 15:18:56 2011 -0500
Committer: Ryan O'Hara <rohara(a)redhat.com>
CommitterDate: Tue Mar 15 15:18:56 2011 -0500
fence_scsi: grep for keys should be case insensitive
When checking that a key is or is not registered for a device, the key
comparison should be case insensitive. Using sg_persist to query for
registered keys will always give lowercase characters for hexadecimal
keys, so registering key 'A' would appear to fail since it would not
match 'a'.
Resolves: rhbz#653504
Signed-off-by: Ryan O'Hara <rohara(a)redhat.com>
---
fence/agents/scsi/fence_scsi.pl | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/fence/agents/scsi/fence_scsi.pl b/fence/agents/scsi/fence_scsi.pl
index 14b0784..2751bed 100644
--- a/fence/agents/scsi/fence_scsi.pl
+++ b/fence/agents/scsi/fence_scsi.pl
@@ -73,7 +73,7 @@ sub do_action_off ($@)
log_error ("device $dev does not exist") if (! -e $dev);
log_error ("device $dev is not a block device") if (! -b $dev);
- my @keys = grep { /^$node_key$/ } get_registration_keys ($dev);
+ my @keys = grep { /^$node_key$/i } get_registration_keys ($dev);
if (scalar (@keys) != 0) {
do_preempt_abort ($host_key, $node_key, $dev);
@@ -97,7 +97,7 @@ sub do_action_status ($@)
do_reset ($dev);
- my @keys = grep { /^$node_key$/ } get_registration_keys ($dev);
+ my @keys = grep { /^$node_key$/i } get_registration_keys ($dev);
if (scalar (@keys) != 0) {
$dev_count++;
@@ -119,7 +119,7 @@ sub do_verify_on ($@)
my $count = 0;
for $dev (@devices) {
- my @keys = grep { /^$node_key$/ } get_registration_keys ($dev);
+ my @keys = grep { /^$node_key$/i } get_registration_keys ($dev);
## check that our key is registered
if (scalar (@keys) == 0) {
@@ -150,7 +150,7 @@ sub do_verify_off ($@)
my $count = 0;
for $dev (@devices) {
- my @keys = grep { /^$node_key$/ } get_registration_keys ($dev);
+ my @keys = grep { /^$node_key$/i } get_registration_keys ($dev);
## check that our key is not registered
if (scalar (@keys) != 0) {
Gitweb: http://git.fedorahosted.org/git/fence-agents.git?p=fence-agents.git;a=commi…
Commit: cca0e05d60dbdc4e7fd7389b8d0f6635038201e6
Parent: c1880d1153aaad96e206178fc7e6e32b720ef4fd
Author: Ryan O'Hara <rohara(a)redhat.com>
AuthorDate: Tue Mar 15 15:13:04 2011 -0500
Committer: Ryan O'Hara <rohara(a)redhat.com>
CommitterDate: Tue Mar 15 15:13:04 2011 -0500
fence_scsi: fix typo when opening logfile
There is a typo in the code that opens the logfile. The logfile should
be opened in append mode. This was fixed in RHEL6 quite some time ago,
but for whatever reason didn't get pushed into upstream.
Signed-off-by: Ryan O'Hara <rohara(a)redhat.com>
---
fence/agents/scsi/fence_scsi.pl | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/fence/agents/scsi/fence_scsi.pl b/fence/agents/scsi/fence_scsi.pl
index befb398..14b0784 100644
--- a/fence/agents/scsi/fence_scsi.pl
+++ b/fence/agents/scsi/fence_scsi.pl
@@ -765,7 +765,7 @@ else {
## and redirect STDOUT and STDERR to the logfile.
##
if (defined $opt_f) {
- open (LOG, >">$opt_f") or die "$!\n";
+ open (LOG, ">>$opt_f") or die "$!\n";
open (STDOUT, ">&LOG");
open (STDERR, ">&LOG");
}
Gitweb: http://git.fedorahosted.org/git/fence-agents.git?p=fence-agents.git;a=commi…
Commit: c1880d1153aaad96e206178fc7e6e32b720ef4fd
Parent: 89d4cfcf9bccec2299d3ce837930f1f3624522b2
Author: Jim Ramsay <jim_ramsay(a)dell.com>
AuthorDate: Fri Mar 4 14:04:03 2011 -0500
Committer: Ryan O'Hara <rohara(a)redhat.com>
CommitterDate: Tue Mar 15 14:46:19 2011 -0500
Allow fence_scsi to use any valid hexadecimal key
The check for a non-zero key is using perl's implicit string-to-integer
conversion that only works on base 10 digits, which means that any key
starting with at least one digit [1-9] will come through as okay, but
any key starting with [A-F] will evaluate as 0 and fail the test.
An explicit conversion to integer via hex() is the solution.
I hit this in a cluster with a cluster ID of 43316 == 0xA934 and scsi
fencing configured, where starting the cman service would always fail at
the "Unfencing self" step.
Signed-off-by: Jim Ramsay <jim_ramsay(a)dell.com>
Signed-off-by: Ryan O'Hara <rohara(a)redhat.com>
Resolves: rhbz#653504
---
fence/agents/scsi/fence_scsi.pl | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/fence/agents/scsi/fence_scsi.pl b/fence/agents/scsi/fence_scsi.pl
index 9df5c0c..befb398 100644
--- a/fence/agents/scsi/fence_scsi.pl
+++ b/fence/agents/scsi/fence_scsi.pl
@@ -787,7 +787,7 @@ else {
## verify that key is not zero
##
-if ($key == 0) {
+if (hex($key) == 0) {
log_error ("key cannot be zero");
}
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=14…
Commit: 14ff5606a01ff5b87d1fdbd785c969b523477a0f
Parent: e3872a336a8f31d8ac3f342bd6631c600ec6d5f9
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
AuthorDate: Tue Mar 15 08:22:02 2011 +0100
Committer: Fabio M. Di Nitto <fdinitto(a)redhat.com>
CommitterDate: Tue Mar 15 11:52:38 2011 +0100
cman-preconfig: allow cman to configure corosync multicast ttl
syntax:
<cman...>
<multicast ttl=".."/>
</cman>
Resolves: rhbz#684020
Acked-by: Christine Caulfield <ccaulfie(a)redhat.com>
Signed-off-by: Fabio M. Di Nitto <fdinitto(a)redhat.com>
---
cman/daemon/cman-preconfig.c | 24 +++++++++++++++++++++---
config/tools/xml/cluster.rng.in | 17 +++++++++++++++--
2 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/cman/daemon/cman-preconfig.c b/cman/daemon/cman-preconfig.c
index 4f98176..5a73fb3 100644
--- a/cman/daemon/cman-preconfig.c
+++ b/cman/daemon/cman-preconfig.c
@@ -289,7 +289,7 @@ static int add_udpu_members(struct objdb_iface_ver0 *objdb, hdb_handle_t interfa
return 0;
}
-static int add_ifaddr(struct objdb_iface_ver0 *objdb, char *mcast, char *ifaddr, int port, enum tx_mech transport)
+static int add_ifaddr(struct objdb_iface_ver0 *objdb, char *mcast, char *ifaddr, int port, int ttl, enum tx_mech transport)
{
hdb_handle_t totem_object_handle;
hdb_handle_t find_handle;
@@ -366,6 +366,19 @@ static int add_ifaddr(struct objdb_iface_ver0 *objdb, char *mcast, char *ifaddr,
objdb->object_key_create_typed(interface_object_handle, "mcastport",
tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
+ /* paranoia check. corosync already does it */
+ if ((ttl < 0) || (ttl > 255)) {
+ sprintf(error_reason, "TTL value (%u) out of range (0 - 255)", ttl);
+ return -1;
+ }
+
+ /* add the key to the objdb only if value is not default */
+ if (ttl != 1) {
+ sprintf(tmp, "%d", ttl);
+ objdb->object_key_create_typed(interface_object_handle, "ttl",
+ tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
+ }
+
num_interfaces++;
}
return ret;
@@ -608,6 +621,7 @@ static int get_nodename(struct objdb_iface_ver0 *objdb)
enum tx_mech transport = TX_MECH_UDP;
char *str;
int error;
+ unsigned int ttl = 1;
if (!getenv("CMAN_NOCONFIG")) {
/* our nodename */
@@ -677,6 +691,7 @@ static int get_nodename(struct objdb_iface_ver0 *objdb)
if (objdb->object_find_next(find_handle2, &mcast_handle) == 0) {
objdb_get_string(objdb, mcast_handle, "addr", &mcast_name);
+ objdb_get_int(objdb, mcast_handle, "ttl", &ttl, 0);
}
objdb->object_find_destroy(find_handle2);
}
@@ -743,7 +758,7 @@ static int get_nodename(struct objdb_iface_ver0 *objdb)
}
}
- if (add_ifaddr(objdb, mcast_name, nodename, portnum, transport)) {
+ if (add_ifaddr(objdb, mcast_name, nodename, portnum, ttl, transport)) {
write_cman_pipe(error_reason);
return -1;
}
@@ -753,6 +768,7 @@ static int get_nodename(struct objdb_iface_ver0 *objdb)
objdb->object_find_create(node_object_handle,"altname", strlen("altname"), &find_handle);
while (objdb->object_find_next(find_handle, &alt_object) == 0) {
unsigned int port;
+ unsigned int altttl = 1;
char *node;
char *mcast;
@@ -762,11 +778,13 @@ static int get_nodename(struct objdb_iface_ver0 *objdb)
objdb_get_int(objdb, alt_object, "port", &port, portnum);
+ objdb_get_int(objdb, alt_object, "ttl", &altttl, ttl);
+
if (objdb_get_string(objdb, alt_object, "mcast", &mcast)) {
mcast = mcast_name;
}
- if (add_ifaddr(objdb, mcast, node, portnum, transport)) {
+ if (add_ifaddr(objdb, mcast, node, portnum, altttl, transport)) {
write_cman_pipe(error_reason);
return -1;
}
diff --git a/config/tools/xml/cluster.rng.in b/config/tools/xml/cluster.rng.in
index 75bbd28..821fb82 100644
--- a/config/tools/xml/cluster.rng.in
+++ b/config/tools/xml/cluster.rng.in
@@ -147,14 +147,22 @@ To validate your cluster.conf against this schema, run:
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."> <attribute
- name="addr" rha:description="A multicast address specified
+ forms the lower 16 bits based on the cluster ID.">
+ <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>
</element>
</optional>
</element>
@@ -734,6 +742,11 @@ To validate your cluster.conf against this schema, run:
<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>
</optional>
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=0f…
Commit: 0f5af364300d3ddb2de2428de2f169be917a3c15
Parent: 4a14778e8bb739fb06abe575d5564b4a7e5079ad
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
AuthorDate: Tue Mar 15 08:22:02 2011 +0100
Committer: Fabio M. Di Nitto <fdinitto(a)redhat.com>
CommitterDate: Tue Mar 15 08:55:45 2011 +0100
cman-preconfig: allow cman to configure corosync multicast ttl
syntax:
<cman...>
<multicast ttl=".."/>
</cman>
Resolves: rhbz#684020
Signed-off-by: Fabio M. Di Nitto <fdinitto(a)redhat.com>
---
cman/daemon/cman-preconfig.c | 24 +++++++++++++++++++++---
config/tools/xml/cluster.rng.in | 17 +++++++++++++++--
2 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/cman/daemon/cman-preconfig.c b/cman/daemon/cman-preconfig.c
index 5239d89..0b3e7fd 100644
--- a/cman/daemon/cman-preconfig.c
+++ b/cman/daemon/cman-preconfig.c
@@ -276,7 +276,7 @@ static int add_udpu_members(struct objdb_iface_ver0 *objdb, hdb_handle_t interfa
return 0;
}
-static int add_ifaddr(struct objdb_iface_ver0 *objdb, char *mcast, char *ifaddr, int port, enum tx_mech transport)
+static int add_ifaddr(struct objdb_iface_ver0 *objdb, char *mcast, char *ifaddr, int port, int ttl, enum tx_mech transport)
{
hdb_handle_t totem_object_handle;
hdb_handle_t find_handle;
@@ -353,6 +353,19 @@ static int add_ifaddr(struct objdb_iface_ver0 *objdb, char *mcast, char *ifaddr,
objdb->object_key_create_typed(interface_object_handle, "mcastport",
tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
+ /* paranoia check. corosync already does it */
+ if ((ttl < 0) || (ttl > 255)) {
+ sprintf(error_reason, "TTL value (%u) out of range (0 - 255)", ttl);
+ return -1;
+ }
+
+ /* add the key to the objdb only if value is not default */
+ if (ttl != 1) {
+ sprintf(tmp, "%d", ttl);
+ objdb->object_key_create_typed(interface_object_handle, "ttl",
+ tmp, strlen(tmp)+1, OBJDB_VALUETYPE_STRING);
+ }
+
num_interfaces++;
}
return ret;
@@ -592,6 +605,7 @@ static int get_nodename(struct objdb_iface_ver0 *objdb)
enum tx_mech transport = TX_MECH_UDP;
char *str;
int error;
+ unsigned int ttl = 1;
if (!getenv("CMAN_NOCONFIG")) {
/* our nodename */
@@ -661,6 +675,7 @@ static int get_nodename(struct objdb_iface_ver0 *objdb)
if (objdb->object_find_next(find_handle2, &mcast_handle) == 0) {
objdb_get_string(objdb, mcast_handle, "addr", &mcast_name);
+ objdb_get_int(objdb, mcast_handle, "ttl", &ttl, 0);
}
objdb->object_find_destroy(find_handle2);
}
@@ -730,7 +745,7 @@ static int get_nodename(struct objdb_iface_ver0 *objdb)
}
}
- if (add_ifaddr(objdb, mcast_name, nodename, portnum, transport)) {
+ if (add_ifaddr(objdb, mcast_name, nodename, portnum, ttl, transport)) {
write_cman_pipe(error_reason);
return -1;
}
@@ -740,6 +755,7 @@ static int get_nodename(struct objdb_iface_ver0 *objdb)
objdb->object_find_create(node_object_handle,"altname", strlen("altname"), &find_handle);
while (objdb->object_find_next(find_handle, &alt_object) == 0) {
unsigned int port;
+ unsigned int altttl = 1;
char *node;
char *mcast;
@@ -749,11 +765,13 @@ static int get_nodename(struct objdb_iface_ver0 *objdb)
objdb_get_int(objdb, alt_object, "port", &port, portnum);
+ objdb_get_int(objdb, alt_object, "ttl", &altttl, ttl);
+
if (objdb_get_string(objdb, alt_object, "mcast", &mcast)) {
mcast = mcast_name;
}
- if (add_ifaddr(objdb, mcast, node, portnum, transport)) {
+ if (add_ifaddr(objdb, mcast, node, portnum, altttl, transport)) {
write_cman_pipe(error_reason);
return -1;
}
diff --git a/config/tools/xml/cluster.rng.in b/config/tools/xml/cluster.rng.in
index 04906c9..c873cae 100644
--- a/config/tools/xml/cluster.rng.in
+++ b/config/tools/xml/cluster.rng.in
@@ -147,14 +147,22 @@ To validate your cluster.conf against this schema, run:
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."> <attribute
- name="addr" rha:description="A multicast address specified
+ forms the lower 16 bits based on the cluster ID.">
+ <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>
</element>
</optional>
</element>
@@ -734,6 +742,11 @@ To validate your cluster.conf against this schema, run:
<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>
</optional>
Gitweb: http://git.fedorahosted.org/git/fence-agents.git?p=fence-agents.git;a=commi…
Commit: 89d4cfcf9bccec2299d3ce837930f1f3624522b2
Parent: eb08d9febd107f80616c3e36b3bd48e1bfe38934
Author: Arnaud Quette <aquette.dev(a)gmail.com>
AuthorDate: Fri Mar 11 14:28:33 2011 +0100
Committer: Fabio M. Di Nitto <fdinitto(a)redhat.com>
CommitterDate: Fri Mar 11 14:28:33 2011 +0100
eaton_snmp: fix list offset
Signed-off-by: Fabio M. Di Nitto <fdinitto(a)redhat.com>
---
fence/agents/eaton_snmp/fence_eaton_snmp.py | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/fence/agents/eaton_snmp/fence_eaton_snmp.py b/fence/agents/eaton_snmp/fence_eaton_snmp.py
index 18df1cb..81d9810 100644
--- a/fence/agents/eaton_snmp/fence_eaton_snmp.py
+++ b/fence/agents/eaton_snmp/fence_eaton_snmp.py
@@ -120,9 +120,13 @@ def get_outlets_status(conn, options):
for x in res_ports:
t=x[0].split('.')
- port_num=((device.has_switches) and "%s:%s"%(t[len(t)-3],t[len(t)-1]) or "%s"%(t[len(t)-1]))
+ # Plug indexing start from zero, so we substract '1' from the
+ # user's given plug number
+ port_num=str(int(((device.has_switches) and "%s:%s"%(t[len(t)-3],t[len(t)-1]) or "%s"%(t[len(t)-1]))) + 1)
- port_name=x[1].strip('"')
+ # Plug indexing start from zero, so we add '1'
+ # for the user's exposed plug number
+ port_name=str(int(x[1].strip('"')) + 1)
port_status=""
result[port_num]=(port_name,port_status)
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=aa…
Commit: aabd30fca943f8c865691bbc76ddb045c1ec0a33
Parent: 01af75d8f464e4c2d4a38c12e9a18c9b3d0008f4
Author: Fabio M. Di Nitto <fdinitto(a)redhat.com>
AuthorDate: Thu Nov 25 10:21:00 2010 +0100
Committer: Fabio M. Di Nitto <fdinitto(a)redhat.com>
CommitterDate: Thu Nov 25 10:21:00 2010 +0100
obsolete master branch
Signed-off-by: Fabio M. Di Nitto <fdinitto(a)redhat.com>
---
Makefile.am | 32 -
README | 3 +
autogen.sh | 4 -
bindings/Makefile.am | 3 -
bindings/perl/Makefile.am | 3 -
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.am | 59 -
bindings/perl/ccs/test.pl | 20 -
bindings/perl/ccs/typemap | 1 -
cman/Makefile.am | 4 -
cman/cman_tool/Makefile.am | 17 -
cman/cman_tool/cman_tool.h | 100 --
cman/cman_tool/join.c | 335 -----
cman/cman_tool/main.c | 1014 -------------
cman/config/Makefile.am | 14 -
cman/config/cman-preconfig.c | 1262 ----------------
cman/config/cman.h | 15 -
cman/config/nodelist.h | 93 --
cman/init.d/cman.in | 748 ----------
cman/man/Makefile.am | 8 -
cman/man/cman.5 | 222 ---
cman/man/cman_tool.8 | 345 -----
cman/man/cmannotifyd.8 | 66 -
cman/man/mkqdisk.8 | 31 -
cman/man/qdisk.5 | 478 ------
cman/man/qdiskd.8 | 25 -
cman/notifyd/Makefile.am | 41 -
cman/notifyd/cman_notify.in | 40 -
cman/notifyd/main.c | 506 -------
cman/qdisk/Makefile.am | 28 -
cman/qdisk/bitmap.c | 93 --
cman/qdisk/daemon_init.c | 239 ---
cman/qdisk/disk.c | 792 ----------
cman/qdisk/disk.h | 285 ----
cman/qdisk/disk_util.c | 267 ----
cman/qdisk/iostate.c | 145 --
cman/qdisk/iostate.h | 17 -
cman/qdisk/main.c | 1879 ------------------------
cman/qdisk/mkqdisk.c | 95 --
cman/qdisk/platform.h | 40 -
cman/qdisk/proc.c | 265 ----
cman/qdisk/scandisk.c | 766 ----------
cman/qdisk/scandisk.h | 86 --
cman/qdisk/score.c | 424 ------
cman/qdisk/score.h | 44 -
cman/services/Makefile.am | 3 -
cman/services/cman/Makefile.am | 3 -
cman/services/cman/include/Makefile.am | 3 -
cman/services/cman/include/corosync/cman.h | 39 -
cman/services/cman/include/corosync/ipc_cman.h | 58 -
cman/services/cman/lib/Makefile.am | 21 -
cman/services/cman/lib/libcman.c | 1274 ----------------
cman/services/cman/lib/libcman.h | 418 ------
cman/services/cman/lib/libcman.pc.in | 11 -
cman/services/cman/services/Makefile.am | 14 -
cman/services/cman/services/cman.c | 571 -------
cman/tests/Makefile.am | 13 -
cman/tests/client.c | 115 --
cman/tests/libtest.c | 134 --
cman/tests/qwait.c | 60 -
cman/tests/sysman.c | 75 -
cman/tests/sysmand.c | 472 ------
cman/tests/user_service.c | 287 ----
common/Makefile.am | 3 -
common/liblogthread/Makefile.am | 14 -
common/liblogthread/liblogthread.c | 336 -----
common/liblogthread/liblogthread.h | 19 -
common/liblogthread/liblogthread.pc.in | 11 -
config/Makefile.am | 3 -
config/libs/Makefile.am | 3 -
config/libs/libccsconfdb/Makefile.am | 24 -
config/libs/libccsconfdb/ccs.h | 16 -
config/libs/libccsconfdb/ccs_internal.h | 29 -
config/libs/libccsconfdb/extras.c | 449 ------
config/libs/libccsconfdb/fullxpath.c | 327 ----
config/libs/libccsconfdb/libccs.c | 651 --------
config/libs/libccsconfdb/libccs.pc.in | 11 -
config/libs/libccsconfdb/xpathlite.c | 426 ------
config/man/Makefile.am | 3 -
config/man/cluster.conf.5 | 208 ---
config/plugins/Makefile.am | 3 -
config/plugins/ldap/99cluster.ldif | 138 --
config/plugins/ldap/Makefile.am | 15 -
config/plugins/ldap/configldap.c | 288 ----
config/plugins/ldap/example.ldif | 137 --
config/plugins/xml/Makefile.am | 14 -
config/plugins/xml/config.c | 150 --
config/tools/Makefile.am | 3 -
config/tools/ccs_tool/Makefile.am | 24 -
config/tools/ccs_tool/ccs_tool.c | 309 ----
config/tools/ccs_tool/editconf.c | 1252 ----------------
config/tools/ccs_tool/editconf.h | 8 -
config/tools/ldap/Makefile.am | 9 -
config/tools/ldap/confdb2ldif.c | 203 ---
config/tools/man/Makefile.am | 4 -
config/tools/man/ccs_tool.8 | 185 ---
config/tools/man/confdb2ldif.8 | 64 -
config/tools/mkconf/Makefile.am | 14 -
config/tools/mkconf/mkconf.c | 248 ----
configure.ac | 308 ----
doc/COPYING.applications | 339 -----
doc/COPYING.libraries | 510 -------
doc/COPYRIGHT | 58 -
doc/Makefile.am | 34 -
doc/README.licence | 33 -
doc/cluster.logrotate.in | 8 -
doc/cman_notify_template.sh | 57 -
doc/gfs2.txt | 45 -
doc/journaling.txt | 155 --
doc/min-gfs.txt | 159 --
doc/usage.txt | 177 ---
group/Makefile.am | 3 -
group/man/Makefile.am | 3 -
group/man/group_tool.8 | 61 -
group/tool/Makefile.am | 5 -
group/tool/main.c | 147 --
make/copyright.cf | 6 -
make/lcrso.mk | 23 -
122 files changed, 3 insertions(+), 22529 deletions(-)
diff --git a/Makefile.am b/Makefile.am
deleted file mode 100644
index b845c7a..0000000
--- a/Makefile.am
+++ /dev/null
@@ -1,32 +0,0 @@
-EXTRA_DIST = autogen.sh make/lcrso.mk
-
-AUTOMAKE_OPTIONS = foreign
-
-MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure depcomp \
- config.guess config.sub missing install-sh \
- autoheader automake autoconf libtool libtoolize \
- ltmain.sh compile make/clusterautoconfig.h.in \
- make/clusterautoconfig.h.in~
-
-noinst_HEADERS = make/copyright.cf
-
-ACLOCAL_AMFLAGS = -I m4
-
-SUBDIRS = common config cman group doc
-
-if BUILD_BINDINGS
-SUBDIRS += bindings
-endif
-
-install-exec-local:
- $(INSTALL) -d $(DESTDIR)/$(LOGDIR)
- $(INSTALL) -d $(DESTDIR)/$(CLUSTERVARRUN)
- $(INSTALL) -d $(DESTDIR)/$(CLUSTERVARLIB)
-
-uninstall-local:
- rmdir $(DESTDIR)/$(LOGDIR) || :;
- rmdir $(DESTDIR)/$(CLUSTERVARRUN) || :;
- rmdir $(DESTDIR)/$(CLUSTERVARLIB) || :;
-
-maintainer-clean-local:
- rm -rf m4
diff --git a/README b/README
new file mode 100644
index 0000000..d2d00c9
--- /dev/null
+++ b/README
@@ -0,0 +1,3 @@
+cluster.git master branch is no longer actively developed.
+
+Please refer to STABLE31 branch or RHEL6 branch for stable releases.
diff --git a/autogen.sh b/autogen.sh
deleted file mode 100755
index 3c5e1d9..0000000
--- a/autogen.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-# Run this to generate all the initial makefiles, etc.
-mkdir -p m4
-autoreconf -i -v && echo Now run ./configure and make
diff --git a/bindings/Makefile.am b/bindings/Makefile.am
deleted file mode 100644
index 4e80eeb..0000000
--- a/bindings/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-SUBDIRS = perl
diff --git a/bindings/perl/Makefile.am b/bindings/perl/Makefile.am
deleted file mode 100644
index 5d953b3..0000000
--- a/bindings/perl/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-SUBDIRS = ccs
diff --git a/bindings/perl/ccs/CCS.pm.in b/bindings/perl/ccs/CCS.pm.in
deleted file mode 100644
index 1dc5c24..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 0bde4d4..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.am b/bindings/perl/ccs/Makefile.am
deleted file mode 100644
index 1fa5dcd..0000000
--- a/bindings/perl/ccs/Makefile.am
+++ /dev/null
@@ -1,59 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-PERL_TARGET = CCS.pm META.yml
-
-PERL_MAKEFILE = Makefile.perl
-
-PERL_MAKEFILEPL = Makefile.PL
-
-LINK_SRCS = CCS.xs typemap test.pl
-
-EXTRA_DIST = $(PERL_MAKEFILE_PL) $(LINK_SRCS) \
- CCS.pm.in META.yml.in
-
-AM_CPPFLAGS = -I$(top_srcdir)/config/libs/libccsconfdb/
-
-AM_LDFLAGS = -L$(top_builddir)/config/libs/libccsconfdb/.libs -lccs
-
-all-local: linkcode $(PERL_MAKEFILE) $(PERL_TARGET)
- ${MAKE} -f $(PERL_MAKEFILE) LD_RUN_PATH="";
-
-%.pm: $(srcdir)/%.pm.in
- cat $< | \
- sed \
- -e 's/_VERSION_/${PACKAGE_VERSION}/g' \
- > $@
-
-%.yml: $(srcdir)/%.yml.in
- cat $< | \
- sed \
- -e 's/_VERSION_/${PACKAGE_VERSION}/g' \
- > $@
-
-$(PERL_MAKEFILE): linkcode $(PERL_TARGET) Makefile
- perl $(PERL_MAKEFILEPL) \
- FIRST_MAKEFILE=$@ \
- INC='$(AM_CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)' \
- LIBS='$(AM_LDFLAGS) $(LDFLAGS)' \
- INSTALLDIRS=vendor
-
-linkcode:
- if [ ! -e $(PERL_MAKEFILEPL) ]; then \
- for i in $(PERL_MAKEFILEPL) $(LINK_SRCS); do \
- $(LN_S) $(srcdir)/$$i $$i; \
- done; \
- touch linkcode; \
- fi
-
-clean-local:
- -${MAKE} -f $(PERL_MAKEFILE) clean
- rm -f $(PERL_TARGET) *.old
- if [ -e linkcode ]; then \
- rm -f $(PERL_MAKEFILEPL) $(LINK_SRCS) linkcode; \
- fi
-
-install-exec-local:
- ${MAKE} -f $(PERL_MAKEFILE) install ;
-
-uninstall-local:
- echo "MakeMaker does not support uninstall."
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/cman/Makefile.am b/cman/Makefile.am
deleted file mode 100644
index 673ca3a..0000000
--- a/cman/Makefile.am
+++ /dev/null
@@ -1,4 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-# don't do init for now.
-SUBDIRS = services cman_tool config qdisk notifyd man tests # init.d
diff --git a/cman/cman_tool/Makefile.am b/cman/cman_tool/Makefile.am
deleted file mode 100644
index 4972f1f..0000000
--- a/cman/cman_tool/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-sbin_PROGRAMS = cman_tool
-
-noinst_HEADERS = cman_tool.h
-
-cman_tool_SOURCES = main.c join.c
-
-cman_tool_CPPFLAGS = -I$(top_srcdir)/cman/services/cman/lib/ \
- -I$(top_srcdir)/config/libs/libccsconfdb/
-
-cman_tool_CFLAGS = $(votequorum_CFLAGS)
-
-cman_tool_LDFLAGS = $(votequorum_LIBS)
-
-cman_tool_LDADD = $(top_builddir)/cman/services/cman/lib/libcman.la \
- $(top_builddir)/config/libs/libccsconfdb/libccs.la
diff --git a/cman/cman_tool/cman_tool.h b/cman/cman_tool/cman_tool.h
deleted file mode 100644
index 3766ee2..0000000
--- a/cman/cman_tool/cman_tool.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef __CMAN_TOOL_DOT_H__
-#define __CMAN_TOOL_DOT_H__
-
-#include <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,
-};
-
-struct commandline
-{
- int operation;
- int num_nodenames;
- char *multicast_addr;
- char *nodenames[MAX_INTERFACES];
- char *interfaces[MAX_INTERFACES];
- char *override_nodename;
- char *key_filename;
- char *filename;
- char *format_opts;
- char *config_lcrso;
- int votes;
- int expected_votes;
- int two_node;
- int port;
- char clustername[MAX_CLUSTER_NAME_LEN];
- int remove;
- int force;
- int verbose;
- int nodeid;
- int timeout;
- unsigned int config_version;
-
- int config_version_opt;
- int votes_opt;
- int expected_votes_opt;
- int port_opt;
- int nodeid_opt;
- int clustername_opt;
- int wait_opt;
- int wait_quorate_opt;
- int fence_opt;
- int addresses_opt;
- int noconfig_opt;
- int nosetpri_opt;
- int noopenais_opt;
-};
-typedef struct commandline commandline_t;
-
-int join(commandline_t *comline, char *envp[]);
-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 fd6d743..0000000
--- a/cman/cman_tool/join.c
+++ /dev/null
@@ -1,335 +0,0 @@
-#include "clusterautoconfig.h"
-
-#include <sys/wait.h>
-#include <stdint.h>
-#include <signal.h>
-#include <netinet/in.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(int close_stderr)
-{
- int devnull = open("/dev/null", O_RDWR);
- if (devnull == -1) {
- perror("Can't open /dev/null");
- exit(3);
- }
-
- /* Detach ourself from the calling environment */
- if (close(0) || close(1)) {
- die("Error closing terminal FDs");
- }
-
- if (dup2(devnull, 0) < 0 || dup2(devnull, 1) < 0) {
- die("Error setting terminal FDs to /dev/null: %m");
- }
-
- if (close_stderr) {
- if (close(2)) {
- die("Error closing stderr FD");
- }
- if (!dup2(devnull, 2) < 0) {
- die("Error setting stderr FD to /dev/null: %m");
- }
- }
-
- setsid();
-}
-
-
-static const char *corosync_exit_reason(signed char status)
-{
- static char reason[256];
- switch (status) {
- case -2:
- return "Could not determine UID to run as";
- break;
- case -3:
- return "Could not determine GID to run as";
- break;
- case -4:
- return "Error initialising memory pool";
- break;
- case -5:
- return "Could not fork";
- break;
- case -6:
- return "Could not bind to libais socket";
- break;
- case -7:
- return "Could not bind to network socket";
- break;
- case -8:
- return "Could not read security key for communications";
- break;
- case -9:
- return "Could not read cluster configuration";
- break;
- case -10:
- 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;
- 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 == 0 || 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];
- cman_handle_t h = NULL;
- int status;
- pid_t corosync_pid;
- int p[2];
-
- /*
- * If we can talk to cman then we're already joined (or joining);
- */
- h = cman_admin_init(NULL);
- if (h)
- die("Node is already active");
-
- /* Set up environment variables for override */
- if (comline->multicast_addr) {
- snprintf(scratch, sizeof(scratch), "CMAN_MCAST_ADDR=%s", comline->multicast_addr);
- envp[envptr++] = strdup(scratch);
- }
- if (comline->votes_opt) {
- snprintf(scratch, sizeof(scratch), "CMAN_VOTES=%d", comline->votes);
- envp[envptr++] = strdup(scratch);
- }
- if (comline->expected_votes_opt) {
- snprintf(scratch, sizeof(scratch), "CMAN_EXPECTEDVOTES=%d", comline->expected_votes);
- envp[envptr++] = strdup(scratch);
- }
- if (comline->port) {
- snprintf(scratch, sizeof(scratch), "CMAN_IP_PORT=%d", comline->port);
- envp[envptr++] = strdup(scratch);
- }
- if (comline->nodeid) {
- snprintf(scratch, sizeof(scratch), "CMAN_NODEID=%d", comline->nodeid);
- envp[envptr++] = strdup(scratch);
- }
- if (comline->clustername_opt) {
- snprintf(scratch, sizeof(scratch), "CMAN_CLUSTER_NAME=%s", comline->clustername);
- envp[envptr++] = strdup(scratch);
- }
- if (comline->nodenames[0]) {
- snprintf(scratch, sizeof(scratch), "CMAN_NODENAME=%s", comline->nodenames[0]);
- envp[envptr++] = strdup(scratch);
- }
- if (comline->key_filename) {
- snprintf(scratch, sizeof(scratch), "CMAN_KEYFILE=%s", comline->key_filename);
- envp[envptr++] = strdup(scratch);
- }
- if (comline->two_node) {
- snprintf(scratch, sizeof(scratch), "CMAN_2NODE=true");
- envp[envptr++] = strdup(scratch);
- }
- if (comline->verbose ^ DEBUG_STARTUP_ONLY) {
- snprintf(scratch, sizeof(scratch), "CMAN_DEBUGLOG=%d", comline->verbose);
- envp[envptr++] = strdup(scratch);
- }
- if (comline->noconfig_opt) {
- envp[envptr++] = strdup("CMAN_NOCONFIG=true");
- snprintf(scratch, sizeof(scratch), "COROSYNC_DEFAULT_CONFIG_IFACE=cmanpreconfig%s",
- comline->noopenais_opt?"":":openaisserviceenablestable");
- envp[envptr++] = strdup(scratch);
- }
- else {
- snprintf(scratch, sizeof(scratch), "COROSYNC_DEFAULT_CONFIG_IFACE=%s:cmanpreconfig%s", comline->config_lcrso,
- comline->noopenais_opt?"":":openaisserviceenablestable");
- 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(!(comline->verbose & ~DEBUG_STARTUP_ONLY));
-
- 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);
- 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);
- }
- }
-
- } 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);
- return 0;
-}
diff --git a/cman/cman_tool/main.c b/cman/cman_tool/main.c
deleted file mode 100644
index 4985e76..0000000
--- a/cman/cman_tool/main.c
+++ /dev/null
@@ -1,1014 +0,0 @@
-#include "clusterautoconfig.h"
-
-#include <inttypes.h>
-#include <unistd.h>
-#include <signal.h>
-#include <time.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:r:i:N:t:o:k:F:C:VAPwfqah?Xd::")
-#define OP_JOIN 1
-#define OP_LEAVE 2
-#define OP_EXPECTED 3
-#define OP_VOTES 4
-#define OP_KILL 5
-#define OP_VERSION 6
-#define OP_WAIT 7
-#define OP_STATUS 8
-#define OP_NODES 9
-#define OP_SERVICES 10
-#define OP_DEBUG 11
-
-
-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 AIS communications\n");
- printf(" -P Don't set aisexec to realtime priority\n");
- printf(" -X Use internal cman defaults for configuration\n");
- printf(" -A Don't load openais services\n");
- printf("\n");
- }
-
-
- if (!subcmd || subcmd == OP_WAIT) {
- printf("wait Wait until the node is a member of a cluster\n");
- printf(" -q Wait until the cluster is quorate\n");
- printf(" -t Maximum time (in seconds) to wait\n");
- printf("\n");
- }
-
- if (!subcmd || subcmd == OP_LEAVE) {
- printf("leave\n");
- printf(" -w If cluster is in transition, wait and keep trying\n");
- printf(" -t Maximum time (in seconds) to wait\n");
- printf(" remove Tell other nodes to ajust quorum downwards if necessary\n");
- printf(" force Leave even if cluster subsystems are active\n");
- printf("\n");
- }
-
- if (!subcmd || subcmd == OP_KILL) {
- printf("kill\n");
- printf(" -n <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(" -f Also show when node was last fenced\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 <config> A new config version to set on all members\n");
- printf("\n");
- }
-}
-
-static void sigalarm_handler(int sig)
-{
- fprintf(stderr, "Timed-out waiting for cluster\n");
- exit(2);
-}
-
-static 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 numaddrs;
- struct cman_node_address addrs[MAX_INTERFACES];
- int quorate;
- int i;
-
- 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("Flags:");
- if (einfo->ei_flags & CMAN_EXTRA_FLAG_2NODE)
- printf(" 2node");
- if (einfo->ei_flags & CMAN_EXTRA_FLAG_DISALLOWED)
- printf(" DisallowedNodes");
- if (einfo->ei_flags & CMAN_EXTRA_FLAG_HASSTATE)
- printf(" HasState");
- if (einfo->ei_flags & CMAN_EXTRA_FLAG_NOCONFIG)
- printf(" NoConfig");
- printf(" \n");
-
- memset(&node, 0, sizeof(node));
- 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);
- }
- if (einfo->ei_num_addresses > 0) {
- printf("Multicast addresses: %s\n", einfo->ei_addresses);
- }
-
- if (cman_get_node_addrs(h, CMAN_NODEID_US, MAX_INTERFACES, &numaddrs, addrs) == 0) {
- printf("Node addresses: ");
- for (i = 0; i < numaddrs; i++)
- {
- print_address(addrs[i].cna_address);
- printf(" ");
- }
- 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;
-
- return FMT_NONE;
-}
-
-
-static void print_node(commandline_t *comline, cman_handle_t h, int *format, struct cman_node *node)
-{
- char member_type;
- int i,j,k;
- int numaddrs;
- struct cman_node_address addrs[MAX_INTERFACES];
-
- 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;
- }
-
- if (!comline->format_opts) {
- printf("%8u %c %s\n",
- node->cn_nodeid, member_type,
- 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) {
- 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_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 Id Sts 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;
-
- if (comline->expected_votes == 0) {
- die("expected_votes not specified");
- }
-
- 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);
-}
-
-
-/* This just tells corosync to reload the config file */
-static void version(commandline_t *comline)
-{
- struct cman_version ver;
- cman_handle_t h;
- int result;
-
- h = open_cman_handle(1);
-
- if ((result = cman_get_version(h, &ver)))
- die("can't get version: %s", cman_error(errno));
-
- if (ver.cv_config == -1) {
- printf("cman is running without a configuration file\n");
- goto out;
- }
-
- 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;
- }
-
- ver.cv_config = comline->config_version;
-
- if ((result = cman_set_version(h, &ver)))
- die("can't set version: %s", cman_error(errno));
- out:
- cman_finish(h);
-}
-
-static int cluster_wait(commandline_t *comline)
-{
- cman_handle_t h;
- int ret = 0;
-
- h = open_cman_handle(0);
-
- if (comline->wait_quorate_opt) {
- while (cman_is_quorate(h) <= 0) {
- sleep(1);
- }
- }
- else {
- while (cman_get_node_count(h) < 0) {
- sleep(1);
- }
- }
-
- cman_finish(h);
-
- return ret;
-}
-
-static void kill_node(commandline_t *comline)
-{
- cman_handle_t h;
- int i;
- struct cman_node node;
-
- if (!comline->num_nodenames) {
- die("No node name specified\n");
- }
-
- h = open_cman_handle(1);
-
- for (i=0; 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 0
-// TODO this should be done via cluster.conf ?
-// or can we do something directly in objdb ??
-//
- if (cman_set_debuglog(h, comline->verbose))
- perror("setting debuglog failed");
-#endif
- 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 show_help = 0;
-
- while (cont) {
- optchar = getopt(argc, argv, OPTION_STRING);
-
- switch (optchar) {
-
- case 'm':
- comline->multicast_addr = strdup(optarg);
- break;
-
- case 'f':
- comline->fence_opt = 1;
- break;
-
- case 'a':
- comline->addresses_opt = 1;
- break;
-
- case 'n':
- i = comline->num_nodenames;
- if (i >= MAX_INTERFACES)
- die("maximum of %d node names allowed",
- MAX_INTERFACES);
- if (strlen(optarg) > MAX_NODE_NAME_LEN)
- die("maximum node name length is %d",
- MAX_NODE_NAME_LEN);
- comline->nodenames[i] = strdup(optarg);
- comline->num_nodenames++;
- break;
-
- case 'o':
- comline->override_nodename = strdup(optarg);
- break;
-
- case 'k':
- comline->key_filename = strdup(optarg);
- break;
-
- case 'C':
- comline->config_lcrso = strdup(optarg);
- break;
-
- case 'r':
- comline->config_version = get_int_arg(optchar, optarg);
- comline->config_version_opt = TRUE;
- break;
-
- case 'v':
- comline->votes = get_int_arg(optchar, optarg);
- comline->votes_opt = TRUE;
- break;
-
- case 'e':
- comline->expected_votes = get_int_arg(optchar, optarg);
- comline->expected_votes_opt = TRUE;
- break;
-
- case '2':
- comline->two_node = TRUE;
- break;
-
- case 'p':
- comline->port = get_int_arg(optchar, optarg);
- comline->port_opt = TRUE;
- break;
-
- case 'N':
- comline->nodeid = get_int_arg(optchar, optarg);
- comline->nodeid_opt = TRUE;
- break;
-
- case 'c':
- if (strlen(optarg) > MAX_NODE_NAME_LEN-1)
- die("maximum cluster name length is %d",
- MAX_CLUSTER_NAME_LEN-1);
- strcpy(comline->clustername, optarg);
- comline->clustername_opt = TRUE;
- break;
-
- case 'F':
- comline->format_opts = strdup(optarg);
- break;
-
- case 'V':
- printf("cman_tool %s (built %s %s)\n",
- PACKAGE_VERSION, __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- break;
-
- case 'h':
- show_help = 1;
- break;
-
- case ':':
- case '?':
- fprintf(stderr, "Please use '-h' for usage.\n");
- exit(EXIT_FAILURE);
- break;
-
- case 'd':
- if (optarg)
- comline->verbose = atoi(optarg);
- else
- comline->verbose = 255;
- break;
-
- case 'w':
- comline->wait_opt = TRUE;
- break;
-
- case 'q':
- comline->wait_quorate_opt = TRUE;
- break;
-
- case 't':
- comline->timeout = get_int_arg(optchar, optarg);
- break;
-
- case EOF:
- cont = FALSE;
- break;
-
- case 'X':
- comline->noconfig_opt = TRUE;
- break;
-
- case 'A':
- comline->noopenais_opt = TRUE;
- break;
-
- case 'P':
- comline->nosetpri_opt = TRUE;
- break;
- default:
- die("unknown option: %c", optchar);
- break;
- };
- }
-
- 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
- die("unknown option %s", argv[optind]);
-
- optind++;
- }
-
- if (show_help) {
- print_usage(comline->operation);
- exit(EXIT_SUCCESS);
- }
-
- if (!comline->operation)
- die("no operation specified");
-}
-
-static void check_arguments(commandline_t *comline)
-{
- if (comline->two_node && comline->expected_votes != 1)
- die("expected_votes value (%d) invalid in two node mode",
- comline->expected_votes);
-
- if (comline->port_opt &&
- (comline->port <= 0 || comline->port > 65535))
- die("Port must be a number between 1 and 65535");
-
- /* This message looks like it contradicts the condition but
- a nodeid of zero simply means "assign one for me" and is a
- perfectly reasonable override */
- if (comline->nodeid < 0 || comline->nodeid > 4096)
- die("Node id must be between 1 and 4096");
-
- if (strlen(comline->clustername) > MAX_CLUSTER_NAME_LEN) {
- die("Cluster name must be < %d characters long",
- MAX_CLUSTER_NAME_LEN);
- }
-
- if (comline->timeout && !comline->wait_opt && !comline->wait_quorate_opt)
- die("timeout is only appropriate with wait");
-}
-
-int main(int argc, char *argv[], char *envp[])
-{
- commandline_t comline;
- int ret;
-
- prog_name = argv[0];
-
- memset(&comline, 0, sizeof(commandline_t));
-
- decode_arguments(argc, argv, &comline);
-
- switch (comline.operation) {
- case OP_JOIN:
- check_arguments(&comline);
-
- if (comline.timeout) {
- signal(SIGALRM, sigalarm_handler);
- alarm(comline.timeout);
- }
-
- join(&comline, envp);
- if (comline.wait_opt || comline.wait_quorate_opt) {
- do {
- ret = cluster_wait(&comline);
- if (ret == ENOTCONN)
- join(&comline, envp);
-
- } while (ret == ENOTCONN);
- }
- break;
-
- case OP_LEAVE:
- leave(&comline);
- break;
-
- case OP_EXPECTED:
- set_expected(&comline);
- break;
-
- case OP_VOTES:
- set_votes(&comline);
- break;
-
- case OP_KILL:
- kill_node(&comline);
- break;
-
- case OP_VERSION:
- version(&comline);
- break;
-
- case OP_WAIT:
- if (comline.timeout) {
- signal(SIGALRM, sigalarm_handler);
- alarm(comline.timeout);
- }
- cluster_wait(&comline);
- break;
-
- case OP_STATUS:
- show_status();
- break;
-
- case OP_NODES:
- show_nodes(&comline);
- break;
-
- case OP_SERVICES:
- if (show_services() < 0) {
- fprintf(stderr, "Unable to invoke group_tool\n");
- exit(EXIT_FAILURE);
- }
- break;
-
- case OP_DEBUG:
- set_debuglog(&comline);
- break;
- }
-
- exit(EXIT_SUCCESS);
-}
-
-char *prog_name;
diff --git a/cman/config/Makefile.am b/cman/config/Makefile.am
deleted file mode 100644
index 5bbec56..0000000
--- a/cman/config/Makefile.am
+++ /dev/null
@@ -1,14 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-AM_CFLAGS = -fPIC \
- $(cfg_CFLAGS)
-
-LCRSO = config_cmanpre.lcrso
-
-SOURCES = cman-preconfig.c
-
-EXTRA_DIST = $(SOURCES)
-
-noinst_HEADERS = cman.h nodelist.h
-
-include $(top_srcdir)/make/lcrso.mk
diff --git a/cman/config/cman-preconfig.c b/cman/config/cman-preconfig.c
deleted file mode 100644
index b22f359..0000000
--- a/cman/config/cman-preconfig.c
+++ /dev/null
@@ -1,1262 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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>
-#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 "nodelist.h"
-
-#define MAX_PATH_LEN PATH_MAX
-
-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 node_votes=0;
-static int num_interfaces;
-static int startup_pipe;
-static unsigned int cluster_id;
-static char nodename[MAX_CLUSTER_MEMBER_NAME_LEN];
-static int nodeid;
-static int two_node;
-static unsigned int disable_openais;
-static unsigned int portnum;
-static int num_nodenames;
-static char *key_filename=NULL;
-static char *mcast_name;
-static char *cluster_name;
-static char error_reason[1024] = { '\0' };
-static hdb_handle_t cluster_parent_handle;
-
-/*
- * Exports the interface for the service
- */
-static struct config_iface_ver0 cmanpreconfig_iface_ver0 = {
- .config_readconfig = cmanpre_readconfig,
- .config_reloadconfig = cmanpre_reloadconfig
-};
-
-static struct lcr_iface ifaces_ver0[2] = {
- {
- .name = "cmanpreconfig",
- .version = 0,
- .versions_replace = 0,
- .versions_replace_count = 0,
- .dependencies = 0,
- .dependency_count = 0,
- .constructor = NULL,
- .destructor = NULL,
- .interfaces = NULL,
- }
-};
-
-static struct lcr_comp cmanpre_comp_ver0 = {
- .iface_count = 1,
- .ifaces = ifaces_ver0,
-};
-
-
-
-__attribute__ ((constructor)) static void cmanpre_comp_register(void) {
- lcr_interfaces_set(&ifaces_ver0[0], &cmanpreconfig_iface_ver0);
- lcr_component_register(&cmanpre_comp_ver0);
-}
-
-static char *facility_name_get (unsigned int facility)
-{
- unsigned int i;
-
- for (i = 0; facilitynames[i].c_name != NULL; i++) {
- if (facility == facilitynames[i].c_val) {
- return (facilitynames[i].c_name);
- }
- }
- return (NULL);
-}
-
-static char *priority_name_get (unsigned int priority)
-{
- unsigned int i;
-
- for (i = 0; prioritynames[i].c_name != NULL; i++) {
- if (priority == prioritynames[i].c_val) {
- return (prioritynames[i].c_name);
- }
- }
- return (NULL);
-}
-
-
-#define LOCALHOST_IPV4 "127.0.0.1"
-#define LOCALHOST_IPV6 "::1"
-
-/* Compare two addresses */
-static int ipaddr_equal(struct sockaddr_storage *addr1, struct sockaddr_storage *addr2)
-{
- int addrlen = 0;
- struct sockaddr *saddr1 = (struct sockaddr *)addr1;
- struct sockaddr *saddr2 = (struct sockaddr *)addr2;
-
- if (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(saddr1, saddr2, 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 unsigned int 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 sum_expected(struct objdb_iface_ver0 *objdb)
-{
- int vote_sum = 0;
- hdb_handle_t nodes_handle;
- hdb_handle_t find_handle=0;
-
- nodes_handle = nodeslist_init(objdb, cluster_parent_handle, &find_handle);
- do {
- int votes;
-
- objdb_get_int(objdb, nodes_handle, "votes", (unsigned int *)&votes, 1);
- if (votes < 0) {
- votes = 1;
- }
- vote_sum += votes;
- nodes_handle = nodeslist_next(objdb, find_handle);
- } while (nodes_handle);
- objdb->object_find_destroy(find_handle);
-
- return vote_sum;
-}
-
-static int add_ifaddr(struct objdb_iface_ver0 *objdb, char *mcast, char *ifaddr, int port, int broadcast)
-{
- 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];
- int ret = 0;
-
- /* 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 address is localhost, please choose a real host address");
- return -1;
- }
-
- objdb->object_find_create(OBJECT_PARENT_HANDLE, "totem", strlen("totem"), &find_handle);
- if (objdb->object_find_next(find_handle, &totem_object_handle)) {
-
- objdb->object_create(OBJECT_PARENT_HANDLE, &totem_object_handle,
- "totem", strlen("totem"));
- }
- objdb->object_find_destroy(find_handle);
-
- if (objdb->object_create(totem_object_handle, &interface_object_handle,
- "interface", strlen("interface")) == 0) {
- 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(interface_object_handle, "ringnumber", strlen("ringnumber"),
- tmp, strlen(tmp)+1);
-
- 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(interface_object_handle, "bindnetaddr", strlen("bindnetaddr"),
- tmp, strlen(tmp)+1);
-
- if (broadcast)
- objdb->object_key_create(interface_object_handle, "broadcast", strlen("broadcast"),
- "yes", strlen("yes")+1);
- else
- objdb->object_key_create(interface_object_handle, "mcastaddr", strlen("mcastaddr"),
- mcast, strlen(mcast)+1);
-
- sprintf(tmp, "%d", port);
- objdb->object_key_create(interface_object_handle, "mcastport", strlen("mcastport"),
- tmp, strlen(tmp)+1);
-
- num_interfaces++;
- }
- return ret;
-}
-
-static uint16_t generate_cluster_id(char *name)
-{
- int i;
- int value = 0;
-
- for (i=0; i<strlen(name); i++) {
- value <<= 1;
- value += name[i];
- }
- sprintf(error_reason, "Generated cluster id for '%s' is %d\n", name, value & 0xFFFF);
- return value & 0xFFFF;
-}
-
-static char *default_mcast(char *node, uint16_t clusterid)
-{
- struct addrinfo *ainfo;
- struct addrinfo ahints;
- int ret;
- int family;
- static char addr[132];
-
- 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);
- 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 addr;
- }
- if (family == AF_INET6) {
- snprintf(addr, sizeof(addr), "ff15::%x", clusterid);
- return 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 error;
-
- /* 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.
- NOTE: This is IPv4 only */
- error = getifaddrs(&ifa_list);
- if (error)
- 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);
-
- error = getnameinfo(sa, salen, nodename2,
- sizeof(nodename2), NULL, 0, 0);
- if (!error) {
-
- if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
- strcpy(node, nodename2);
- 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);
- goto out;
- }
- }
- }
-
- /* See if it's the IP address that's in cluster.conf */
- error = getnameinfo(sa, sizeof(*sa), nodename2,
- sizeof(nodename2), NULL, 0, NI_NUMERICHOST);
- if (error)
- continue;
-
- if (nodelist_byname(objdb, cluster_parent_handle, nodename2)) {
- strcpy(node, nodename2);
- goto out;
- }
- }
-
- error = -1;
- out:
- freeifaddrs(ifa_list);
- return error;
-}
-
-/* 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 security key filename */
- if (getenv("CMAN_KEYFILE")) {
- key_filename = strdup(getenv("CMAN_KEYFILE"));
- if (key_filename == NULL) {
- sprintf(error_reason, "Cannot allocate memory for key filename");
- return -1;
- }
- }
-
- /* find our own number of votes */
- if (getenv("CMAN_VOTES")) {
- node_votes = atoi(getenv("CMAN_VOTES"));
- }
-
- /* nodeid */
- if (getenv("CMAN_NODEID")) {
- nodeid = atoi(getenv("CMAN_NODEID"));
- }
-
- if (getenv("CMAN_MCAST_ADDR")) {
- mcast_name = getenv("CMAN_MCAST_ADDR");
- }
-
- if (getenv("CMAN_2NODE")) {
- two_node = 1;
- expected_votes = 1;
- node_votes = 1;
- }
- if (getenv("CMAN_DEBUGLOG")) {
- debug = atoi(getenv("CMAN_DEBUGLOG"));
- if (debug > 0)
- debug = 1;
- }
-
- return 0;
-}
-
-
-static int get_nodename(struct objdb_iface_ver0 *objdb)
-{
- char *nodeid_str = NULL;
- char *votes_str;
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
- hdb_handle_t node_object_handle;
- hdb_handle_t alt_object;
- int broadcast = 0;
- char *str;
- int error;
-
- if (!getenv("CMAN_NOCONFIG")) {
- /* our nodename */
- if (nodename_env != NULL) {
- if (strlen(nodename_env) >= sizeof(nodename)) {
- sprintf(error_reason, "Overridden node name %s is too long", nodename);
- 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);
- 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");
- return -1;
- }
- if (!objdb_get_string(objdb, node_object_handle, "votes", &votes_str)) {
- node_votes=atoi(votes_str);
- }
- }
-
- objdb->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle);
-
- if (objdb->object_find_next(find_handle, &object_handle) == 0) {
-
- hdb_handle_t mcast_handle;
- hdb_handle_t find_handle2;
-
- if (!mcast_name) {
-
- objdb->object_find_create(object_handle, "multicast", strlen("multicast"), &find_handle2);
- if (objdb->object_find_next(find_handle2, &mcast_handle) == 0) {
-
- objdb_get_string(objdb, mcast_handle, "addr", &mcast_name);
- }
- objdb->object_find_destroy(find_handle2);
- }
-
- if (!mcast_name) {
- mcast_name = default_mcast(nodename, cluster_id);
- }
-
- /* See if the user wants our default set of openais services (default=yes) */
- objdb_get_int(objdb, object_handle, "disable_openais", &disable_openais, 0);
-
- objdb->object_key_create(object_handle, "nodename", strlen("nodename"),
- nodename, strlen(nodename)+1);
- }
- objdb->object_find_destroy(find_handle);
-
- nodeid = atoi(nodeid_str);
- error = 0;
-
- /* optional port */
- if (!portnum) {
- objdb_get_int(objdb, object_handle, "port", &portnum, DEFAULT_PORT);
- }
-
- /* Check for broadcast */
- if (!objdb_get_string(objdb, object_handle, "broadcast", &str)) {
- if (strcmp(str, "yes") == 0) {
- mcast_name = strdup("255.255.255.255");
- if (!mcast_name)
- return -1;
- broadcast = 1;
- }
- free(str);
- }
-
- if (add_ifaddr(objdb, mcast_name, nodename, portnum, broadcast)) {
- 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) {
- unsigned int port;
- char *node;
- char *mcast;
-
- if (objdb_get_string(objdb, alt_object, "name", &node)) {
- continue;
- }
-
- objdb_get_int(objdb, alt_object, "port", &port, portnum);
-
- if (objdb_get_string(objdb, alt_object, "mcast", &mcast)) {
- mcast = mcast_name;
- }
-
- if (add_ifaddr(objdb, mcast, node, portnum, broadcast)) {
- write_cman_pipe(error_reason);
- return -1;
- }
-
- num_nodenames++;
- }
- objdb->object_find_destroy(find_handle);
-
-out:
- return error;
-}
-
-/* These are basically cman overrides to the totem config bits */
-static void add_cman_overrides(struct objdb_iface_ver0 *objdb)
-{
- char *logstr;
- char *logfacility;
- char *loglevel;
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
- char tmp[256];
-
- /* "totem" key already exists, because we have added the interfaces by now */
- objdb->object_find_create(OBJECT_PARENT_HANDLE,"totem", strlen("totem"), &find_handle);
- if (objdb->object_find_next(find_handle, &object_handle) == 0)
- {
- char *value;
-
- objdb->object_key_create(object_handle, "version", strlen("version"),
- "2", 2);
-
- sprintf(tmp, "%d", nodeid);
- objdb->object_key_create(object_handle, "nodeid", strlen("nodeid"),
- tmp, strlen(tmp)+1);
-
- objdb->object_key_create(object_handle, "vsftype", strlen("vsftype"),
- "none", strlen("none")+1);
-
- /* Set the token timeout is 10 seconds, but don't overrride anything that
- might be in cluster.conf */
- if (objdb_get_string(objdb, object_handle, "token", &value)) {
- snprintf(tmp, sizeof(tmp), "%d", DEFAULT_TOKEN_TIMEOUT);
- objdb->object_key_create(object_handle, "token", strlen("token"),
- tmp, strlen(tmp)+1);
- }
- if (objdb_get_string(objdb, object_handle, "token_retransmits_before_loss_const", &value)) {
- objdb->object_key_create(object_handle, "token_retransmits_before_loss_const",
- strlen("token_retransmits_before_loss_const"),
- "20", strlen("20")+1);
- }
-
- /* Extend consensus & join timeouts per bz#214290 */
- if (objdb_get_string(objdb, object_handle, "join", &value)) {
- objdb->object_key_create(object_handle, "join", strlen("join"),
- "60", strlen("60")+1);
- }
- if (objdb_get_string(objdb, object_handle, "consensus", &value)) {
- objdb->object_key_create(object_handle, "consensus", strlen("consensus"),
- "4800", strlen("4800")+1);
- }
-
- /* Set RRP mode appropriately */
- if (objdb_get_string(objdb, object_handle, "rrp_mode", &value)) {
- if (num_interfaces > 1) {
- objdb->object_key_create(object_handle, "rrp_mode", strlen("rrp_mode"),
- "active", strlen("active")+1);
- }
- else {
- objdb->object_key_create(object_handle, "rrp_mode", strlen("rrp_mode"),
- "none", strlen("none")+1);
- }
- }
-
- if (objdb_get_string(objdb, object_handle, "secauth", &value)) {
- sprintf(tmp, "%d", 1);
- objdb->object_key_create(object_handle, "secauth", strlen("secauth"),
- tmp, strlen(tmp)+1);
- }
-
- /* optional security key filename */
- if (!key_filename) {
- objdb_get_string(objdb, object_handle, "keyfile", &key_filename);
- }
- else {
- objdb->object_key_create(object_handle, "keyfile", strlen("keyfile"),
- key_filename, strlen(key_filename)+1);
- }
- if (!key_filename) {
- /* Use the cluster name as key,
- * This isn't a good isolation strategy but it does make sure that
- * clusters on the same port/multicast by mistake don't actually interfere
- * and that we have some form of encryption going.
- */
-
- int keylen;
- memset(tmp, 0, sizeof(tmp));
-
- strcpy(tmp, cluster_name);
-
- /* Key length must be a multiple of 4 */
- keylen = (strlen(cluster_name)+4) & 0xFC;
- objdb->object_key_create(object_handle, "key", strlen("key"),
- tmp, keylen);
- }
- }
- objdb->object_find_destroy(find_handle);
-
- /* Make sure mainconfig doesn't stomp on our logging options */
- objdb->object_find_create(OBJECT_PARENT_HANDLE, "logging", strlen("logging"), &find_handle);
- if (objdb->object_find_next(find_handle, &object_handle)) {
-
- objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
- "logging", strlen("logging"));
- }
- objdb->object_find_destroy(find_handle);
-
- logfacility = facility_name_get(SYSLOGFACILITY);
- loglevel = priority_name_get(SYSLOGLEVEL);
-
- /* enable timestamps on logging */
- if (objdb_get_string(objdb, object_handle, "timestamp", &logstr)) {
- objdb->object_key_create(object_handle, "timestamp", strlen("timestamp"),
- "on", strlen("on")+1);
- }
-
- /* configure logfile */
- if (objdb_get_string(objdb, object_handle, "to_logfile", &logstr)) {
- objdb->object_key_create(object_handle, "to_logfile", strlen("to_logfile"),
- "yes", strlen("yes")+1);
- }
-
- if (objdb_get_string(objdb, object_handle, "logfile", &logstr)) {
- objdb->object_key_create(object_handle, "logfile", strlen("logfile"),
- LOGDIR "/corosync.log", strlen(LOGDIR "/corosync.log")+1);
- }
-
- if (objdb_get_string(objdb, object_handle, "logfile_priority", &logstr)) {
- objdb->object_key_create(object_handle, "logfile_priority", strlen("logfile_priority"),
- loglevel, strlen(loglevel)+1);
- }
-
- /* syslog */
- if (objdb_get_string(objdb, object_handle, "to_syslog", &logstr)) {
- objdb->object_key_create(object_handle, "to_syslog", strlen("to_syslog"),
- "yes", strlen("yes")+1);
- }
-
- if (objdb_get_string(objdb, object_handle, "syslog_facility", &logstr)) {
- objdb->object_key_create(object_handle, "syslog_facility", strlen("syslog_facility"),
- logfacility, strlen(logfacility)+1);
- }
-
- if (objdb_get_string(objdb, object_handle, "syslog_priority", &logstr)) {
- objdb->object_key_create(object_handle, "syslog_priority", strlen("syslog_priority"),
- loglevel, strlen(loglevel)+1);
- }
-
- 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(object_handle, "to_stderr", strlen("to_stderr"),
- "yes", strlen("yes")+1);
- }
-
- /* 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(object_handle, "user", strlen("user"),
- "ais", strlen("ais") + 1);
- objdb->object_key_create(object_handle, "group", strlen("group"),
- "ais", strlen("ais") + 1);
-
- objdb->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle);
- if (objdb->object_find_next(find_handle, &object_handle) == 0)
- {
- char str[255];
-
- sprintf(str, "%d", cluster_id);
-
- objdb->object_key_create(object_handle, "cluster_id", strlen("cluster_id"),
- str, strlen(str) + 1);
- }
- 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(object_handle, "name", strlen("name"),
- "corosync_quorum", strlen("corosync_quorum") + 1);
- objdb->object_key_create(object_handle, "ver", strlen("ver"),
- "0", 2);
-
- /* Make sure we load our alter-ego - the main cman module */
- objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
- "service", strlen("service"));
- objdb->object_key_create(object_handle, "name", strlen("name"),
- "corosync_cman", strlen("corosync_cman") + 1);
- objdb->object_key_create(object_handle, "ver", strlen("ver"),
- "0", 2);
-
- /* 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(object_handle, "provider", strlen("provider"),
- "corosync_votequorum", strlen("corosync_votequorum") + 1);
-
- if (!expected_votes)
- expected_votes = sum_expected(objdb);
-
- sprintf(tmp, "%d", expected_votes);
- objdb->object_key_create(object_handle, "expected_votes", strlen("expected_votes"),
- tmp, strlen(tmp)+1);
-
- sprintf(tmp, "%d", node_votes);
- objdb->object_key_create(object_handle, "votes", strlen("votes"),
- tmp, strlen(tmp)+1);
-
- if (two_node) {
- objdb->object_key_create(object_handle, "two_node", strlen("two_node"),
- "1", strlen("1") + 1);
- }
-}
-
-/* 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;
-
- /* Enforce key */
- key_filename = strdup(NOCCS_KEY_FILENAME);
- if (!key_filename) {
- sprintf(error_reason, "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");
- return -1;
- }
-
- if (!cluster_id)
- cluster_id = generate_cluster_id(cluster_name);
-
- if (!nodename_env) {
- int error;
- struct utsname utsname;
-
- error = uname(&utsname);
- if (error) {
- sprintf(error_reason, "cannot get node name, uname failed");
- return -1;
- }
-
- nodename_env = (char *)&utsname.nodename;
- }
- strcpy(nodename, nodename_env);
- num_nodenames = 1;
-
- if (!mcast_name) {
- mcast_name = default_mcast(nodename, cluster_id);
- }
-
- /* This will increase as nodes join the cluster */
- if (!expected_votes)
- expected_votes = 1;
- if (!node_votes)
- node_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);
- 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(object_handle, "name", strlen("name"),
- nodename, strlen(nodename)+1);
-
- sprintf(tmp, "%d", node_votes);
- objdb->object_key_create(object_handle, "votes", strlen("votes"),
- tmp, strlen(tmp)+1);
-
- sprintf(tmp, "%d", nodeid);
- objdb->object_key_create(object_handle, "nodeid", strlen("nodeid"),
- tmp, strlen(tmp)+1);
-
- /* Write the default cluster name */
- objdb->object_key_create(cluster_parent_handle, "name", strlen("name"),
- cluster_name, strlen(cluster_name)+1);
-
- /* Add a dummy config_version */
- sprintf(tmp, "%d", -1);
- objdb->object_key_create(cluster_parent_handle, "config_version", strlen("config_version"),
- tmp, strlen(tmp)+1);
-
- /* A flag to show there is no configuration file */
- sprintf(tmp, "%d", 1);
- objdb->object_key_create(cluster_parent_handle, "no_config", strlen("no_config"),
- tmp, strlen(tmp)+1);
-
-
- 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(new_object, &key_name, &key_name_len,
- &key_value, &key_value_len)) {
-
- objdb->object_key_create(new_object, key_name, key_name_len,
- key_value, key_value_len);
- }
-
- /* Create sub-objects */
- res = objdb->object_find_create(source_object, NULL, 0, &find_handle);
- if (res) {
- sprintf(error_reason, "error resetting object iterator for object "HDB_X_FORMAT": %d\n", source_object, res);
- return -1;
- }
-
- while ( (res = objdb->object_find_next(find_handle, &object_handle) == 0)) {
-
- /* Down we go ... */
- copy_config_tree(objdb, object_handle, new_object, 0);
- }
- objdb->object_find_destroy(find_handle);
-
- return 0;
-}
-
-/*
- * Copy trees from /cluster where they live in cluster.conf, into the root
- * of the config tree where corosync expects to find them.
- */
-static int copy_tree_to_root(struct objdb_iface_ver0 *objdb, 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;
-
- objdb_get_string(objdb, cluster_parent_handle, "name", &cluster_name);
-
- /* 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 (!portnum)
- objdb_get_int(objdb, object_handle, "port", &portnum, DEFAULT_PORT);
-
- if (!key_filename)
- objdb_get_string(objdb, object_handle, "keyfile", &key_filename);
-
- if (!cluster_id)
- objdb_get_int(objdb, object_handle, "cluster_id", &cluster_id, 0);
-
- if (!cluster_id)
- cluster_id = generate_cluster_id(cluster_name);
- }
- objdb->object_find_destroy(find_handle);
- return 0;
-}
-
-static int cmanpre_reloadconfig(struct objdb_iface_ver0 *objdb, int flush, const char **error_string)
-{
- int ret = -1;
- hdb_handle_t object_handle;
- hdb_handle_t find_handle;
- hdb_handle_t cluster_parent_handle_new;
-
- /* don't reload if we've been told to run configless */
- if (getenv("CMAN_NOCONFIG")) {
- sprintf(error_reason, "Config not updated because we were run with cman_tool -X");
- ret = 0;
- goto err;
- }
-
- /* find both /cluster entries */
- objdb->object_find_create(OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"), &find_handle);
- objdb->object_find_next(find_handle, &cluster_parent_handle);
- if (!cluster_parent_handle) {
- sprintf (error_reason, "%s", "Cannot find old /cluster/ key in configuration\n");
- goto err;
- }
- objdb->object_find_next(find_handle, &cluster_parent_handle_new);
- if (!cluster_parent_handle_new) {
- sprintf (error_reason, "%s", "Cannot find new /cluster/ key in configuration\n");
- goto err;
- }
- objdb->object_find_destroy(find_handle);
-
- /* destroy the old one */
- objdb->object_destroy(cluster_parent_handle);
-
- /* update the reference to the new config */
- cluster_parent_handle = cluster_parent_handle_new;
-
- /* destroy top level /logging */
- objdb->object_find_create(OBJECT_PARENT_HANDLE, "logging", strlen("logging"), &find_handle);
- objdb->object_find_next(find_handle, &object_handle);
- objdb->object_find_destroy(find_handle);
- if (object_handle) {
- objdb->object_destroy(object_handle);
- }
-
- /* copy /cluster/logging to /logging */
- ret = copy_tree_to_root(objdb, "logging", 0);
-
- /* destroy top level /totem */
- objdb->object_find_create(OBJECT_PARENT_HANDLE, "totem", strlen("totem"), &find_handle);
- objdb->object_find_next(find_handle, &object_handle);
- objdb->object_find_destroy(find_handle);
- if (object_handle) {
- objdb->object_destroy(object_handle);
- }
-
- /* copy /cluster/totem to /totem */
- ret = copy_tree_to_root(objdb, "totem", 0);
-
- return 0;
-
-err:
- *error_string = error_reason;
- return ret;
-}
-
-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;
-
- if (getenv("CMAN_PIPE"))
- startup_pipe = atoi(getenv("CMAN_PIPE"));
-
- objdb->object_find_create(OBJECT_PARENT_HANDLE, "cluster", strlen("cluster"), &find_handle);
- objdb->object_find_next(find_handle, &cluster_parent_handle);
- objdb->object_find_destroy(find_handle);
- if (!cluster_parent_handle) {
- objdb->object_create(OBJECT_PARENT_HANDLE, &cluster_parent_handle,
- "cluster", strlen("cluster"));
- }
- else {
- /* Move these to a place where corosync expects to find them */
- ret = copy_tree_to_root(objdb, "totem", 0);
- ret = copy_tree_to_root(objdb, "logging", 0);
- ret = copy_tree_to_root(objdb, "event", 0);
- ret = copy_tree_to_root(objdb, "amf", 0);
- ret = copy_tree_to_root(objdb, "aisexec", 0);
- ret = copy_tree_to_root(objdb, "service", 1);
- }
-
- objdb->object_find_create(cluster_parent_handle, "cman", strlen("cman"), &find_handle);
- if (objdb->object_find_next(find_handle, &object_handle)) {
- objdb->object_create(cluster_parent_handle, &object_handle,
- "cman", strlen("cman"));
- }
- objdb->object_find_destroy(find_handle);
-
- /* This will create /libccs/@next_handle.
- * next_handle will be atomically incremented by corosync to return ccs_handle down the pipe.
- * We create it in cman-preconfig to avoid an "init" race in libccs.
- */
-
- objdb->object_find_create(OBJECT_PARENT_HANDLE, "libccs", strlen("libccs"), &find_handle);
- if (objdb->object_find_next(find_handle, &object_handle)) {
- int next_handle = 0;
-
- objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle,
- "libccs", strlen("libccs"));
-
- objdb->object_key_create(object_handle, "next_handle", strlen("next_handle"),
- &next_handle, sizeof(int));
- }
- objdb->object_find_destroy(find_handle);
-
- get_env_overrides();
- if (getenv("CMAN_NOCONFIG"))
- ret = set_noccs_defaults(objdb);
- else
- ret = get_cman_globals(objdb);
-
- if (!ret) {
- ret = get_nodename(objdb);
- add_cman_overrides(objdb);
- }
-
- if (!ret) {
- sprintf (error_reason, "%s", "Successfully parsed cman config\n");
- }
- else {
- if (error_reason[0] == '\0')
- sprintf (error_reason, "%s", "Error parsing cman config\n");
- }
- *error_string = error_reason;
-
- return ret;
-}
diff --git a/cman/config/cman.h b/cman/config/cman.h
deleted file mode 100644
index 8e04d21..0000000
--- a/cman/config/cman.h
+++ /dev/null
@@ -1,15 +0,0 @@
-
-/* How we announce ourself in syslog */
-#define CMAN_NAME "CMAN"
-
-#define MAX_CLUSTER_MEMBER_NAME_LEN 255
-
-/* Defaults for configuration variables */
-#define NOCCS_KEY_FILENAME DEFAULT_CONFIG_DIR "/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
diff --git a/cman/config/nodelist.h b/cman/config/nodelist.h
deleted file mode 100644
index f004145..0000000
--- a/cman/config/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/cman.in b/cman/init.d/cman.in
deleted file mode 100644
index ef89c85..0000000
--- a/cman/init.d/cman.in
+++ /dev/null
@@ -1,748 +0,0 @@
-#!/bin/bash
-#
-# cman - Cluster Manager init script
-#
-# chkconfig: - 21 79
-# description: Starts and stops cman
-#
-#
-### BEGIN INIT INFO
-# Provides: cman
-# Required-Start: $network $time
-# Required-Stop: $network $time
-# Default-Start:
-# Default-Stop:
-# Short-Description: Starts and stops cman
-# Description: Starts and stops the Cluster Manager set of daemons
-### END INIT INFO
-
-# set secure PATH
-PATH="/bin:/usr/bin:/sbin:/usr/sbin:@SBINDIR@"
-
-local_chkconfig()
-{
- ls /etc/rc${2}.d/S*${3} > /dev/null 2>/dev/null
- return $?
-}
-
-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/default ]; then
- [ -f /etc/default/cluster ] && . /etc/default/cluster
- [ -f /etc/default/cman ] && . /etc/default/cman
- [ -z "$LOCK_FILE" ] && LOCK_FILE="/var/lock/cman"
- [ -z "$(which chkconfig)" ] && 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=120
-
-# CMAN_QUORUM_TIMEOUT -- amount of time to wait for a quorate cluster on
-# startup quorum is needed by many other applications, so we may as
-# well wait here. If CMAN_QUORUM_TIMEOUT is less than 1, quorum will
-# be ignored.
-[ -z "$CMAN_QUORUM_TIMEOUT" ] && CMAN_QUORUM_TIMEOUT=0
-
-# CMAN_SHUTDOWN_TIMEOUT -- amount of time to wait for cman to become a
-# cluster member before calling cman_tool leave during shutdown.
-# The default is 60 seconds
-[ -z "$CMAN_SHUTDOWN_TIMEOUT" ] && CMAN_SHUTDOWN_TIMEOUT=60
-
-# 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
-
-# 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").
-[ -z "$FENCE_JOIN" ] && FENCE_JOIN="yes"
-
-# NETWORK_BRIDGE_SCRIPT -- script to use for xen network bridging.
-# This script must exist in the /etc/xen/scripts directory.
-# The default script is "network-bridge".
-[ -z "$NETWORK_BRIDGE_SCRIPT" ] && NETWORK_BRIDGE_SCRIPT="network-bridge"
-
-[ -n "$CLUSTERNAME" ] && cman_join_opts="-c $CLUSTERNAME"
-
-[ -n "$NODENAME" ] && cman_join_opts+=" -n $NODENAME"
-
-# CONFIG_LOADER -- select default config parser.
-# This can be:
-# xmlconfig - read directly from cluster.conf and use ricci as default config
-# propagation method. (default)
-# ldapconfig - read configuration from an ldap server.
-# Requires: LDAP_URL or/and LDAP_BASEDN envvar to be set.
-# LDAP_BINDDN and LDAP_BINDPWD have to be either both set or both unset.
-# corosync_parser - use internal corosync config file parser.
-# openaisparser - use internal openais config file parser.
-[ -n "$CONFIG_LOADER" ] && cman_join_opts+=" -C $CONFIG_LOADER"
-
-load_modules()
-{
- errmsg=$( /sbin/modprobe configfs 2>&1 ) || return 1
- errmsg=$( /sbin/modprobe dlm 2>&1 ) || return 1
- errmsg=$( /sbin/modprobe lock_dlm 2>&1 ) || true
- return 0
-}
-
-start_configfs()
-{
- # configfs
- awk '{ print $2 }' /etc/mtab | grep "/sys/kernel/config" > /dev/null 2>&1 \
- && awk '{ print $3 }' /etc/mtab | grep "configfs" > /dev/null 2>&1
- if [ $? -ne 0 ]
- then
- errmsg=$( /bin/mount -t configfs none /sys/kernel/config 2>&1 )
- return $?
- fi
- return 0
-}
-
-start_cman()
-{
- # cman
- @SBINDIR@/cman_tool status > /dev/null 2>&1
- if [ $? -ne 0 ]
- then
- case "$CONFIG_LOADER" in
- ldapconfig)
- if [ -n "$LDAP_URL" ] || [ -n "$LDAP_BASEDN" ]; then
- if [ -n "$LDAP_BINDDN" ]; then
- if [ -z "$LDAP_BINDPWD" ]; then
- errmsg="ldadconfig has been select but LDAP_BINDPWD is not set"
- return 1
- fi
- fi
- if [ -n "$LDAP_BINDPWD" ]; then
- if [ -z "$LDAP_BINDDN" ]; then
- errmsg="ldadconfig has been select but LDAP_BINDDN is not set"
- return 1
- fi
- fi
- else
- errmsg="ldadconfig has been select but neither LDAP_URL or LDAP_BASEDN have been set"
- return 1
- fi
- ;;
- *)
- # nothing to do for now
- ;;
- esac
- errmsg=$( @SBINDIR@/cman_tool -t $CMAN_CLUSTER_TIMEOUT -w join \
- $cman_join_opts 2>&1 ) || return 1
-
- if [ $CMAN_QUORUM_TIMEOUT -gt 0 ]
- then
- errmsg=$( @SBINDIR@/cman_tool -t $CMAN_QUORUM_TIMEOUT \
- -q wait 2>&1 ) || return 1
- fi
- fi
- return 0
-}
-
-unfence_self()
-{
- fence_node -U > /dev/null 2>&1
- error=$?
-
- if [ $error -eq 0 ]
- then
- echo " Unfencing self... done"
- return 0
- else
- if [ $error -eq 1 ]
- then
- echo " Unfencing self... failed"
- return 1
- else
- return 0
- fi
- fi
-}
-
-start_qdiskd()
-{
- status qdiskd > /dev/null 2>&1
- if [ $? -ne 0 ] && \
- ccs_tool query /cluster/quorumd >/dev/null 2>&1; then
- errmsg=$( @SBINDIR@/qdiskd -Q 2>&1 ) || return 1
- fi
- return 0
-}
-
-
-start_daemons()
-{
- status fenced > /dev/null 2>&1
- if [ $? -ne 0 ]; then
- errmsg=$( @SBINDIR@/fenced 2>&1 ) || return 1
- fi
- status dlm_controld > /dev/null 2>&1
- if [ $? -ne 0 ]; then
- errmsg=$( @SBINDIR@/dlm_controld 2>&1 ) || return 1
- fi
- status gfs_controld > /dev/null 2>&1
- if [ $? -ne 0 ]; then
- errmsg=$( @SBINDIR@/gfs_controld 2>&1 ) || return 1
- fi
- status cmannotifyd > /dev/null 2>&1
- if [ $? -ne 0 ]; then
- case "$CMAN_NOTIFYD_START" in
- yes)
- errmsg=$(@SBINDIR@/cmannotifyd 2>&1 ) || return 1
- ;;
- no)
- # nothing to do
- ;;
- conditional)
- if [ -n "$(ls -1 @NOTIFYDDIR@ 2>/dev/null)" ]; then
- errmsg=$(@SBINDIR@/cmannotifyd 2>&1 ) || return 1
- fi
- ;;
- *)
- errmsg="unknown CMAN_NOTIFYD_START option"
- return 1
- ;;
- esac
- fi
- return 0
-}
-
-start_fence()
-{
- @SBINDIR@/cman_tool status | grep Flags | grep 2node > /dev/null 2>&1
- if [ $? -ne 0 ]
- then
- errmsg=$( @SBINDIR@/fence_tool join -w $FENCE_JOIN_TIMEOUT \
- > /dev/null 2>&1 ) || return 1
- else
- errmsg=$( @SBINDIR@/fence_tool join -w $FENCE_JOIN_TIMEOUT \
- -m $FENCED_MEMBER_DELAY join \
- > /dev/null 2>&1 ) || return 1
- fi
- return 0
-}
-
-start_fence_xvmd()
-{
- status fence_xvmd > /dev/null 2>&1
- if [ $? -ne 0 ]; then
- errmsg=$( @SBINDIR@/fence_xvmd $FENCE_XVMD_OPTS 2>&1 ) || return 1
- fi
- return 0
-}
-
-xend_bridged_net_enabled() {
- # Not a xen kernel
- test -d /proc/xen || return 1
-
- current_runlevel=$(/sbin/runlevel 2>/dev/null | awk '{ print $2 }' 2>/dev/null)
- if [ -z "$current_runlevel" ]; then
- errmsg='Unable to determine the current runlevel'
- return 1
- fi
-
- chkconfig --levels "$current_runlevel" xend 2>/dev/null
- if [ $? -ne 0 ]; then
- # xend doesn't start at this runlevel.
- return 1
- fi
-
- if [ ! -f /etc/xen/xend-config.sxp ]; then
- # xend isn't configured to use bridged networking.
- return 1
- fi
-
- egrep "^[[:blank:]]*\([[:blank:]]*network-script[[:blank:]]+(')?[[:blank:]]*${NETWORK_BRIDGE_SCRIPT}([[:blank:]]*\)|[[:blank:]]+)" /etc/xen/xend-config.sxp >&/dev/null
- if [ $? -ne 0 ]; then
- # xend isn't configured to use bridged networking.
- return 1
- fi
- return 0
-}
-
-xend_bridged_net_start() {
- if [ ! -x /etc/xen/scripts/${NETWORK_BRIDGE_SCRIPT} ]; then
- if [ -f /etc/xen/scripts/${NETWORK_BRIDGE_SCRIPT} ]; then
- errmsg='The xend bridged network script cannot be run'
- else
- errmsg='The xend bridged network script is missing'
- fi
- return 1
- fi
-
- /sbin/modprobe netbk >& /dev/null
- /sbin/modprobe netloop >& /dev/null
- bridge_parms=`egrep -m 1 "^[[:blank:]]*\([[:blank:]]*network-script[[:blank:]]+(')?[[:blank:]]*${NETWORK_BRIDGE_SCRIPT}([[:blank:]]*\)|[[:blank:]]+)" /etc/xen/xend-config.sxp| sed -r "s/^[[:blank:]]*\([[:blank:]]*network-script[[:blank:]]+'?[[:blank:]]*${NETWORK_BRIDGE_SCRIPT}[[:blank:]]*//; s/'?[[:blank:]]*\).*//"`
- errmsg=$(/etc/xen/scripts/${NETWORK_BRIDGE_SCRIPT} start $bridge_parms 2>&1) || return 1
- return 0
-}
-
-fence_xvmd_enabled()
-{
- #
- # Check the value of FENCE_JOIN.
- # If FENCE_JOIN is set to "no", then we should disable fence_xvm.
- #
- if [ "$FENCE_JOIN" = "no" ]; then
- return 1
- fi
-
- #
- # Check for the 'xm' binary. If it's not here, we are not
- # running on a machine capable of running xvmd.
- #
- which xm > /dev/null 2>&1 || return 1
-
- #
- # Check for presence of /cluster/fence_xvmd in cluster.conf
- # (If -X is specified, it doesn't matter if it's in cluster.conf;
- # we'll start it anyway since ccsd is not required)
- #
- @SBINDIR@/cman_tool status > /dev/null 2>&1
- if [ $? -eq 0 ]
- then
- if [ "$FENCE_XVMD_OPTS" = "${FENCE_XVMD_OPTS/-X/}" ]; then
- @SBINDIR@/ccs_tool query /cluster/fence_xvmd || return 1
- fi
- fi
-
- return 0
-}
-
-fence_join_enabled()
-{
- #
- # Check the value of FENCE_JOIN.
- # If FENCE_JOIN is set to "no", we will not attempt to join
- # the fence domain. If FENCE_JOIN is set to any other value,
- # we will attempt to join the fence domain (default).
- #
- if [ "$FENCE_JOIN" = "no" ]; then
- return 1
- else
- return 0
- fi
-}
-
-start()
-{
- echo "Starting cluster: "
-
- # required for distributions that use tmpfs for /var/run
- mkdir -p /var/run/cluster
-
- xend_bridged_net_enabled
- if [ $? -eq 0 ]
- then
- echo -n " Enabling workaround for Xend bridged networking... "
- xend_bridged_net_start
- if [ $? -eq 0 ]
- then
- echo "done"
- else
- echo "failed: $errmsg"
- return 1
- fi
- fi
-
- echo -n " Loading modules... "
- ulimit -c unlimited
- load_modules
- if [ $? -eq 0 ]
- then
- echo "done"
- else
- echo "failed"
- return 1
- fi
-
- echo -n " Mounting configfs... "
- start_configfs
- if [ $? -eq 0 ]
- then
- echo "done"
- else
- echo "failed"
- return 1
- fi
-
- echo -n " Starting cman... "
- start_cman
- if [ $? -eq 0 ]
- then
- echo "done"
- else
- echo "failed"
- return 1
- fi
-
- unfence_self
- if [ $? -eq 1 ]
- then
- return 1
- fi
-
- echo -n " Starting qdiskd... "
- start_qdiskd
- if [ $? -eq 0 ]
- then
- echo "done"
- else
- echo "failed"
- return 1
- fi
-
- echo -n " Starting daemons... "
- start_daemons
- if [ $? -eq 0 ]
- then
- echo "done"
- else
- echo "failed"
- return 1
- fi
-
- if fence_join_enabled; then
- echo -n " Starting fencing... "
- start_fence
- if [ $? -eq 0 ]
- then
- echo "done"
- else
- echo "failed"
- return 1
- fi
- fi
-
- if fence_xvmd_enabled; then
- echo -n " Starting virtual machine fencing host... "
- start_fence_xvmd
- if [ $? -eq 0 ]
- then
- echo "done"
- else
- echo "failed"
- return 1
- fi
- fi
-
- return 0
-}
-
-stop_configfs()
-{
- awk '{ print $2 }' /etc/mtab | grep "/sys/kernel/config" > /dev/null 2>&1 \
- && awk '{ print $3 }' /etc/mtab | grep "configfs" > /dev/null 2>&1
- if [ $? -eq 0 ] && [ -z "$(ls -1 /sys/kernel/config)" ]
- then
- errmsg=$( /bin/umount /sys/kernel/config 2>&1 )
- if [ $? -ne 0 ]
- then
- echo -n $errmsg " "
- fi
- fi
- return 0
-}
-
-stop_cman()
-{
- @SBINDIR@/cman_tool status > /dev/null 2>&1
- if [ $? -eq 0 ]
- then
- errmsg=$( @SBINDIR@/cman_tool -t $CMAN_SHUTDOWN_TIMEOUT \
- -w leave $1 2>&1 ) || return 1
- fi
- return 0 # all ok
-}
-
-stop_daemons()
-{
- if pid=$(pidof gfs_controld 2>&1); then
- errmsg=$(kill $pid 2>&1) || return 1
- fi
- if pid=$(pidof dlm_controld 2>&1); then
- errmsg=$(kill $pid 2>&1) || return 1
- fi
- if pid=$(pidof fenced 2>&1); then
- errmsg=$(kill $pid 2>&1) || return 1
- fi
- return 0 # all ok
-}
-
-stop_cmannotifyd()
-{
- if pid=$(pidof cmannotifyd 2>&1); then
- errmsg=$(kill $pid 2>&1) || return 1
- fi
- return 0
-}
-
-stop_qdiskd()
-{
- retries=0
-
- pid="$(pidof qdiskd)"
- while [ -n "$pid" ] && [ $retries -lt 5 ]; do
- kill $pid 2>&1
- sleep 1
- ((retries++))
- pid="$(pidof qdiskd)"
- done
- if [ -z "$(pidof qdiskd)" ]; then
- return 0
- else
- return 1
- fi
-}
-
-stop_fence()
-{
- if pidof fenced > /dev/null 2>&1
- then
- @SBINDIR@/fence_tool leave -w 10 > /dev/null 2>&1
- rtrn=$?
- return $rtrn
- fi
- return 0 # all ok
-}
-
-stop_fence_xvmd()
-{
- if pidof fence_xvmd > /dev/null 2>&1
- then
- pkill -TERM fence_xvmd
- sleep 1 # A bit of time for fenced to exit
- fi
-
- [ -z "$(pidof fence_xvmd)" ]
- return $?
-}
-
-stop()
-{
- echo "Stopping cluster: "
-
- if fence_xvmd_enabled; then
- echo -n " Stopping virtual machine fencing host... "
- stop_fence_xvmd
- if [ $? -eq 0 ]
- then
- echo "done"
- else
- echo "failed"
- return 1
- fi
- fi
-
- if fence_join_enabled; then
- echo -n " Stopping fencing... "
- stop_fence
- if [ $? -eq 0 ]
- then
- echo "done"
- else
- echo "failed"
- return 1
- fi
- fi
-
- echo -n " Stopping daemons... "
- stop_daemons
- if [ $? -eq 0 ]
- then
- echo "done"
- else
- echo "failed"
- return 1
- fi
-
- echo -n " Stopping the Quorum Disk Daemon: "
- stop_qdiskd
- if [ $? -eq 0 ]
- then
- echo "done"
- else
- echo "failed"
- return 1
- fi
-
- echo -n " Stopping cman... "
- if [ $1 ]; then
- stop_cman $1
- else
- stop_cman
- fi
- if [ $? -eq 0 ]
- then
- echo "done"
- else
- echo "failed"
- return 1
- fi
-
- echo -n " Stopping cmannotifyd... "
- stop_cmannotifyd
- if [ $? -eq 0 ]
- then
- echo "done"
- else
- echo "failed"
- return 1
- fi
-
- echo -n " Unmounting configfs... "
- stop_configfs
- if [ $? -eq 0 ]
- then
- echo "done"
- else
- echo "failed"
- return 1
- fi
-
- return 0
-}
-
-cmanstatus()
-{
- errmsg=$( status fenced 2>&1) || return 1
- errmsg=$( status dlm_controld 2>&1) || return 1
- errmsg=$( status gfs_controld 2>&1) || return 1
-
- case "$CMAN_NOTIFYD_START" in
- yes)
- errmsg=$( status cmannotifyd 2>&1) || return 1
- ;;
- no)
- # nothing to do
- ;;
- conditional)
- if [ -n "$(ls -1 @NOTIFYDDIR@ 2>/dev/null)" ]; then
- errmsg=$( status cmannotifyd 2>&1) || return 1
- fi
- ;;
- esac
-
- if ccs_tool query /cluster/quorumd >/dev/null 2>&1; then
- errmsg=$( status qdiskd 2>&1) || return 1
- fi
-
- errmsg=$( status corosync 2>&1) || return 1
-
- fence_xvmd_enabled || return 0
- errmsg=$( status fence_xvmd 2>&1) || return 1
-
- return 0
-}
-
-rtrn=1
-
-# See how we were called.
-case "$1" in
- start)
- start
- rtrn=$?
- [ $rtrn = 0 ] && touch $LOCK_FILE
- if [ $rtrn -ne 0 ]
- then
- echo $errmsg
- failure "failed to start cman"
- echo
- else
- success "start"
- echo
- fi
- ;;
- stop)
- if [ $2 ]; then
- stop
- else
- stop remove
- fi
- rtrn=$?
- [ $rtrn = 0 ] && rm -f $LOCK_FILE
- if [ $rtrn -ne 0 ]
- then
- echo $errmsg
- failure "failed to stop cman"
- echo
- else
- success "shutdown"
- echo
- fi
- ;;
-
- restart|reload)
- $0 stop restart
- $0 start
- rtrn=$?
- ;;
-
- status)
- cmanstatus
- rtrn=$?
- if [ $rtrn -ne 0 ] ; then
- echo $errmsg
- else
- echo "cman is running."
- fi
- ;;
-
- *)
- echo $"Usage: $0 {start|stop|reload|restart|status}"
- ;;
-esac
-
-exit $rtrn
diff --git a/cman/man/Makefile.am b/cman/man/Makefile.am
deleted file mode 100644
index a9e03ca..0000000
--- a/cman/man/Makefile.am
+++ /dev/null
@@ -1,8 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-dist_man_MANS = cman.5 \
- qdisk.5 \
- cman_tool.8 \
- qdiskd.8 \
- mkqdisk.8 \
- cmannotifyd.8
diff --git a/cman/man/cman.5 b/cman/man/cman.5
deleted file mode 100644
index 8e52226..0000000
--- a/cman/man/cman.5
+++ /dev/null
@@ -1,222 +0,0 @@
-.\" groff -t -e -mandoc -Tlatin1 cman.5 | less
-
-.TH "cman" "5" "" "" "cluster.conf cman configuration section"
-
-.SH "NAME"
-cman \- cluster.conf cman configuration section
-
-.SH "DESCRIPTION"
-
-.in +7
-Cman configuration values are placed in the <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 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="229.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="229.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 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/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 />
- <logging />
- <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 >
- />
- <logging syslog_facility="local4" />
- <aisexec user="root" group="root" />
-
-Here's how to set the token timeout to five seconds:
-
- <totem token="5000"/>
-
-And this is how to add extra corosync logging options to CMAN and CPG:
-
- <logging to_stderr="yes">
- <logger_subsys subsys="CPG" debug="on" to_stderr="yes">
- </logger_subsys>
- <logger_subsys subsys="CMAN" debug="on" to_stderr="yes">
- </logger_subsys>
- </logging>
-
-.in -7
-
-
-.sp
-
-.SH "SEE ALSO"
-
-cluster.conf(5), corosync.conf(5), ccs(7), cman_tool(8)
-
diff --git a/cman/man/cman_tool.8 b/cman/man/cman_tool.8
deleted file mode 100644
index d9bc224..0000000
--- a/cman/man/cman_tool.8
+++ /dev/null
@@ -1,345 +0,0 @@
-.TH CMAN_TOOL 8 "Nov 8 2007" "Cluster utilities"
-
-.SH NAME
-cman_tool \- Cluster Management Tool
-.SH SYNOPSIS
-.B cman_tool join | leave | kill | expected | votes | version | wait | status | nodes | services | debug [options]
-.br
-.SH DESCRIPTION
-.PP
-.B cman_tool
-is a program that manages the cluster management subsystem CMAN. cman_tool
-can be used to join the node to a cluster, leave the cluster, kill another
-cluster node or change the value of expected votes of a cluster.
-.br
-Be careful that you understand the consequences of the commands issued via cman_tool
-as they can affect all nodes in your cluster. Most of the time the cman_tool
-will only be invoked from your startup and shutdown scripts.
-.br
-.SH SUBCOMMANDS
-.TP
-.I join
-This is the main use of cman_tool. It instructs the cluster manager to attempt
-to join an existing cluster or (if no existing cluster exists) then to form
-a new one on its own.
-.br
-If no options are given to this command then it will take the cluster
-configuration information from cluster.conf. However, it is possible to provide
-all the information on the command-line or to override cluster.conf values by using
-the command line.
-
-.TP
-.I leave
-Tells CMAN to leave the cluster. You cannot do this if there are subsystems
-(eg DLM, GFS) active. You should dismount all GFS filesystems,
-shutdown CLVM, fenced and anything else using the cluster manager before
-using
-.B cman_tool leave.
-Look at 'cman_tool status' and group_tool to see how many (and which)
-subsystems are active.
-.br
-When a node leaves the cluster, the remaining nodes recalculate quorum and this
-may block cluster activity if the required number of votes is not present.
-If this node is to be down for an extended period of time and you need to
-keep the cluster running, add the
-.B remove
-option, and the remaining nodes will recalculate quorum such that activity
-can continue.
-
-.TP
-.I kill
-Tells CMAN to kill another node in the cluster. This will cause the local
-node to send a "KILL" message to that node and it will shut down. Recovery
-will occur for the killed node as if it had failed. This is a sort of remote
-version of "leave force" so only use if if you really know what you are doing.
-
-.TP
-.I expected
-Tells CMAN a new value of expected votes and instructs it to recalculate
-quorum based on this value.
-.br
-Use this option if your cluster has lost quorum due to nodes failing and
-you need to get it running again in a hurry.
-
-.TP
-.I version
-Used alone this will report the major, minor, patch and config versions
-used by CMAN (also displayed in 'cman_tool status'). It can also be used
-with -r to tell cluster members to update.
-
-.TP
-.I wait
-Waits until the node is a member of the cluster and then returns.
-
-.TP
-.I status
-Displays the local view of the cluster status.
-
-.TP
-.I nodes
-Displays the local view of the cluster nodes.
-
-.TP
-.I services
-Displays the local view of subsystems using cman (deprecated, group_tool
-should be used instead).
-
-.TP
-.I debug
-Sets the debug level of the running cman daemon. Debug output will be
-sent to syslog level LOG_DEBUG. the
-.B -d
-switch specifies the new logging level. This is the same bitmask used
-for cman_tool join -d
-.br
-.SH "LEAVE" OPTIONS
-.TP
-.I -w
-Normally, "cman_tool leave" will fail if the cluster is in transition (ie
-another node is joining or leaving the cluster). By adding the -w flag,
-cman_tool will wait and retry the leave operation repeatedly until it succeeds
-or a more serious error occurs.
-.TP
-.I -t <seconds>
-If -w is also specified then -t dictates the maximum amount of time cman_tool
-is prepared to wait. If the operation times out then a status of 2 is returned.
-.TP
-.I force
-Shuts down the cluster manager without first telling any of the subsystems
-to close down. Use this option with extreme care as it could easily cause data
-loss.
-.TP
-.I remove
-Tells the rest of the cluster to recalculate quorum such that activity can
-continue without this node.
-
-.SH "EXPECTED" OPTIONS
-.TP
-.I -e <expected-votes>
-The new value of expected votes to use. This will usually be enough
-to bring the cluster back to life. Values that would cause incorrect
-quorum will be rejected.
-
-.SH "KILL" OPTIONS
-.TP
-.I -n <nodename>
-The node name of the node to be killed. This should be the unqualified node
-name as it appears in 'cman_tool nodes'.
-
-.SH "VERSION" OPTIONS
-.TP
-.I -r <config_version>
-Update config version. You don't need to use this when adding a new node,
-the new cman node will tell the rest of the cluster to read the latest
-version of the config file automatically.
-.br
-In fact the argument to -r might look as though it is ignored.
-Its presence simply tells cman to re-read the configuration file and look
-for that version in the file. cman will keep re-reading the file
-until a version number >= the passed version is found.
-.br
-cman_tool version on its own will always show the current version
-and not the one being looked for. So be aware that the display
-will possible not update immediately after you have run
-cman_tool version -r.
-.SH "WAIT" OPTIONS
-.TP
-.I -q
-Waits until the cluster is quorate before returning.
-.I -t <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 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 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.
-.SH "NODES" OPTIONS
-.TP
-.I -f
-Shows the date/time the node was last fenced (if it has bee fenced), and also
-the fence system that was used.
-.br
-.TP
-.I -a
-Shows the IP address(es) the nodes are communicating on.
-.br
-.TP
-.I -n <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>
-Currently only a value of 1 is supported.
-.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 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.
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 7a00a25..0000000
--- a/cman/man/qdisk.5
+++ /dev/null
@@ -1,478 +0,0 @@
-.TH "QDisk" "5" "20 Feb 2007" "" "Cluster Quorum Disk"
-.SH "NAME"
-qdisk \- a disk-based quorum daemon for CMAN / Linux-Cluster
-.SH "1. Overview"
-.SH "1.1 Problem"
-In some situations, it may be necessary or desirable to sustain
-a majority node failure of a cluster without introducing the need for
-asymmetric cluster configurations (e.g. client-server, or heavily-weighted
-voting nodes).
-
-.SH "1.2. Design Requirements"
-* Ability to sustain 1..(n-1)/n simultaneous node failures, without the
-danger of a simple network partition causing a split brain. That is, we
-need to be able to ensure that the majority failure case is not merely
-the result of a network partition.
-
-* Ability to use external reasons for deciding which partition is the
-the quorate partition in a partitioned cluster. For example, a user may
-have a service running on one node, and that node must always be the master
-in the event of a network partition. Or, a node might lose all network
-connectivity except the cluster communication path - in which case, a
-user may wish that node to be evicted from the cluster.
-
-* Integration with CMAN. We must not require CMAN to run with us (or
-without us). Linux-Cluster does not require a quorum disk normally -
-introducing new requirements on the base of how Linux-Cluster operates
-is not allowed.
-
-* Data integrity. In order to recover from a majority failure, fencing
-is required. The fencing subsystem is already provided by Linux-Cluster.
-
-* Non-reliance on hardware or protocol specific methods (i.e. SCSI
-reservations). This ensures the quorum disk algorithm can be used on the
-widest range of hardware configurations possible.
-
-* Little or no memory allocation after initialization. In critical paths
-during failover, we do not want to have to worry about being killed during
-a memory pressure situation because we request a page fault, and the Linux
-OOM killer responds...
-
-.SH "1.3. Hardware Considerations and Requirements"
-.SH "1.3.1. Concurrent, Synchronous, Read/Write Access"
-This quorum daemon requires a shared block device with concurrent read/write
-access from all nodes in the cluster. The shared block device can be
-a multi-port SCSI RAID array, a Fiber-Channel RAID SAN, a RAIDed iSCSI
-target, or even GNBD. The quorum daemon uses O_DIRECT to write to the
-device.
-
-.SH "1.3.2. Bargain-basement JBODs need not apply"
-There is a minimum performance requirement inherent when using disk-based
-cluster quorum algorithms, so design your cluster accordingly. Using a
-cheap JBOD with old SCSI2 disks on a multi-initiator bus will cause
-problems at the first load spike. Plan your loads accordingly; a node's
-inability to write to the quorum disk in a timely manner will cause the
-cluster to evict the node. Using host-RAID or multi-initiator parallel
-SCSI configurations with the qdisk daemon is unlikely to work, and will
-probably cause administrators a lot of frustration. That having been
-said, because the timeouts are configurable, most hardware should work
-if the timeouts are set high enough.
-
-.SH "1.3.3. Fencing is Required"
-In order to maintain data integrity under all failure scenarios, use of
-this quorum daemon requires adequate fencing, preferably power-based
-fencing. Watchdog timers and software-based solutions to reboot the node
-internally, while possibly sufficient, are not considered 'fencing' for
-the purposes of using the quorum disk.
-
-.SH "1.4. Limitations"
-* At this time, this daemon supports a maximum of 16 nodes. This is
-primarily a scalability issue: As we increase the node count, we increase
-the amount of synchronous I/O contention on the shared quorum disk.
-
-* Cluster node IDs must be statically configured in cluster.conf and
-must be numbered from 1..16 (there can be gaps, of course).
-
-* Cluster node votes should be more or less equal.
-
-* CMAN must be running before the qdisk program can operate in full
-capacity. If CMAN is not running, qdisk will wait for it.
-
-* CMAN's eviction timeout should be at least 2x the quorum daemon's
-to give the quorum daemon adequate time to converge on a master during a
-failure + load spike situation.
-
-* For 'all-but-one' failure operation, the total number of votes assigned
-to the quorum device should be equal to or greater than the total number
-of node-votes in the cluster. While it is possible to assign only one
-(or a few) votes to the quorum device, the effects of doing so have not
-been explored.
-
-* For 'tiebreaker' operation in a two-node cluster, unset CMAN's two_node
-flag (or set it to 0), set CMAN's expected votes to '3', set each node's
-vote to '1', and set qdisk's vote count to '1' as well. This will allow
-the cluster to operate if either both nodes are online, or a single node &
-the heuristics.
-
-* Currently, the quorum disk daemon is difficult to use with CLVM if
-the quorum disk resides on a CLVM logical volume. CLVM requires a
-quorate cluster to correctly operate, which introduces a chicken-and-egg
-problem for starting the cluster: CLVM needs quorum, but the quorum daemon
-needs CLVM (if and only if the quorum device lies on CLVM-managed storage).
-One way to work around this is to *not* set the cluster's expected votes
-to include the quorum daemon's votes. Bring all nodes online, and start
-the quorum daemon *after* the whole cluster is running. This will allow
-the expected votes to increase naturally.
-
-.SH "2. Algorithms"
-.SH "2.1. Heartbeating & Liveliness Determination"
-Nodes update individual status blocks on the quorum disk at a user-
-defined rate. Each write of a status block alters the timestamp, which
-is what other nodes use to decide whether a node has hung or not. If,
-after a user-defined number of 'misses' (that is, failure to update a
-timestamp), a node is declared offline. After a certain number of 'hits'
-(changed timestamp + "i am alive" state), the node is declared online.
-
-The status block contains additional information, such as a bitmask of
-the nodes that node believes are online. Some of this information is
-used by the master - while some is just for performance recording, and
-may be used at a later time. The most important pieces of information
-a node writes to its status block are:
-
-.in 12
-- Timestamp
-.br
-- Internal state (available / not available)
-.br
-- Score
-.br
-- Known max score (may be used in the future to detect invalid configurations)
-.br
-- Vote/bid messages
-.br
-- Other nodes it thinks are online
-.in 0
-
-.SH "2.2. Scoring & Heuristics"
-The administrator can configure up to 10 purely arbitrary heuristics, and
-must exercise caution in doing so. At least one administrator-
-defined heuristic is required for operation, but it is generally a good
-idea to have more than one heuristic. By default, only nodes scoring over
-1/2 of the total maximum score will claim they are available via the
-quorum disk, and a node (master or otherwise) whose score drops too low
-will remove itself (usually, by rebooting).
-
-The heuristics themselves can be any command executable by 'sh -c'. For
-example, in early testing the following was used:
-
-.ti 12
-<\fBheuristic \fP\fIprogram\fP\fB="\fP[ -f /quorum ]\fB" \fP\fIscore\fP\fB="\fP10\fB" \fP\fIinterval\fP\fB="\fP2\fB"/>\fP
-
-This is a literal sh-ism which tests for the existence of a file called
-"/quorum". Without that file, the node would claim it was unavailable.
-This is an awful example, and should never, ever be used in production,
-but is provided as an example as to what one could do...
-
-Typically, the heuristics should be snippets of shell code or commands which
-help determine a node's usefulness to the cluster or clients. Ideally, you
-want to add traces for all of your network paths (e.g. check links, or
-ping routers), and methods to detect availability of shared storage.
-
-.SH "2.3. Master Election"
-Only one master is present at any one time in the cluster, regardless of
-how many partitions exist within the cluster itself. The master is
-elected by a simple voting scheme in which the lowest node which believes
-it is capable of running (i.e. scores high enough) bids for master status.
-If the other nodes agree, it becomes the master. This algorithm is
-run whenever no master is present.
-
-If another node comes online with a lower node ID while a node is still
-bidding for master status, it will rescind its bid and vote for the lower
-node ID. If a master dies or a bidding node dies, the voting algorithm
-is started over. The voting algorithm typically takes two passes to
-complete.
-
-Master deaths take marginally longer to recover from than non-master
-deaths, because a new master must be elected before the old master can
-be evicted & fenced.
-
-.SH "2.4. Master Duties"
-The master node decides who is or is not in the master partition, as
-well as handles eviction of dead nodes (both via the quorum disk and via
-the linux-cluster fencing system by using the cman_kill_node() API).
-
-.SH "2.5. How it All Ties Together"
-When a master is present, and if the master believes a node to be online,
-that node will advertise to CMAN that the quorum disk is available. The
-master will only grant a node membership if:
-
-.in 12
-(a) CMAN believes the node to be online, and
-.br
-(b) that node has made enough consecutive, timely writes
-.in 16
-to the quorum disk, and
-.in 12
-(c) the node has a high enough score to consider itself online.
-.in 0
-
-.SH "3. Configuration"
-.SH "3.1. The <quorumd> tag"
-This tag is a child of the top-level <cluster> tag.
-
-.in 8
-\fB<quorumd\fP
-.in 9
-\fIinterval\fP\fB="\fP1\fB"\fP
-.in 12
-This is the frequency of read/write cycles, in seconds.
-
-.in 9
-\fItko\fP\fB="\fP10\fB"\fP
-.in 12
-This is the number of cycles a node must miss in order to be declared dead.
-
-.in 9
-\fItko_up\fP\fB="\fPX\fB"\fP
-.in 12
-This is the number of cycles a node must be seen in order to be declared
-online. Default is \fBfloor(tko/3)\fP.
-
-.in 9
-\fIupgrade_wait\fP\fB="\fP2\fB"\fP
-.in 12
-This is the number of cycles a node must wait before initiating a bid
-for master status after heuristic scoring becomes sufficient. The
-default is 2. This can not be set to 0, and should not exceed \fBtko\fP.
-
-.in 9
-\fImaster_wait\fP\fB="\fPX\fB"\fP
-.in 12
-This is the number of cycles a node must wait for votes before declaring
-itself master after making a bid. Default is \fBfloor(tko/2)\fP.
-This can not be less than 2, must be greater than tko_up, and should not
-exceed \fBtko\fP.
-
-.in 9
-\fIvotes\fP\fB="\fP3\fB"\fP
-.in 12
-This is the number of votes the quorum daemon advertises to CMAN when it
-has a high enough score.
-
-.in 9
-\fIlog_level\fP\fB="\fP4\fB"\fP
-.in 12
-This controls the verbosity of the quorum daemon in the system logs.
-0 = emergencies; 7 = debug. 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
-\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.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 for every heuristic is 2 seconds.
-.in 0
-
-.in 9
-\fItko\fP\fB="\fP1\fB"\fP
-.in 12
-After this many failed attempts to run the heuristic, it is considered DOWN,
-and its score is removed. The default tko for each heuristic is 1, which
-may be inadequate for things such as 'ping'.
-.in 8
-\fB/>\fP
-.in 0
-
-
-.SH "3.3. Examples"
-.SH "3.3.1. 3 cluster nodes & 3 routers"
-.in 8
-<cman expected_votes="6" .../>
-.br
-<clusternodes>
-.in 12
-<clusternode name="node1" votes="1" ... />
-.br
-<clusternode name="node2" votes="1" ... />
-.br
-<clusternode name="node3" votes="1" ... />
-.in 8
-</clusternodes>
-.br
-<quorumd interval="1" tko="10" votes="3" label="testing">
-.in 12
-<heuristic program="ping A -c1 -t1" score="1" interval="2" tko="3"/>
-.br
-<heuristic program="ping B -c1 -t1" score="1" interval="2" tko="3"/>
-.br
-<heuristic program="ping C -c1 -t1" score="1" interval="2" tko="3"/>
-.br
-.in 8
-</quorumd>
-
-.SH "3.3.2. 2 cluster nodes & 1 IP tiebreaker"
-.in 8
-<cman two_node="0" expected_votes="3" .../>
-.br
-<clusternodes>
-.in 12
-<clusternode name="node1" votes="1" ... />
-.br
-<clusternode name="node2" votes="1" ... />
-.in 8
-</clusternodes>
-.br
-<quorumd interval="1" tko="10" votes="1" label="testing">
-.in 12
-<heuristic program="ping A -c1 -t1" score="1" interval="2" tko="3"/>
-.br
-.in 8
-</quorumd>
-.in 0
-
-
-.SH "3.4. Heuristic score considerations"
-* Heuristic timeouts should be set high enough to allow the previous run
-of a given heuristic to complete.
-
-* Heuristic scripts returning anything except 0 as their return code
-are considered failed.
-
-* The worst-case for improperly configured quorum heuristics is a race
-to fence where two partitions simultaneously try to kill each other.
-
-.SH "3.5. Creating a quorum disk partition"
-The mkqdisk utility can create and list currently configured quorum disks
-visible to the local node; see
-.B mkqdisk(8)
-for more details.
-
-.SH "SEE ALSO"
-mkqdisk(8), qdiskd(8), cman(5), syslog.conf(5), gettimeofday(2)
diff --git a/cman/man/qdiskd.8 b/cman/man/qdiskd.8
deleted file mode 100644
index 21bccbf..0000000
--- a/cman/man/qdiskd.8
+++ /dev/null
@@ -1,25 +0,0 @@
-.TH "qdiskd" "8" "July 2006" "" "Quorum Disk Management"
-.SH "NAME"
-qdiskd \- Cluster Quorum Disk Daemon
-.SH "SYNOPSIS"
-\fBqdiskd [\-f] [\-d]
-.SH "DESCRIPTION"
-.PP
-The \fBqdiskd\fP daemon talks to CMAN and provides a mechanism for determining
-node-fitness in a cluster environment. See
-.B
-qdisk(5)
-for configuration information.
-.SH "OPTIONS"
-.IP "\-f"
-Run in the foreground (do not fork / daemonize).
-.IP "\-d"
-Enable debug output.
-.IP "\-Q"
-Close stdin/out/err immediately before doing validations. This
-is primarily for use when being called from an init script. Using
-this option will stop all output, and can not be used with the -d
-option.
-
-.SH "SEE ALSO"
-mkqdisk(8), qdisk(5), cman(5)
diff --git a/cman/notifyd/Makefile.am b/cman/notifyd/Makefile.am
deleted file mode 100644
index 5c80177..0000000
--- a/cman/notifyd/Makefile.am
+++ /dev/null
@@ -1,41 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-sbin_PROGRAMS = cmannotifyd
-
-notifyscript = cman_notify
-
-sbin_SCRIPTS = $(notifyscript)
-
-EXTRA_DIST = $(notifyscript).in
-
-cmannotifyd_SOURCES = main.c
-
-cmannotifyd_CPPFLAGS = -D_GNU_SOURCE \
- -I$(top_srcdir)/common/liblogthread/ \
- -I$(top_srcdir)/config/libs/libccsconfdb/ \
- $(cfg_CFLAGS) \
- $(quorum_CFLAGS) \
- $(confdb_CFLAGS)
-
-
-cmannotifyd_LDADD = $(top_builddir)/common/liblogthread/liblogthread.la \
- $(top_builddir)/config/libs/libccsconfdb/libccs.la \
- $(cfg_LIBS) \
- $(quorum_LIBS) \
- $(confdb_LIBS)
-
-$(notifyscript): $(notifyscript).in
- cat $^ | sed \
- -e 's#_NOTIFYDDIR_#${NOTIFYDDIR}#g' \
- -e 's#_LOGDIR_#${LOGDIR}#g' \
- > $@
- chmod a+x $@
-
-install-exec-local:
- $(INSTALL) -d $(DESTDIR)/$(NOTIFYDDIR)
-
-uninstall-local:
- rmdir $(DESTDIR)/$(NOTIFYDDIR) || :;
-
-clean-generic:
- rm -f $(notifyscript)
diff --git a/cman/notifyd/cman_notify.in b/cman/notifyd/cman_notify.in
deleted file mode 100644
index 447657b..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 0668e59..0000000
--- a/cman/notifyd/main.c
+++ /dev/null
@@ -1,506 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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 <corosync/cfg.h>
-#include <corosync/quorum.h>
-#include <corosync/confdb.h>
-#include "liblogthread.h"
-#include "ccs.h"
-
-#include "copyright.cf"
-
-int debug = 0;
-int daemonize = 1;
-int daemon_quit = 0;
-int rr = 0;
-
-
-#define LOCKFILE_NAME CLUSTERVARRUN "/cmannotifyd.pid"
-
-#define OPTION_STRING "hdfVr"
-
-#ifndef MAX_ARGS
-#define MAX_ARGS 128
-#endif
-
-static corosync_cfg_handle_t cfg_handle;
-static quorum_handle_t quorum_handle;
-static confdb_handle_t confdb_handle;
-
-static void corosync_cfg_shutdown_callback (
- corosync_cfg_handle_t cfg_handle,
- corosync_cfg_shutdown_flags_t flags);
-
-static void quorum_notification_callback (
- quorum_handle_t handle,
- uint32_t quorate,
- uint64_t ring_seq,
- uint32_t view_list_entries,
- uint32_t *view_list);
-
-static void confdb_reload_callback (
- confdb_handle_t handle,
- confdb_reload_type_t type);
-
-
-static corosync_cfg_callbacks_t cfg_callbacks =
-{
- .corosync_cfg_state_track_callback = NULL,
- .corosync_cfg_shutdown_callback = corosync_cfg_shutdown_callback
-};
-
-static quorum_callbacks_t quorum_callbacks =
-{
- .quorum_notify_fn = quorum_notification_callback
-};
-
-static confdb_callbacks_t confdb_callbacks =
-{
- .confdb_reload_notify_fn = confdb_reload_callback
-};
-
-
-
-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",
- PACKAGE_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);
- }
-
- 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, uint32_t 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 corosync_cfg_shutdown_callback(corosync_cfg_handle_t handle,
- corosync_cfg_shutdown_flags_t flags)
-{
- logt_print(LOG_DEBUG, "Received a CFG shutdown request\n");
-
- corosync_cfg_replyto_shutdown(handle, COROSYNC_CFG_SHUTDOWN_FLAG_YES);
-
- dispatch_notification("CMAN_REASON_TRY_SHUTDOWN", 0);
-}
-
-
-static void quorum_notification_callback(quorum_handle_t handle,
- uint32_t quorate,
- uint64_t ring_seq,
- uint32_t view_list_entries,
- uint32_t *view_list)
-{
- logt_print(LOG_DEBUG,
- "Received a quorum notification\n");
- dispatch_notification("CMAN_REASON_STATECHANGE", quorate);
-}
-
-static void confdb_reload_callback (
- confdb_handle_t handle,
- confdb_reload_type_t type)
-{
- logt_print(LOG_DEBUG,
- "Received a config reload notification, type=%d\n", type);
- dispatch_notification("CMAN_REASON_CONFIG_UPDATE", 0);
-}
-
-static void byebye_corosync(void)
-{
- if (cfg_handle)
- {
- corosync_cfg_finalize(cfg_handle);
- cfg_handle = 0LL;
- }
- if (quorum_handle)
- {
- quorum_finalize(quorum_handle);
- quorum_handle = 0LL;
- }
- if (confdb_handle)
- {
- confdb_finalize(confdb_handle);
- confdb_handle = 0LL;
- }
-}
-
-static void setup_corosync(int forever)
-{
- int init = 0;
- cs_error_t cs_err;
-
-retry_init:
-
- if (!cfg_handle) {
- cs_err = corosync_cfg_initialize(&cfg_handle, &cfg_callbacks);
- if (cs_err != CS_OK)
- goto init_fail;
- }
-
- if (!quorum_handle) {
- cs_err = quorum_initialize(&quorum_handle, &quorum_callbacks);
- if (cs_err != CS_OK)
- goto init_fail;
- cs_err = quorum_trackstart(quorum_handle, CS_TRACK_CHANGES);
- }
-
- if (!confdb_handle) {
- cs_err = confdb_initialize(&confdb_handle, &confdb_callbacks);
- if (cs_err != CS_OK)
- goto init_fail;
- cs_err = confdb_track_changes(confdb_handle, OBJECT_PARENT_HANDLE, CONFDB_TRACK_DEPTH_ONE);
- }
- goto out_ok;
-
-init_fail:
- if ((init++ < 5) || (forever)) {
- if (daemon_quit)
- goto out;
-
- sleep(1);
- goto retry_init;
- }
- logt_print(LOG_CRIT, "corosync_init error %d\n", errno);
- exit(EXIT_FAILURE);
-
-out:
- byebye_corosync();
-out_ok:
- return;
-}
-
-static void loop(void)
-{
- cs_error_t cs_result;
- int select_result;
- fd_set read_fds;
- int cfg_fd;
- int quorum_fd;
- int confdb_fd;
-
- do {
- FD_ZERO (&read_fds);
- corosync_cfg_fd_get(cfg_handle, &cfg_fd);
- confdb_fd_get(confdb_handle, &confdb_fd);
- quorum_fd_get(quorum_handle, &quorum_fd);
- FD_SET (cfg_fd, &read_fds);
- FD_SET (confdb_fd, &read_fds);
- FD_SET (quorum_fd, &read_fds);
- select_result = select(FD_SETSIZE, &read_fds, 0, 0, 0);
-
- if (daemon_quit)
- goto out;
-
- if (select_result == -1) {
- logt_print(LOG_CRIT, "Unable to select on corosync fds: %s\n", strerror(errno));
- byebye_corosync();
- logt_print(LOG_DEBUG, "waiting for corosync to reappear..\n");
- setup_corosync(1);
- logt_print(LOG_DEBUG, "corosync is back..\n");
- }
-
- if (FD_ISSET(cfg_fd, &read_fds)) {
- cs_result = corosync_cfg_dispatch(cfg_handle, CS_DISPATCH_ONE);
- if (cs_result != CS_OK) {
- byebye_corosync();
- logt_print(LOG_DEBUG, "waiting for corosync to reappear..\n");
- setup_corosync(1);
- logt_print(LOG_DEBUG, "corosync is back..\n");
- }
- }
- if (FD_ISSET(confdb_fd, &read_fds)) {
- cs_result = confdb_dispatch(confdb_handle, CS_DISPATCH_ONE);
- if (cs_result != CS_OK) {
- byebye_corosync();
- logt_print(LOG_DEBUG, "waiting for corosync to reappear..\n");
- setup_corosync(1);
- logt_print(LOG_DEBUG, "corosync is back..\n");
- }
- }
- if (FD_ISSET(quorum_fd, &read_fds)) {
- cs_result = quorum_dispatch(quorum_handle, CS_DISPATCH_ONE);
- if (cs_result != CS_OK) {
- byebye_corosync();
- logt_print(LOG_DEBUG, "waiting for corosync to reappear..\n");
- setup_corosync(1);
- logt_print(LOG_DEBUG, "corosync is back..\n");
- }
- }
- } while (select_result && !daemon_quit);
-
-out:
- logt_print(LOG_DEBUG, "shutting down...\n");
- byebye_corosync();
-}
-
-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_corosync(0);
- loop();
-
- return 0;
-}
diff --git a/cman/qdisk/Makefile.am b/cman/qdisk/Makefile.am
deleted file mode 100644
index 3ba8d98..0000000
--- a/cman/qdisk/Makefile.am
+++ /dev/null
@@ -1,28 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-AM_CPPFLAGS = -D_GNU_SOURCE \
- -I$(top_srcdir)/common/liblogthread/ \
- -I$(top_srcdir)/config/libs/libccsconfdb/ \
- -I$(top_srcdir)/cman/services/cman/lib/
-
-AM_LDFLAGS = -lpthread -lz -lrt
-
-sbin_PROGRAMS = qdiskd mkqdisk
-
-noinst_HEADERS = disk.h iostate.h platform.h scandisk.h score.h
-
-shared_SOURCES = disk.c disk_util.c proc.c scandisk.c iostate.c
-
-qdiskd_SOURCES = main.c score.c bitmap.c daemon_init.c \
- $(shared_SOURCES)
-
-mkqdisk_SOURCES = mkqdisk.c \
- $(shared_SOURCES)
-
-shared_LDADD = $(top_builddir)/common/liblogthread/liblogthread.la
-
-qdiskd_LDADD = $(top_builddir)/config/libs/libccsconfdb/libccs.la \
- $(top_builddir)/cman/services/cman/lib/libcman.la \
- $(shared_LDADD)
-
-mkqdisk_LDADD = $(shared_LDADD)
diff --git a/cman/qdisk/bitmap.c b/cman/qdisk/bitmap.c
deleted file mode 100644
index d893c98..0000000
--- a/cman/qdisk/bitmap.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/** @file
- * Bitmap and membership mask handling routines.
- */
-#include "clusterautoconfig.h"
-
-#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 1b71738..0000000
--- a/cman/qdisk/daemon_init.c
+++ /dev/null
@@ -1,239 +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 "clusterautoconfig.h"
-
-#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), CLUSTERVARRUN "/%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 8e9bb4b..0000000
--- a/cman/qdisk/disk.c
+++ /dev/null
@@ -1,792 +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 "clusterautoconfig.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <string.h>
-#include <errno.h>
-#include <disk.h>
-#include <platform.h>
-#include <unistd.h>
-#include <time.h>
-#include <linux/fs.h>
-#include <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_verify");
- return -1;
- }
-
- ret = qdisk_open(partname, &disk);
- if (ret < 0) {
- logt_print(LOG_ERR, "qdisk_open");
- return -1;
- }
-
- if (header_init(&disk, label) < 0) {
- return -1;
- }
-
- time(&t);
-
- ps.ps_magic = STATE_MAGIC_NUMBER;
- ps.ps_updatenode = 0;
- ps.pad0 = 0;
- ps.ps_timestamp = (uint64_t)t;
- ps.ps_state = (uint8_t)S_NONE;
- ps.pad1[0] = 0;
- ps.ps_flags = 0;
- ps.ps_score = 0;
- ps.ps_scoremax = 0;
- ps.ps_ca_sec = 0;
- ps.ps_ca_usec = 0;
- ps.ps_lc_sec = 0;
- ps.ps_ca_usec = 0;
-
- /* Node IDs 1..N */
- for (nid = 1; nid <= MAX_NODES_DISK; nid++) {
- ps.ps_nodeid = nid;
-
- printf("Initializing status block for node %d...\n", nid);
- wps = ps;
- swab_status_block_t(&wps);
-
- if (qdisk_write(&disk, qdisk_nodeid_offset(nid, disk.d_blksz), &wps, sizeof(wps)) < 0) {
- printf("Error writing node ID block %d\n", nid);
- qdisk_close(&disk);
- return -1;
- }
- }
-
- qdisk_close(&disk);
-
- return 0;
-}
-
diff --git a/cman/qdisk/disk.h b/cman/qdisk/disk.h
deleted file mode 100644
index b00c580..0000000
--- a/cman/qdisk/disk.h
+++ /dev/null
@@ -1,285 +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.
-} disk_node_state_t;
-
-
-typedef enum {
- M_NONE = 0x0,
- M_BID = 0x1,
- M_ACK = 0x2,
- M_NACK = 0x3,
- M_MASK = 0x4
-} disk_msg_id_t;
-
-
-typedef enum {
- FL_MSG = 0x1,
- FL_BID = 0x2,
- FL_VOTE = 0x4
-} disk_state_flag_t;
-
-
-typedef enum {
- RF_REBOOT = 0x1, /* Reboot if we go from master->none */
- RF_STOP_CMAN = 0x2,
- RF_DEBUG = 0x4,
- RF_PARANOID = 0x8,
- RF_ALLOW_KILL = 0x10,
- RF_UPTIME = 0x20,
- RF_CMAN_LABEL = 0x40,
- RF_IOTIMEOUT = 0x80
-} run_flag_t;
-
-
-/* RHEL 2.1 / RHCS3 old magic numbers */
-#define HEADER_MAGIC_OLD 0x39119FCD /* partition header */
-#define STATE_MAGIC_OLD 0xF1840DCE /* Status block */
-#define SHARED_HEADER_MAGIC_OLD 0x00DEBB1E /* Per-block header */
-
-/* Conversion */
-#define HEADER_MAGIC_NUMBER 0xeb7a62c2 /* Partition header */
-#define STATE_MAGIC_NUMBER 0x47bacef8 /* Status block */
-#define SHARED_HEADER_MAGIC 0x00DEBB1E /* Per-block headeer */
-
-/* Version magic. */
-#define VERSION_MAGIC_V2 0x389fabc4
-
-
-typedef struct __attribute__ ((packed)) {
- uint32_t ps_magic;
- /* 4 */
- uint32_t ps_updatenode; // Last writer
- /* 8 */
- uint64_t ps_timestamp; // time of last update
- /* 16 */
- uint32_t ps_nodeid;
- uint32_t pad0;
- /* 24 */
- uint8_t ps_state; // running or stopped
- uint8_t pad1[1];
- uint16_t ps_flags;
- /* 26 */
- uint16_t ps_score; // Local points
- uint16_t ps_scoremax; // What we think is our max
- // points, if other nodes
- // disagree, we may be voted
- // out
- /* 28 */
- uint32_t ps_ca_sec; // Cycle speed (average)
- uint32_t ps_ca_usec;
- /* 36 */
- uint32_t ps_lc_sec; // Cycle speed (last)
- uint32_t ps_lc_usec;
- uint64_t ps_incarnation; // Token to detect hung +
- // restored node
- /* 44 */
- uint16_t ps_msg; // Vote/bid mechanism
- uint16_t ps_seq;
- uint32_t ps_arg;
- /* 52 */
- memb_mask_t ps_mask; // Bitmap
- memb_mask_t ps_master_mask; // Bitmap
- /* 60 */
-} status_block_t;
-
-#define swab_status_block_t(ptr) \
-{\
- swab32((ptr)->ps_magic);\
- swab32((ptr)->ps_updatenode);\
- swab64((ptr)->ps_timestamp);\
- swab32((ptr)->ps_nodeid);\
- swab32((ptr)->pad0);\
- /* state + pad */ \
- swab16((ptr)->ps_flags);\
- swab16((ptr)->ps_score);\
- swab16((ptr)->ps_scoremax);\
- /* Cycle speeds */ \
- swab32((ptr)->ps_ca_sec);\
- swab32((ptr)->ps_ca_usec);\
- swab32((ptr)->ps_lc_sec);\
- swab32((ptr)->ps_lc_usec);\
- /* Message */ \
- swab16((ptr)->ps_msg); \
- swab16((ptr)->ps_seq); \
- swab32((ptr)->ps_arg); \
- }
-
-
-/*
- * Shared state disk header. Describes cluster global information.
- */
-typedef struct __attribute__ ((packed)) {
- uint32_t qh_magic;
- uint32_t qh_version; //
- uint64_t qh_timestamp; // time of last update
- char qh_updatehost[128];// Hostname who put this here...
- char qh_cluster[120]; // Cluster name; CMAN only
- // supports 16 chars.
- uint32_t qh_blksz; // Known block size @ creation
- uint32_t qh_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_pad;
- 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;
-
-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 fc56d1d..0000000
--- a/cman/qdisk/disk_util.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/**
- @file Misc. Quorum daemon context utilities / high-level functions
- */
-
-#include "clusterautoconfig.h"
-
-#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 3d861ec..0000000
--- a/cman/qdisk/iostate.c
+++ /dev/null
@@ -1,145 +0,0 @@
-#include "clusterautoconfig.h"
-
-#include <pthread.h>
-#include <iostate.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/time.h>
-#include <liblogthread.h>
-#include "iostate.h"
-
-static iostate_t main_state = 0;
-static int main_incarnation = 0;
-static int qdisk_timeout = 0, sleeptime = 0;
-static int thread_active = 0;
-static pthread_t io_nanny_tid = 0;
-static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t state_cond = PTHREAD_COND_INITIALIZER;
-
-struct state_table {
- iostate_t state;
- const char *value;
-};
-
-static struct state_table io_state_table[] = {
-{ STATE_NONE, "none" },
-{ STATE_WRITE, "write" },
-{ STATE_READ, "read" },
-{ STATE_LSEEK, "seek" },
-{ -1, NULL } };
-
-static const char *
-state_to_string(iostate_t state)
-{
- static const char *ret = "unknown";
- int i;
-
- for (i=0; io_state_table[i].value; i++) {
- if (io_state_table[i].state == state) {
- ret = io_state_table[i].value;
- break;
- }
- }
-
- return ret;
-}
-
-
-void
-io_state(iostate_t state)
-{
- pthread_mutex_lock(&state_mutex);
- main_state = state;
- main_incarnation++; /* it does not matter if this wraps. */
-
- /* 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;
-
- /* Start with wherever we're at now */
- pthread_mutex_lock(&state_mutex);
- current_main_state = last_main_state = main_state;
- current_main_incarnation = last_main_incarnation = main_incarnation;
- pthread_mutex_unlock(&state_mutex);
-
- while (thread_active) {
- pthread_mutex_lock(&state_mutex);
- clock_gettime(CLOCK_REALTIME, &wait_time);
- wait_time.tv_sec += sleeptime;
- pthread_cond_timedwait(&state_cond, &state_mutex, &wait_time);
- current_main_state = main_state;
- current_main_incarnation = main_incarnation;
- pthread_mutex_unlock(&state_mutex);
-
- if (!thread_active)
- break;
-
- if (!current_main_state)
- continue;
-
- /* if the state or incarnation changed, the main qdiskd
- * thread is healthy */
- if (current_main_state != last_main_state ||
- current_main_incarnation != last_main_incarnation) {
- last_main_state = current_main_state;
- last_main_incarnation = current_main_incarnation;
- continue;
- }
-
- /* Don't log things twice */
- if (logged_incarnation == current_main_incarnation)
- continue;
- logged_incarnation = current_main_incarnation;
-
- 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(int timeout)
-{
- int ret;
-
- pthread_mutex_lock(&state_mutex);
-
- sleeptime = timeout / 2;
- qdisk_timeout = timeout;
- thread_active = 1;
-
- ret = pthread_create(&io_nanny_tid, NULL, io_nanny_thread, NULL);
- pthread_mutex_unlock(&state_mutex);
-
- return ret;
-}
-
-
-int
-io_nanny_stop(void)
-{
- thread_active = 0;
- pthread_cond_broadcast(&state_cond);
- pthread_join(io_nanny_tid, NULL);
- io_nanny_tid = 0;
-
- return 0;
-}
diff --git a/cman/qdisk/iostate.h b/cman/qdisk/iostate.h
deleted file mode 100644
index 7dd7bf6..0000000
--- a/cman/qdisk/iostate.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _IOSTATE_H
-#define _IOSTATE_H
-
-typedef enum {
- STATE_NONE = 0,
- STATE_READ = 1,
- STATE_WRITE = 2,
- STATE_LSEEK = 3,
- STATE_UNKNOWN = 4
-} iostate_t;
-
-void io_state(iostate_t state);
-
-int io_nanny_start(int timeout);
-int io_nanny_stop(void);
-
-#endif
diff --git a/cman/qdisk/main.c b/cman/qdisk/main.c
deleted file mode 100644
index e07e76c..0000000
--- a/cman/qdisk/main.c
+++ /dev/null
@@ -1,1879 +0,0 @@
-/**
- @file Main loop / functions for disk-based quorum daemon.
- */
-
-#include "clusterautoconfig.h"
-
-#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 <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) {
- /* 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 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 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_ctx *ctx = (qd_ctx *)private;
-
- 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;
- 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;
- 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;
- 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 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;
-}
-
-
-static int
-get_dynamic_config_data(qd_ctx *ctx, int ccsfd)
-{
- char *val = NULL;
- char query[256];
-
- if (ccsfd < 0)
- return -1;
-
- logt_print(LOG_DEBUG, "Loading dynamic configuration\n");
-
- /* 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);
- }
-
- return 0;
-}
-
-
-static int
-get_static_config_data(qd_ctx *ctx, int ccsfd)
-{
- char *val = NULL;
- char query[256];
-
- 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;
- }
-
- /* Get tko */
- snprintf(query, sizeof(query), "/cluster/quorumd/@tko");
- if (ccs_get(ccsfd, query, &val) == 0) {
- ctx->qc_tko = atoi(val);
- free(val);
- if (ctx->qc_tko < 3)
- ctx->qc_tko = 3;
- }
-
- /* Get up-tko (transition off->online) */
- ctx->qc_tko_up = (ctx->qc_tko / 3);
- snprintf(query, sizeof(query), "/cluster/quorumd/@tko_up");
- if (ccs_get(ccsfd, query, &val) == 0) {
- ctx->qc_tko_up = atoi(val);
- free(val);
- }
- if (ctx->qc_tko_up < 2)
- ctx->qc_tko_up = 2;
-
- /* After coming online, wait this many intervals before
- being allowed to bid for master. */
- ctx->qc_upgrade_wait = 2; /* (ctx->qc_tko / 3); */
- snprintf(query, sizeof(query), "/cluster/quorumd/@upgrade_wait");
- if (ccs_get(ccsfd, query, &val) == 0) {
- ctx->qc_upgrade_wait = atoi(val);
- free(val);
- }
- if (ctx->qc_upgrade_wait < 1)
- ctx->qc_upgrade_wait = 1;
-
- /* wait this many intervals after bidding for master before
- becoming Caesar */
- ctx->qc_master_wait = (ctx->qc_tko / 2);
- snprintf(query, sizeof(query), "/cluster/quorumd/@master_wait");
- if (ccs_get(ccsfd, query, &val) == 0) {
- ctx->qc_master_wait = atoi(val);
- free(val);
- }
- if (ctx->qc_master_wait <= ctx->qc_tko_up)
- ctx->qc_master_wait = ctx->qc_tko_up + 1;
-
- /* Get votes */
- snprintf(query, sizeof(query), "/cluster/quorumd/@votes");
- if (ccs_get(ccsfd, query, &val) == 0) {
- ctx->qc_votes = atoi(val);
- free(val);
- if (ctx->qc_votes < 0)
- ctx->qc_votes = 0;
- }
-
- /* Get device */
- snprintf(query, sizeof(query), "/cluster/quorumd/@device");
- if (ccs_get(ccsfd, query, &val) == 0) {
- ctx->qc_device = val;
- }
-
- /* Get label (overrides device) */
- snprintf(query, sizeof(query), "/cluster/quorumd/@label");
- if (ccs_get(ccsfd, query, &val) == 0) {
- ctx->qc_label = val;
- }
-
- /* Get 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 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;
-
- 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 (ctx->qc_config ||
- get_dynamic_config_data(ctx, ccsfd) < 0)
- goto out;
-
- ctx->qc_config = 1;
-
- if (get_static_config_data(ctx, ccsfd) < 0)
- goto out;
-
- *cfh = configure_heuristics(ccsfd, h, maxh);
-
- 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, "%d tko_up, %d master_wait, "
- "%d upgrade_wait\n",
- ctx->qc_tko_up, ctx->qc_master_wait, ctx->qc_upgrade_wait);
-out:
- logt_print(LOG_DEBUG, "Run Flags: %08x\n", ctx->qc_flags);
-
- ccs_disconnect(ccsfd);
-
- return 0;
-}
-
-
-static void
-check_stop_cman(qd_ctx *ctx)
-{
- if (!(ctx->qc_flags & RF_STOP_CMAN))
- return;
-
- 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)
-
-
-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;
-
- 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 */
- ch_user = cman_init(&ctx);
- 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;
- }
-
- 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;
-
- cman_register_quorum_device(ctx.qc_cman_admin,
- (ctx.qc_flags&RF_CMAN_LABEL)?
- ctx.qc_cman_label:
- ctx.qc_device,
- ctx.qc_votes);
- /*
- XXX this always returns -1 / EBUSY even when it works?!!!
-
- if ((rv = cman_register_quorum_device(ctx.qc_cman_admin, ctx.qc_device,
- ctx.qc_votes)) < 0) {
- logt_print(LOG_CRIT,
- "Could not register %s with CMAN; "
- "return = %d; error = %s\n",
- ctx.qc_device, rv, strerror(errno));
- goto out;
- }
- */
-
- io_nanny_start(ctx.qc_tko * ctx.qc_interval);
-
- if (quorum_loop(&ctx, ni, MAX_NODES_DISK) == 0) {
- /* Only clean up if we're exiting w/o error) */
- 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 80d1f8a..0000000
--- a/cman/qdisk/mkqdisk.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- @file Quorum disk utility
- */
-
-#include "clusterautoconfig.h"
-
-#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, verbose_level = 1;
-
- printf(PROGRAM_NAME " v" PACKAGE_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 */
- return find_partitions(NULL, NULL, 0, verbose_level);
- case 'f':
- return find_partitions( optarg, device,
- sizeof(device), verbose_level);
- case 'c':
- newdev = optarg;
- break;
- case 'l':
- newlabel = optarg;
- break;
- case 'h':
- printf("usage: mkqdisk -L | -f <label> | -c "
- "<device> -l <label> [-d]\n");
- return 0;
- default:
- break;
- }
- }
-
- if (!newdev && !newlabel) {
- printf("usage: mkqdisk -L | -f <label> | -c "
- "<device> -l <label>\n");
- return 1;
- }
-
- if (!newdev || !newlabel) {
- printf("Both a device and a label are required\n");
- return 1;
- }
-
- printf("Writing new quorum disk label '%s' to %s.\n",
- newlabel, newdev);
- printf("WARNING: About to destroy all data on %s; proceed [N/y] ? ",
- newdev);
- if (getc(stdin) != 'y') {
- printf("Good thinking.\n");
- return 0;
- }
-
- return qdisk_init(newdev, newlabel);
-}
diff --git a/cman/qdisk/platform.h b/cman/qdisk/platform.h
deleted file mode 100644
index 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 5f5f4b7..0000000
--- a/cman/qdisk/proc.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/**
- @file Quorum disk /proc/partition scanning functions
- */
-
-#include "clusterautoconfig.h"
-
-#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_verify");
- return -1;
- }
-
- ret = qdisk_open(device, &disk);
- if (ret < 0) {
- logt_print(LOG_ERR, "qdisk_open");
- 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 3825ec4..0000000
--- a/cman/qdisk/scandisk.c
+++ /dev/null
@@ -1,766 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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 70cd500..0000000
--- a/cman/qdisk/score.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/**
- @file Quorum daemon scoring functions + thread.
- */
-
-#include "clusterautoconfig.h"
-
-#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)
-{
- int pid;
- char *argv[4];
- time_t now;
-
- if (h->childpid) {
- errno = EINPROGRESS;
- return -1;
- }
-
- now = time(NULL);
- if (now < h->nextrun)
- return 0;
-
- h->nextrun = now + h->interval;
-
- pid = fork();
- if (pid < 0)
- return -1;
-
- if (pid) {
- h->childpid = pid;
- return 0;
- }
-
- /*
- * always use SCHED_OTHER for the child processes
- * nice -1 is fine; but we don't know what the child process
- * might do, so leaving it (potentially) in SCHED_RR or SCHED_FIFO
- * is out of the question
- *
- * XXX if you set SCHED_OTHER in the conf file and nice 20, the below
- * will make the heuristics a higher prio than qdiskd. This should be
- * fine in practice, because running qdiskd at nice 20 will cause all
- * sorts of problems on a busy system.
- */
- set_priority(SCHED_OTHER, -1);
- munlockall();
- restore_signals();
-
- argv[0] = 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)
-{
- int ret;
- int status;
-
- if (h->childpid == 0)
- /* No child to check */
- return 0;
-
- ret = waitpid(h->childpid, &status, block?0:WNOHANG);
- if (!block && ret == 0)
- /* No children exited */
- return 0;
-
- h->childpid = 0;
- if (ret < 0 && errno == ECHILD)
- /* wrong child? */
- goto miss;
- if (!WIFEXITED(status)) {
- ret = 0;
- goto miss;
- }
- if (WEXITSTATUS(status) != 0) {
- ret = 0;
- goto miss;
- }
-
- /* Returned 0 and was not killed */
- if (!h->available) {
- h->available = 1;
- 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)
-{
- int x;
-
- for (x = 0; x < max; x++)
- fork_heuristic(&h[x]);
- return 0;
-}
-
-
-/**
- Check all available heuristics
- */
-static int
-check_heuristics(struct h_data *h, int max, int block)
-{
- int x;
-
- for (x = 0; x < max; x++)
- check_heuristic(&h[x], block);
- return 0;
-}
-
-
-/**
- Read configuration data from CCS into the array provided
- */
-int
-configure_heuristics(int ccsfd, struct h_data *h, int max)
-{
- int x = 0;
- char *val;
- char query[128];
-
- if (!h || !max)
- return -1;
-
- do {
- h[x].program = NULL;
- h[x].available = 0;
- h[x].misses = 0;
- h[x].interval = 2;
- h[x].tko = 1;
- h[x].score = 1;
- h[x].childpid = 0;
- h[x].nextrun = 0;
-
- /* Get program */
- snprintf(query, sizeof(query),
- "/cluster/quorumd/heuristic[%d]/@program", x+1);
- if (ccs_get(ccsfd, query, &val) != 0)
- /* No more */
- break;
- h[x].program = val;
-
- /* Get score */
- snprintf(query, sizeof(query),
- "/cluster/quorumd/heuristic[%d]/@score", x+1);
- if (ccs_get(ccsfd, query, &val) == 0) {
- h[x].score = atoi(val);
- free(val);
- if (h[x].score <= 0)
- h[x].score = 1;
- }
-
- /* Get query interval */
- snprintf(query, sizeof(query),
- "/cluster/quorumd/heuristic[%d]/@interval", x+1);
- if (ccs_get(ccsfd, query, &val) == 0) {
- h[x].interval = atoi(val);
- free(val);
- if (h[x].interval <= 0)
- h[x].interval = 2;
- }
-
- /* Get tko for this heuristic */
- snprintf(query, sizeof(query),
- "/cluster/quorumd/heuristic[%d]/@tko", x+1);
- if (ccs_get(ccsfd, query, &val) == 0) {
- h[x].tko= atoi(val);
- free(val);
- if (h[x].tko <= 0)
- h[x].tko = 1;
- }
-
- 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 77e155b..0000000
--- a/cman/qdisk/score.h
+++ /dev/null
@@ -1,44 +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;
- int score;
- int available;
- int tko;
- int interval;
- int misses;
- pid_t childpid;
- time_t nextrun;
-};
-
-/*
- Grab score data from CCSD
- */
-int configure_heuristics(int ccsfd, struct h_data *hp, int max);
-
-/*
- 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/services/Makefile.am b/cman/services/Makefile.am
deleted file mode 100644
index 57fe042..0000000
--- a/cman/services/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-SUBDIRS = cman
diff --git a/cman/services/cman/Makefile.am b/cman/services/cman/Makefile.am
deleted file mode 100644
index 26df9bf..0000000
--- a/cman/services/cman/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-SUBDIRS = services lib include
diff --git a/cman/services/cman/include/Makefile.am b/cman/services/cman/include/Makefile.am
deleted file mode 100644
index 5226209..0000000
--- a/cman/services/cman/include/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-noinst_HEADERS = corosync/cman.h corosync/ipc_cman.h
diff --git a/cman/services/cman/include/corosync/cman.h b/cman/services/cman/include/corosync/cman.h
deleted file mode 100644
index baedf35..0000000
--- a/cman/services/cman/include/corosync/cman.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef CMAN_H_DEFINED
-#define CMAN_H_DEFINED
-
-// Actually -- we return proper errnos
-typedef enum {
- CMAN_OK = 1,
- CMAN_ERR_LIBRARY = 2,
- CMAN_ERR_TIMEOUT = 5,
- CMAN_ERR_TRY_AGAIN = 6,
- CMAN_ERR_INVALID_PARAM = 7,
- CMAN_ERR_NO_MEMORY = 8,
- CMAN_ERR_BAD_HANDLE = 9,
- CMAN_ERR_ACCESS = 11,
- CMAN_ERR_NOT_EXIST = 12,
- CMAN_ERR_EXIST = 14,
- CMAN_ERR_NOT_SUPPORTED = 20,
- CMAN_ERR_SECURITY = 29
-} cman_error_t;
-
-typedef unsigned int cman_handle_t;
-typedef void (*cman_callback_t)(cman_handle_t handle, void *privdata, int reason, int arg);
-typedef void (*cman_datacallback_t)(cman_handle_t handle, void *privdata,
- char *buf, int len, uint8_t port, int nodeid);
-
-/* Shutdown flags */
-#define SHUTDOWN_ANYWAY 1
-#define SHUTDOWN_REMOVE 2
-
-typedef enum {CMAN_REASON_PORTCLOSED,
- CMAN_REASON_STATECHANGE,
- CMAN_REASON_PORTOPENED,
- CMAN_REASON_TRY_SHUTDOWN,
- CMAN_REASON_CONFIG_UPDATE} cman_call_reason_t;
-
-
-
-
-
-#endif
diff --git a/cman/services/cman/include/corosync/ipc_cman.h b/cman/services/cman/include/corosync/ipc_cman.h
deleted file mode 100644
index d74f152..0000000
--- a/cman/services/cman/include/corosync/ipc_cman.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef IPC_CMAN_H_DEFINED
-#define IPC_CMAN_H_DEFINED
-
-#include <netinet/in.h>
-
-#define CMAN_SERVICE 9
-
-// These don't
-enum req_cman_types {
- MESSAGE_REQ_CMAN_SENDMSG = 0,
- MESSAGE_REQ_CMAN_IS_LISTENING,
- MESSAGE_REQ_CMAN_BIND,
- MESSAGE_REQ_CMAN_UNBIND
-};
-
-enum res_cman_types {
- MESSAGE_RES_CMAN_SENDMSG = 0,
- MESSAGE_RES_CMAN_IS_LISTENING,
- MESSAGE_RES_CMAN_BIND,
- MESSAGE_RES_CMAN_UNBIND
-};
-
-#define TOTEMIP_ADDRLEN (sizeof(struct in6_addr))
-
-struct req_lib_cman_bind {
- coroipc_request_header_t header __attribute__((aligned(8)));
- unsigned int port;
-};
-
-struct req_lib_cman_sendmsg {
- coroipc_request_header_t header __attribute__((aligned(8)));
- unsigned int to_port;
- unsigned int to_node;
- unsigned int msglen;
- char message[];
-};
-
-struct res_lib_cman_sendmsg {
- coroipc_response_header_t header __attribute__((aligned(8)));
- unsigned int from_port;
- unsigned int from_node;
- unsigned int msglen;
- char message[];
-};
-
-struct req_lib_cman_is_listening {
- coroipc_request_header_t header __attribute__((aligned(8)));
- unsigned int port;
- unsigned int nodeid;
-};
-
-struct res_lib_cman_is_listening {
- coroipc_response_header_t header __attribute__((aligned(8)));
- unsigned int status;
-};
-
-
-#endif
diff --git a/cman/services/cman/lib/Makefile.am b/cman/services/cman/lib/Makefile.am
deleted file mode 100644
index 0d7c74e..0000000
--- a/cman/services/cman/lib/Makefile.am
+++ /dev/null
@@ -1,21 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-libversion = 4:0:0
-
-include_HEADERS = libcman.h
-
-pkgconfigdir = $(libdir)/pkgconfig
-
-pkgconfig_DATA = libcman.pc
-
-lib_LTLIBRARIES = libcman.la
-
-libcman_la_CPPFLAGS = -I$(top_srcdir)/config/libs/libccsconfdb \
- -I$(top_srcdir)/cman/services/cman/include
-
-libcman_la_CFLAGS = $(coroipcc_CFLAGS) $(cfg_CFLAGS) $(votequorum_CFLAGS)
-
-libcman_la_LDFLAGS = $(coroipcc_LIBS) $(cfg_LIBS) $(votequorum_LIBS) \
- -version-info $(libversion)
-
-libcman_la_LIBADD = $(top_builddir)/config/libs/libccsconfdb/libccs.la
diff --git a/cman/services/cman/lib/libcman.c b/cman/services/cman/lib/libcman.c
deleted file mode 100644
index aed5626..0000000
--- a/cman/services/cman/lib/libcman.c
+++ /dev/null
@@ -1,1274 +0,0 @@
-/*
- * Provides a cman API using the corosync executive
- */
-
-#include "clusterautoconfig.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <errno.h>
-#include <netdb.h>
-#include <limits.h>
-
-#include <corosync/corotypes.h>
-#include <corosync/coroipc_types.h>
-#include <corosync/coroipcc.h>
-#include <corosync/corodefs.h>
-#include <corosync/hdb.h>
-#include <corosync/cfg.h>
-#include <corosync/confdb.h>
-#include <corosync/votequorum.h>
-#include <corosync/ipc_cman.h>
-
-#include "ccs.h"
-#include "libcman.h"
-
-DECLARE_HDB_DATABASE(cman_handle_t_db,NULL);
-
-#define CMAN_MAGIC 0x434d414e
-
-#define IPC_REQUEST_SIZE 8192*128
-#define IPC_RESPONSE_SIZE 8192*128
-#define IPC_DISPATCH_SIZE 8192*128
-
-#define CMAN_SHUTDOWN_ANYWAY 1
-#define CMAN_SHUTDOWN_REMOVED 2
-
-struct cman_inst {
- int magic;
- hdb_handle_t handle;
- int finalize;
- void *privdata;
- cman_datacallback_t data_callback;
- cman_callback_t notify_callback;
-
- int node_count;
- votequorum_node_t * node_list;
- int node_list_size;
-
- corosync_cfg_handle_t cfg_handle;
- votequorum_handle_t voteq_handle;
-};
-
-static void cfg_shutdown_callback(
- corosync_cfg_handle_t handle,
- corosync_cfg_shutdown_flags_t flags);
-
-static void votequorum_notification_callback(
- votequorum_handle_t handle,
- uint64_t context,
- uint32_t quorate,
- uint32_t node_list_entries,
- votequorum_node_t node_list[]);
-
-static votequorum_callbacks_t cmq_callbacks =
-{
- .votequorum_notify_fn = votequorum_notification_callback,
-};
-
-static corosync_cfg_callbacks_t cfg_callbacks =
-{
- .corosync_cfg_state_track_callback = NULL,
- .corosync_cfg_shutdown_callback = cfg_shutdown_callback,
-};
-
-
-#define VALIDATE_HANDLE(h) do {if (!(h) || (h)->magic != CMAN_MAGIC) {errno = EINVAL; return -1;}} while (0)
-
-static struct cman_inst *admin_inst;
-
-static void cfg_shutdown_callback(
- corosync_cfg_handle_t handle,
- corosync_cfg_shutdown_flags_t flags)
-{
- int cman_flags = 0;
-
- if (!admin_inst)
- return;
-
- if (flags == COROSYNC_CFG_SHUTDOWN_FLAG_REGARDLESS)
- cman_flags = CMAN_SHUTDOWN_ANYWAY;
-
- if (admin_inst->notify_callback)
- admin_inst->notify_callback((void *)admin_inst, admin_inst->privdata, CMAN_REASON_TRY_SHUTDOWN, cman_flags);
-
-}
-
-static void votequorum_notification_callback(
- votequorum_handle_t handle,
- uint64_t context,
- uint32_t quorate,
- uint32_t node_list_entries,
- votequorum_node_t node_list[])
-{
- struct cman_inst *cman_inst;
-
- votequorum_context_get(handle, (void **)&cman_inst);
-
- /* Save information for synchronous queries */
- cman_inst->node_count = node_list_entries;
- if (cman_inst->node_list_size < node_list_entries) {
- if (cman_inst->node_list)
- free(cman_inst->node_list);
-
- cman_inst->node_list = malloc(sizeof(votequorum_node_t) * node_list_entries * 2);
- if (cman_inst->node_list) {
- memcpy(cman_inst->node_list, node_list, sizeof(votequorum_node_t) * node_list_entries);
- cman_inst->node_list_size = node_list_entries;
- }
- }
-
- if (context && cman_inst->notify_callback)
- cman_inst->notify_callback((void*)cman_inst, cman_inst->privdata, CMAN_REASON_STATECHANGE, quorate);
-}
-
-static int votequorum_check_and_start(struct cman_inst *cman_inst)
-{
- if (!cman_inst->voteq_handle) {
- if (votequorum_initialize(&cman_inst->voteq_handle, &cmq_callbacks) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- votequorum_context_set(cman_inst->voteq_handle, (void*)cman_inst);
- }
- return 0;
-}
-
-static int refresh_node_list(struct cman_inst *cman_inst)
-{
- int error;
-
- if (votequorum_check_and_start(cman_inst))
- return -1;
-
- votequorum_trackstart(cman_inst->voteq_handle, 0, CS_TRACK_CURRENT);
-
- error = votequorum_dispatch(cman_inst->voteq_handle, CS_DISPATCH_ONE);
- return (error==CS_OK?0:-1);
-}
-
-cman_handle_t cman_init (
- void *privdata)
-{
- cs_error_t error;
- hdb_handle_t handle;
- struct cman_inst *cman_inst;
-
- error = hdb_handle_create (&cman_handle_t_db, sizeof (struct cman_inst), &handle);
- if (error) {
- goto error_no_destroy;
- }
-
- error = hdb_handle_get (&cman_handle_t_db, handle, (void *)&cman_inst);
- if (error) {
- goto error_destroy;
- }
-
- error = coroipcc_service_connect (
- COROSYNC_SOCKET_NAME,
- CMAN_SERVICE,
- IPC_REQUEST_SIZE,
- IPC_RESPONSE_SIZE,
- IPC_DISPATCH_SIZE,
- &cman_inst->handle);
- if (error != CS_OK) {
- goto error_put_destroy;
- }
-
- cman_inst->privdata = privdata;
- cman_inst->magic = CMAN_MAGIC;
- cman_inst->cfg_handle = (corosync_cfg_handle_t)0LL;
- cman_inst->voteq_handle = (votequorum_handle_t)0LL;
-
- return (void *)cman_inst;
-
-error_put_destroy:
- hdb_handle_put (&cman_handle_t_db, handle);
-error_destroy:
- hdb_handle_destroy (&cman_handle_t_db, handle);
-error_no_destroy:
- errno = ENOMEM;
- return NULL;
-}
-
-cman_handle_t cman_admin_init (
- void *privdata)
-{
- if (admin_inst) {
- errno = EBUSY;
- return NULL;
- }
-
- admin_inst = cman_init(privdata);
- return admin_inst;
-}
-
-
-int cman_finish (
- cman_handle_t handle)
-{
- struct cman_inst *cman_inst;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- if (cman_inst->voteq_handle) {
- votequorum_finalize(cman_inst->voteq_handle);
- cman_inst->voteq_handle = 0;
- }
- if (cman_inst->cfg_handle) {
- corosync_cfg_finalize(cman_inst->cfg_handle);
- cman_inst->cfg_handle = 0;
- }
-
- if (handle == admin_inst)
- admin_inst = NULL;
-
- /*
- * Another thread has already started finalizing
- */
- if (cman_inst->finalize) {
- errno = EINVAL;
- return -1;
- }
-
- cman_inst->finalize = 1;
-
- /*
- * Disconnect from the server
- */
- coroipcc_service_disconnect (cman_inst->handle);
-
- return 0;
-}
-
-/* These next four calls are the only ones that are specific to cman in the release. Everything else
- * uses standard corosync or 'ccs' libraries.
- * If you really want to do inter-node communications then CPG might be more appropriate to
- * your needs. These functions are here partly to provide an API compatibility, but mainly
- * to provide wire-protocol compatibility with older versions.
- */
-int cman_start_recv_data (
- cman_handle_t handle,
- cman_datacallback_t callback,
- uint8_t port)
-{
- int error;
- struct cman_inst *cman_inst;
- struct iovec iov[2];
- struct req_lib_cman_bind req_lib_cman_bind;
- coroipc_response_header_t res;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- req_lib_cman_bind.header.size = sizeof (struct req_lib_cman_bind);
- req_lib_cman_bind.header.id = MESSAGE_REQ_CMAN_BIND;
- req_lib_cman_bind.port = port;
-
- iov[0].iov_base = (char *)&req_lib_cman_bind;
- iov[0].iov_len = sizeof (struct req_lib_cman_bind);
-
- error = coroipcc_msg_send_reply_receive (cman_inst->handle,
- iov, 1,
- &res, sizeof (coroipc_response_header_t));
-
- if (error != CS_OK) {
- goto error_exit;
- }
-
- errno = error = res.error;
-
-error_exit:
- return (error==CS_OK?0:-1);
-}
-
-int cman_end_recv_data (
- cman_handle_t handle)
-{
- int error;
- struct cman_inst *cman_inst;
- struct iovec iov[2];
- coroipc_response_header_t req;
- coroipc_response_header_t res;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- req.size = sizeof (coroipc_response_header_t);
- req.id = MESSAGE_REQ_CMAN_UNBIND;
-
- iov[0].iov_base = (char *)&req;
- iov[0].iov_len = sizeof (coroipc_response_header_t);
-
- error = coroipcc_msg_send_reply_receive (cman_inst->handle,
- iov, 1,
- &res, sizeof (coroipc_response_header_t));
-
- if (error != CS_OK) {
- goto error_exit;
- }
-
- errno = error = res.error;
-
-error_exit:
-
- return (error?-1:0);
-}
-
-int cman_send_data(cman_handle_t handle, const void *message, int len, int flags, uint8_t port, int nodeid)
-{
- int error;
- struct cman_inst *cman_inst;
- struct iovec iov[2];
- char buf[len+sizeof(struct req_lib_cman_sendmsg)];
- struct req_lib_cman_sendmsg *req_lib_cman_sendmsg = (struct req_lib_cman_sendmsg *)buf;
- coroipc_response_header_t res;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- req_lib_cman_sendmsg->header.size = sizeof (coroipc_response_header_t);
- req_lib_cman_sendmsg->header.id = MESSAGE_REQ_CMAN_SENDMSG;
- req_lib_cman_sendmsg->to_port = port;
- req_lib_cman_sendmsg->to_node = nodeid;
- req_lib_cman_sendmsg->msglen = len;
- memcpy(req_lib_cman_sendmsg->message, message, len);
-
- iov[0].iov_base = buf;
- iov[0].iov_len = len+sizeof(struct req_lib_cman_sendmsg);
-
- error = coroipcc_msg_send_reply_receive (cman_inst->handle,
- iov, 1,
- &res, sizeof (coroipc_response_header_t));
-
- if (error != CS_OK) {
- goto error_exit;
- }
-
- errno = error = res.error;
-
-error_exit:
-
- return (error?-1:0);
-}
-
-int cman_is_listening (
- cman_handle_t handle,
- int nodeid,
- uint8_t port)
-{
- int error;
- struct cman_inst *cman_inst;
- struct iovec iov[2];
- struct res_lib_cman_is_listening res_lib_cman_is_listening;
- struct req_lib_cman_is_listening req_lib_cman_is_listening;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- req_lib_cman_is_listening.header.size = sizeof (struct req_lib_cman_is_listening);
- req_lib_cman_is_listening.header.id = MESSAGE_REQ_CMAN_IS_LISTENING;
- req_lib_cman_is_listening.nodeid = nodeid;
- req_lib_cman_is_listening.port = port;
-
- iov[0].iov_base = (char *)&req_lib_cman_is_listening;
- iov[0].iov_len = sizeof (struct req_lib_cman_is_listening);
-
- error = coroipcc_msg_send_reply_receive (cman_inst->handle,
- iov, 1,
- &res_lib_cman_is_listening, sizeof (struct res_lib_cman_is_listening));
-
- if (error != CS_OK) {
- goto error_exit;
- }
-
- errno = error = res_lib_cman_is_listening.header.error;
-
-error_exit:
-
- return (error?-1:0);
-}
-
-/* This call is now handled by cfg */
-int cman_get_node_addrs (
- cman_handle_t handle,
- int nodeid,
- int max_addrs,
- int *num_addrs,
- struct cman_node_address *addrs)
-{
- int error;
- struct cman_inst *cman_inst;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- if (!cman_inst->cfg_handle) {
- if (corosync_cfg_initialize(&cman_inst->cfg_handle, &cfg_callbacks) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
-
- error = corosync_cfg_get_node_addrs(cman_inst->cfg_handle, nodeid, max_addrs, num_addrs, (corosync_cfg_node_address_t *)addrs);
-
- return (error==CS_OK?0:-1);
-}
-
-/*
- * An example of how we would query the quorum service.
- * In fact we can use the lower-level quorum service if quorate all we
- * needed to know - it provides the quorum state regardless of which
- * quorum provider is loaded.
- * Users of libcman typically are nosy and want to know all sorts of
- * other things.
- */
-int cman_is_quorate(cman_handle_t handle)
-{
- struct cman_inst *cman_inst;
- int quorate = -1;
- struct votequorum_info info;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- if (votequorum_check_and_start(cman_inst))
- return -1;
-
- if (votequorum_getinfo(cman_inst->voteq_handle, 0, &info) != CS_OK)
- errno = EINVAL;
- else
- quorate = ((info.flags & VOTEQUORUM_INFO_FLAG_QUORATE) != 0);
-
- return quorate;
-}
-
-/* This call is now handled by cfg */
-int cman_shutdown(cman_handle_t handle, int flags)
-{
- struct cman_inst *cman_inst;
- int error;
- corosync_cfg_shutdown_flags_t cfg_flags = 0;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- if (!cman_inst->cfg_handle) {
- if (corosync_cfg_initialize(&cman_inst->cfg_handle, &cfg_callbacks) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
-
- if (flags && CMAN_LEAVEFLAG_REMOVED) {
- if (votequorum_check_and_start(cman_inst))
- return -1;
-
- votequorum_leaving(cman_inst->voteq_handle);
- }
-
- if (flags == CMAN_SHUTDOWN_ANYWAY)
- cfg_flags = COROSYNC_CFG_SHUTDOWN_FLAG_REGARDLESS;
-
- error = corosync_cfg_try_shutdown(cman_inst->cfg_handle, cfg_flags);
-
- /* ERR_LIBRARY happens because corosync shuts down while we are connected */
- if (error == CS_ERR_LIBRARY || error == CS_OK)
- error = 0;
-
- return error;
-}
-/*
- * This call is now mostly handled by cfg.
- * However if we want to do a "leave remove" then we need to tell
- * votequorum first.
- */
-int cman_leave_cluster(cman_handle_t handle, int flags)
-{
- struct cman_inst *cman_inst;
- int error;
- corosync_cfg_shutdown_flags_t cfg_flags = 0;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- if (!cman_inst->cfg_handle) {
- if (corosync_cfg_initialize(&cman_inst->cfg_handle, &cfg_callbacks) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
-
- /* Tell votequorum to reduce quorum when we go */
- if (flags && CMAN_LEAVEFLAG_REMOVED) {
- if (votequorum_check_and_start(cman_inst))
- return -1;
-
- votequorum_leaving(cman_inst->voteq_handle);
- }
-
-
- cfg_flags = COROSYNC_CFG_SHUTDOWN_FLAG_IMMEDIATE;
-
- error = corosync_cfg_try_shutdown(cman_inst->cfg_handle, cfg_flags);
- /* ERR_LIBRARY happens because corosync shuts down while we are connected */
- if (error == CS_ERR_LIBRARY || error == CS_OK)
- error = 0;
-
- return error;
-}
-
-/* This call is now handled by cfg */
-int cman_replyto_shutdown(cman_handle_t handle, int flags)
-{
- struct cman_inst *cman_inst;
- int error;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- if (!cman_inst->cfg_handle) {
- if (corosync_cfg_initialize(&cman_inst->cfg_handle, &cfg_callbacks) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
-
- error = corosync_cfg_replyto_shutdown(cman_inst->cfg_handle, flags);
-
- return error;
-}
-
-/* This call is now handled by cfg */
-int cman_kill_node(cman_handle_t handle, int nodeid)
-{
- struct cman_inst *cman_inst;
- int error;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- if (!cman_inst->cfg_handle) {
- if (corosync_cfg_initialize(&cman_inst->cfg_handle, &cfg_callbacks) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
-
- error = corosync_cfg_kill_node(cman_inst->cfg_handle, nodeid, "Killed by cman_tool");
-
- return (error==CS_OK?0:-1);
-}
-
-/* This call is handled by votequorum */
-int cman_set_votes(cman_handle_t handle, int votes, int nodeid)
-{
- struct cman_inst *cman_inst;
- int error;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- if (votequorum_check_and_start(cman_inst))
- return -1;
-
- error = votequorum_setvotes(cman_inst->voteq_handle, nodeid, votes);
-
- return (error==CS_OK?0:-1);
-}
-
-/* This call is handled by votequorum */
-int cman_set_expected_votes(cman_handle_t handle, int expected)
-{
- struct cman_inst *cman_inst;
- int error;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- if (votequorum_check_and_start(cman_inst))
- return -1;
-
- error = votequorum_setexpected(cman_inst->voteq_handle, expected);
-
- return (error==CS_OK?0:-1);
-}
-
-int cman_get_fd (
- cman_handle_t handle)
-{
- struct cman_inst *cman_inst;
- int fd;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- coroipcc_fd_get (cman_inst->handle, &fd);
-
- return fd;
-}
-
-int cman_getprivdata(
- cman_handle_t handle,
- void **context)
-{
- struct cman_inst *cman_inst;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- *context = cman_inst->privdata;
-
- return (CS_OK);
-}
-
-int cman_setprivdata(
- cman_handle_t handle,
- void *context)
-{
- struct cman_inst *cman_inst;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- cman_inst->privdata = context;
-
- return (CS_OK);
-}
-
-/* This call is handled by votequorum */
-int cman_register_quorum_device(cman_handle_t handle, char *name, int votes)
-{
- struct cman_inst *cman_inst;
- int error;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- if (votequorum_check_and_start(cman_inst))
- return -1;
-
- error = votequorum_qdisk_register(cman_inst->voteq_handle, name, votes);
-
- return error;
-}
-
-/* This call is handled by votequorum */
-int cman_unregister_quorum_device(cman_handle_t handle)
-{
- struct cman_inst *cman_inst;
- int error;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- if (votequorum_check_and_start(cman_inst))
- return -1;
-
- error = votequorum_qdisk_unregister(cman_inst->voteq_handle);
-
- return error;
-}
-
-/* This call is handled by votequorum */
-int cman_poll_quorum_device(cman_handle_t handle, int isavailable)
-{
- struct cman_inst *cman_inst;
- int error;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- if (votequorum_check_and_start(cman_inst))
- return -1;
-
- error = votequorum_qdisk_poll(cman_inst->voteq_handle, 1);
-
- return error;
-}
-
-/* This call is handled by votequorum */
-int cman_get_quorum_device(cman_handle_t handle, struct cman_qdev_info *info)
-{
- struct cman_inst *cman_inst;
- int error;
- struct votequorum_qdisk_info qinfo;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- if (votequorum_check_and_start(cman_inst))
- return -1;
-
- error = votequorum_qdisk_getinfo(cman_inst->voteq_handle, &qinfo);
-
- if (!error) {
- info->qi_state = qinfo.state;
- info->qi_votes = qinfo.votes;
- strcpy(info->qi_name, qinfo.name);
- }
-
- return error;
-}
-
-/* This call is handled by votequorum */
-int cman_set_dirty(cman_handle_t handle)
-{
- struct cman_inst *cman_inst;
- int error;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- if (votequorum_check_and_start(cman_inst))
- return -1;
-
- error = votequorum_setstate(cman_inst->voteq_handle);
-
- return error;
-}
-
-
-struct res_overlay {
- coroipc_response_header_t header __attribute__((aligned(8)));
- char data[512000];
-};
-
-
-int cman_dispatch (
- cman_handle_t handle,
- int dispatch_types)
-{
- int timeout = -1;
- cs_error_t error = CS_OK;
- int cont = 1; /* always continue do loop except when set to 0 */
- int dispatch_avail;
- struct cman_inst *cman_inst;
- struct res_overlay dispatch_data;
- struct res_lib_cman_sendmsg *res_lib_cman_sendmsg;
-
- if (dispatch_types != CS_DISPATCH_ONE &&
- dispatch_types != CS_DISPATCH_ALL &&
- dispatch_types != CS_DISPATCH_BLOCKING) {
-
- errno = EINVAL;
- return -1;
- }
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- /*
- * Timeout instantly for SA_DISPATCH_ONE or CS_DISPATCH_ALL and
- * wait indefinately for CS_DISPATCH_BLOCKING
- */
- if (dispatch_types == CS_DISPATCH_ALL) {
- timeout = 0;
- }
-
- do {
- dispatch_avail = coroipcc_dispatch_get (cman_inst->handle,
- (void *)&dispatch_data, timeout);
-
- if (error != CS_OK) {
- goto error_put;
- }
-
- if (dispatch_avail == 0 && dispatch_types == CMAN_DISPATCH_ALL) {
- break; /* exit do while cont is 1 loop */
- } else
- if (dispatch_avail == 0) {
- continue; /* next poll */
- }
- if (dispatch_avail == -1) {
- if (cman_inst->finalize == 1) {
- error = 0;
- } else {
- errno = EINVAL;
- error = -1;
- }
- goto error_put;
- }
-
- /*
- * Dispatch incoming message
- */
- switch (dispatch_data.header.id) {
-
- case MESSAGE_RES_CMAN_SENDMSG:
- if (cman_inst->data_callback == NULL) {
- continue;
- }
- res_lib_cman_sendmsg = (struct res_lib_cman_sendmsg *)&dispatch_data;
-
- cman_inst->data_callback ( handle,
- cman_inst->privdata,
- res_lib_cman_sendmsg->message,
- res_lib_cman_sendmsg->msglen,
- res_lib_cman_sendmsg->from_port,
- res_lib_cman_sendmsg->from_node);
- break;
-
- default:
- error = -1;
- errno = EINVAL;
- goto error_put;
- break;
- }
-
- /*
- * Determine if more messages should be processed
- * */
- switch (dispatch_types) {
- case CS_DISPATCH_ONE:
- cont = 0;
- break;
- case CS_DISPATCH_ALL:
- break;
- case CS_DISPATCH_BLOCKING:
- break;
- }
- } while (cont);
-
- goto error_put;
-
-error_put:
- return (error);
-}
-
-/*
- * This call expects to get a listing of all nodes known to the
- * system so we query ccs rather than corosync, as some nodes
- * might not be up yet
- */
-int cman_get_node_count(cman_handle_t handle)
-{
- struct cman_inst *cman_inst;
- int ccs_handle;
- int num_nodes = 0;
- char path[PATH_MAX];
- char *value;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- /* Returns the number of nodes known to ccs, not cman! */
- ccs_handle = ccs_connect();
-
- sprintf(path, "/cluster/clusternodes/clusternode[%d]/@name", num_nodes+1);
-
- while (!ccs_get(ccs_handle, path, &value))
- {
- num_nodes++;
- sprintf(path, "/cluster/clusternodes/clusternode[%d]/@name", num_nodes+1);
- };
-
- ccs_disconnect(ccs_handle);
- return num_nodes;
-}
-
-int cman_is_active(cman_handle_t handle)
-{
- struct cman_inst *cman_inst;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- /* If we have connected, then 'cman' is active */
- return 1;
-}
-
-/*
- * Here we just read values from ccs
- */
-int cman_get_cluster(cman_handle_t handle, cman_cluster_t *clinfo)
-{
- struct cman_inst *cman_inst;
- int ccs_handle;
- char *value;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- ccs_handle = ccs_connect();
- if (!ccs_get(ccs_handle, "/cluster/@name", &value)) {
- strcpy(clinfo->ci_name, value);
- free(value);
- }
- if (!ccs_get(ccs_handle, "/cluster/cman/@cluster_id", &value)) {
- clinfo->ci_number = atoi(value);
- free(value);
- }
- else {
- clinfo->ci_number = 0;
- }
- clinfo->ci_generation = 0; // CC: TODO ???
-
- ccs_disconnect(ccs_handle);
-
- return 0;
-}
-
-/*
- * libccs doesn't do writes yet so we need to use confdb to
- * change the config version.
- * This will signal votequorum to reload the configuration 'file'
- */
-int cman_set_version(cman_handle_t handle, const cman_version_t *version)
-{
- struct cman_inst *cman_inst;
- confdb_handle_t confdb_handle;
- unsigned int ccs_handle;
- char *value;
- char error[256];
- int ret = 0;
- int cur_version=0;
- confdb_callbacks_t callbacks = {
- .confdb_key_change_notify_fn = NULL,
- .confdb_object_create_change_notify_fn = NULL,
- .confdb_object_delete_change_notify_fn = NULL
- };
-
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- ccs_handle = ccs_connect();
- if (!ccs_get(ccs_handle, "/cluster/@config_version", &value)) {
- cur_version = atoi(value);
- free(value);
- }
- ccs_disconnect(ccs_handle);
-
- if (cur_version && cur_version >= version->cv_config) {
- errno = EINVAL;
- return -1;
- }
-
- if (confdb_initialize(&confdb_handle, &callbacks) != CS_OK) {
- errno = EINVAL;
- return -1;
- }
-
- if (confdb_reload(confdb_handle, 0, error, sizeof(error)) != CS_OK) {
- errno = EINVAL;
- ret = -1;
- }
-
- confdb_finalize(confdb_handle);
- return ret;
-}
-
-
-/* This mainly just retreives values from ccs */
-int cman_get_version(cman_handle_t handle, cman_version_t *version)
-{
- struct cman_inst *cman_inst;
- int ccs_handle;
- char *value;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- ccs_handle = ccs_connect();
- if (!ccs_get(ccs_handle, "/cluster/@config_version", &value)) {
- version->cv_config = atoi(value);
- free(value);
- }
-
- /* These are cman_tool versions now ;-) */
- version->cv_major = 7;
- version->cv_minor = 0;
- version->cv_patch = 1;
- ccs_disconnect(ccs_handle);
-
- return 0;
-}
-
-
-
-static char *node_name(corosync_cfg_node_address_t *addr)
-{
- static char name[256];
-
- if (getnameinfo((struct sockaddr *)addr->address, addr->address_length, name, sizeof(name), NULL, 0, NI_NAMEREQD))
- return NULL;
- else
- return name;
-}
-
-/*
- * This is a slightly complicated mix of ccs and votequorum queries.
- * votequorum only knows about active nodes and does not hold node names.
- * so once we have a list of active nodes we fill in the names
- * and also the nodes that have never been seen by corosync.
- */
-int cman_get_nodes(cman_handle_t handle, int maxnodes, int *retnodes, cman_node_t *nodes)
-{
- struct cman_inst *cman_inst;
- int ccs_handle;
- char *value;
- int ret;
- int i;
- int num_nodes = 0;
- char path[PATH_MAX];
- int noconfig_flag=0;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- refresh_node_list(cman_inst);
- ccs_handle = ccs_connect();
-
- if (!ccs_get(ccs_handle, "/cluster/@no_config", &value)) {
- noconfig_flag = atoi(value);
- free(value);
- }
-
- /* If we don't have a config file we will have to look up node names */
- if (noconfig_flag) {
- int max_addrs = 4;
- corosync_cfg_node_address_t addrs[max_addrs];
- int num_addrs;
- char *name = NULL;
- int error;
-
- if (!cman_inst->cfg_handle) {
- if (corosync_cfg_initialize(&cman_inst->cfg_handle, &cfg_callbacks) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- }
-
- for (i=0; i < cman_inst->node_count; i++) {
- nodes[i].cn_nodeid = cman_inst->node_list[i].nodeid;
- name = NULL;
-
- error = corosync_cfg_get_node_addrs(cman_inst->cfg_handle, nodes[i].cn_nodeid, max_addrs, &num_addrs, addrs);
- if (error == CS_OK) {
- name = node_name(&addrs[0]);
- }
- if (name) {
- sprintf(nodes[i].cn_name, "%s", name);
- }
- else {
- sprintf(nodes[i].cn_name, "Node-%x", nodes[i].cn_nodeid);
- }
-
- nodes[i].cn_member = (cman_inst->node_list[i].state == NODESTATE_MEMBER);
- }
- }
- else {
-
- /* We DO have a config file, reconcile in-memory with configuration */
- do {
- sprintf(path, "/cluster/clusternodes/clusternode[%d]/@name", num_nodes+1);
- ret = ccs_get(ccs_handle, path, &value);
- if (!ret) {
- strcpy(nodes[num_nodes].cn_name, value);
- free(value);
- }
-
- sprintf(path, "/cluster/clusternodes/clusternode[%d]/@nodeid", num_nodes+1);
- ret = ccs_get(ccs_handle, path, &value);
- if (!ret) {
- nodes[num_nodes].cn_nodeid = atoi(value);
- free(value);
- }
-
- /* Reconcile with active nodes list. */
- for (i=0; i < cman_inst->node_count; i++) {
- if (cman_inst->node_list[i].nodeid == nodes[num_nodes].cn_nodeid) {
- nodes[num_nodes].cn_member = (cman_inst->node_list[i].state == NODESTATE_MEMBER);
- }
- }
-
- num_nodes++;
- } while (ret == 0 && num_nodes < maxnodes);
- }
-
- *retnodes = num_nodes-1;
- if (cman_inst->node_count > *retnodes)
- *retnodes = cman_inst->node_count;
- ccs_disconnect(ccs_handle);
- return 0;
-}
-
-int cman_get_disallowed_nodes(cman_handle_t handle, int maxnodes, int *retnodes, cman_node_t *nodes)
-{
- struct cman_inst *cman_inst;
- int i;
- int num_nodes = 0;
- int ccs_handle;
- char *value;
- int ret;
- char path[PATH_MAX];
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- refresh_node_list(cman_inst);
- ccs_handle = ccs_connect();
-
- for (i=0; i < cman_inst->node_count; i++) {
- if (cman_inst->node_list[i].state == NODESTATE_DISALLOWED) {
- nodes[num_nodes].cn_nodeid = cman_inst->node_list[i].nodeid;
-
- /* Find the name: */
- sprintf(path, "/cluster/clusternodes/clusternode[@nodeid=\"%d\"]/@name", cman_inst->node_list[i].nodeid);
- ret = ccs_get(ccs_handle, path, &value);
- if (!ret) {
- strcpy(nodes[num_nodes].cn_name, value);
- free(value);
- }
- else {
- sprintf(nodes[i].cn_name, "Node-%x", nodes[i].cn_nodeid);
- }
- }
- }
- *retnodes = num_nodes;
- ccs_disconnect(ccs_handle);
- return 0;
-
-}
-
-int cman_get_node(cman_handle_t handle, int nodeid, cman_node_t *node)
-{
- struct cman_inst *cman_inst;
- struct votequorum_info qinfo;
- int i;
- int ccs_handle;
- int ret = 0;
- char *value;
- char path[PATH_MAX];
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- refresh_node_list(cman_inst);
- ccs_handle = ccs_connect();
-
- if (node->cn_name[0] == '\0') {
- /* Query by node ID */
- if (nodeid == CMAN_NODEID_US) {
- if (votequorum_getinfo(cman_inst->voteq_handle, 0, &qinfo) != CS_OK) {
- return -1;
- }
- nodeid = node->cn_nodeid = qinfo.node_id;
- }
-
- sprintf(path, "/cluster/clusternodes/clusternode[@nodeid=\"%d\"]/@name", nodeid);
- ret = ccs_get(ccs_handle, path, &value);
- if (!ret) {
- strcpy(node->cn_name, value);
- free(value);
- }
- }
- else {
- /* Query by node name */
- sprintf(path, "/cluster/clusternodes/clusternode[@name=\"%s\"]/@nodeid", node->cn_name);
- ret = ccs_get(ccs_handle, path, &value);
- if (!ret) {
- node->cn_nodeid = atoi(value);
- free(value);
- }
- }
-
- /* Fill in state */
- node->cn_member = 3; /* Not in cluster */
- for (i=0; i < cman_inst->node_count; i++) {
- if (cman_inst->node_list[i].nodeid == node->cn_nodeid) {
- if (cman_inst->node_list[i].state == NODESTATE_MEMBER)
- node->cn_member = 2;
- }
- }
-
- return 0;
-}
-
-int cman_start_notification(cman_handle_t handle, cman_callback_t callback)
-{
- struct cman_inst *cman_inst;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- if (votequorum_check_and_start(cman_inst))
- return -1;
-
- cman_inst->notify_callback = callback;
-
- if (votequorum_trackstart(cman_inst->voteq_handle, (uint64_t)(long)handle, CS_TRACK_CURRENT) != CS_OK)
- return -1;
-
- return 0;
-}
-
-int cman_stop_notification(cman_handle_t handle)
-{
- struct cman_inst *cman_inst;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- votequorum_trackstop(cman_inst->voteq_handle);
- cman_inst->notify_callback = NULL;
-
- return 0;
-}
-
-
-/* This is not complete ... but that's my problem, not yours */
-int cman_get_extra_info(cman_handle_t handle, cman_extra_info_t *info, int maxlen)
-{
- struct cman_inst *cman_inst;
- unsigned int ccs_handle;
- char *value;
- struct votequorum_info qinfo;
-
- cman_inst = (struct cman_inst *)handle;
- VALIDATE_HANDLE(cman_inst);
-
- refresh_node_list(cman_inst);
-
- if (votequorum_getinfo(cman_inst->voteq_handle, 0, &qinfo) != CS_OK) {
- return -1;
- }
-
- memset(info, 0, sizeof(cman_extra_info_t));
- info->ei_flags = qinfo.flags;
- info->ei_node_votes = qinfo.node_votes;
- info->ei_total_votes = qinfo.total_votes;
- info->ei_expected_votes = qinfo.node_expected_votes;
- info->ei_quorum = qinfo.quorum;
- info->ei_members = cman_inst->node_count;
- info->ei_node_state = 2;
- info->ei_num_addresses = 1;
-
- ccs_handle = ccs_connect();
- if (!ccs_get(ccs_handle, "/totem/interface/@broadcast", &value)) {
- strcpy(info->ei_addresses, "255.255.255.255");
- free(value);
- }
- else if (!ccs_get(ccs_handle, "/totem/interface/@mcastaddr", &value)) {
- strcpy(info->ei_addresses, value);
- free(value);
- }
-
- if (!ccs_get(ccs_handle, "/cluster/@no_config", &value)) {
- free(value);
- info->ei_flags |= CMAN_EXTRA_FLAG_NOCONFIG;
- }
-
-
- ccs_disconnect(ccs_handle);
-
- return 0;
-}
-
diff --git a/cman/services/cman/lib/libcman.h b/cman/services/cman/lib/libcman.h
deleted file mode 100644
index 3489025..0000000
--- a/cman/services/cman/lib/libcman.h
+++ /dev/null
@@ -1,418 +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;
-
-/*
- * 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
- NOTE: These have changed from Cluster2/3! */
-#define CMAN_EXTRA_FLAG_HASSTATE 1
-#define CMAN_EXTRA_FLAG_DISALLOWED 2
-#define CMAN_EXTRA_FLAG_2NODE 4
-#define CMAN_EXTRA_FLAG_QUORATE 8
-#define CMAN_EXTRA_FLAG_NOCONFIG 256
-
-typedef struct cman_extra_info {
- int ei_node_state;
- int ei_flags;
- int ei_node_votes;
- int ei_total_votes;
- int ei_expected_votes;
- int ei_quorum;
- int ei_members;
- char ei_ports[32];
- int ei_num_addresses;
- char ei_addresses[1]; /* Array of num_addresses*sockaddr_storage*2
- First batch is the multicast address list */
-} cman_extra_info_t;
-
-/* Quorum device info, returned from cman_get_quorum_device() */
-typedef struct cman_qdev_info {
- char qi_name[CMAN_MAX_NODENAME_LEN+1];
- int qi_state;
- int qi_votes;
-} cman_qdev_info_t;
-
-/*
- * NOTE: Apart from cman_replyto_shutdown(), you must not
- * call other cman_* functions while in these two callbacks:
- */
-
-/* Callback routine for a membership or other event */
-typedef void (*cman_callback_t)(cman_handle_t handle, void *privdata, int reason, int arg);
-
-/* Callback routine for data received */
-typedef void (*cman_datacallback_t)(cman_handle_t handle, void *privdata,
- char *buf, int len, uint8_t port, int nodeid);
-
-/* Callback for nodes joining/leaving */
-typedef void (*cman_confchgcallback_t)(cman_handle_t handle, void *privdata,
- unsigned int *member_list, int member_list_entries,
- unsigned int *left_list, int left_list_entries,
- unsigned int *joined_list, int joined_list_entries);
-
-/*
- * cman_init returns the handle you need to pass to the other API calls.
- * cman_admin_init opens admin socket for privileged operations.
- * cman_finish destroys that handle.
- *
- * Note that admin sockets can't send data messages or receive callbacks.
- */
-cman_handle_t cman_init(void *privdata);
-cman_handle_t cman_admin_init(void *privdata);
-int cman_finish(cman_handle_t handle);
-
-/* Update/retrieve the private data */
-int cman_setprivdata(cman_handle_t h, void *privdata);
-int cman_getprivdata(cman_handle_t h, void **privdata);
-
-/*
- * Notification of membership change events. Note that these are sent after
- * a transition, so multiple nodes may have left or joined the cluster.
- */
-int cman_start_notification(cman_handle_t handle, cman_callback_t callback);
-int cman_stop_notification(cman_handle_t handle);
-
-/*
- * Start/stop AIS-style confchg callbacks. These are less racy than the
- * old cman callbacks in that the caller will get one for each AIS
- * confchg message and it will contain all of the nodes that joined &
- * left in that transition.
- */
-int cman_start_confchg(cman_handle_t handle, cman_confchgcallback_t callback);
-int cman_stop_confchg(cman_handle_t handle);
-
-/* Call this if you get a TRY_SHUTDOWN event to signal whether you
- * will let cman shutdown or not.
- * Note that getting this callback does not mean that cman WILL shutdown,
- * only that it might. To detect a cman shutdown see cman_dispatch() below.
- */
-int cman_replyto_shutdown(cman_handle_t, int yesno);
-
-
-/*
- * Get the internal CMAN fd so you can pass it into poll() or select().
- * When it's active then call cman_dispatch() on the handle to process the event
- * NOTE: This fd can change between calls to cman_dispatch() so always call this
- * routine to get the latest one. (This is mainly due to message caching).
- * One upshot of this is that you must never read or write this FD (it may on
- * occasion point to /dev/zero if you have messages cached!)
- */
-int cman_get_fd(cman_handle_t handle);
-
-/*
- * cman_dispatch() will return -1 with errno == EHOSTDOWN if the cluster is
- * shut down, 0 if nothing was read, or a positive number if something was
- * dispatched.
- */
-
-int cman_dispatch(cman_handle_t handle, int flags);
-
-
-/*
- * -----------------------------------------------------------------------------
- * Get info calls.
- */
-
-/* Return the number of nodes we know about. This will normally
- * be the number of nodes in CCS
- */
-int cman_get_node_count(cman_handle_t handle);
-
-/* Returns the number of connected clients. This isn't as useful as a it used to
- * be as a count >1 does not automatically mean cman won't shut down. Subsystems
- * can decide for themselves whether a clean shutdown is possible.
- */
-int cman_get_subsys_count(cman_handle_t handle);
-
-/* Returns an array of node info structures. Call cman_get_node_count() first
- * to determine how big your array needs to be
- */
-int cman_get_nodes(cman_handle_t handle, int maxnodes, int *retnodes, cman_node_t *nodes);
-
-/* Returns a list of nodes that are known to AIS but blocked from joining the
- * CMAN cluster because they rejoined with cluster without a cman_tool join
- */
-int cman_get_disallowed_nodes(cman_handle_t handle, int maxnodes, int *retnodes, cman_node_t *nodes);
-
-/*
- * cman_get_node() can get node info by nodeid OR by name. If the first
- * char of node->cn_name is zero then the nodeid will be used, otherwise
- * the name will be used. I'll say this differently: If you want to look
- * up a node by nodeid, you MUST clear out the cman_node_t structure passed
- * into cman_get_node(). nodeid can be CMAN_NODEID_US.
- */
-int cman_get_node(cman_handle_t handle, int nodeid, cman_node_t *node);
-
-/* cman_get_node() only returns the first address of a node (whatever /that/
- * may mean). If you want to know all of them you need to call this.
- * max_addrs is the size of the 'addrs' array. num_addrs will be filled in by
- * the number of addresses the node has, regardless of the size of max_addrs.
- * So if you don't allocate enough space for the first call, you should know how
- * much is needed for a second!
- */
-int cman_get_node_addrs(cman_handle_t handle, int nodeid, int max_addrs, int *num_addrs, struct cman_node_address *addrs);
-
-/* Returns 1 if cman has completed initialisation and aisexec is running */
-int cman_is_active(cman_handle_t handle);
-
-/*
- * Returns 1 if a client is registered for data callbacks on a particular
- * port on a particular node. if cman returns -1 (errno==EBUSY) then it
- * doesn't currently know the status but has requested it, so try again
- * later or wait for a PORTOPENED notification.
- * nodeid can be CMAN_NODEID_US
- */
-int cman_is_listening(cman_handle_t handle, int nodeid, uint8_t port);
-
-/* Do we have quorum? */
-int cman_is_quorate(cman_handle_t handle);
-
-/* Return software & config (cluster.conf file) version */
-int cman_get_version(cman_handle_t handle, cman_version_t *version);
-
-/* Get cluster name and number */
-int cman_get_cluster(cman_handle_t handle, cman_cluster_t *clinfo);
-
-/* Get fence information for a node.
- * 'int *fenced' is only valid if the node is down, it is set to
- * 1 if the node has been fenced since it left the cluster.
- * agent should be CMAN_MAX_FENCE_AGENT_NAME_LEN
- */
-int cman_get_fenceinfo(cman_handle_t handle, int nodeid, uint64_t *fence_time, int *fenced, char *agent);
-
-/* Get stuff for cman_tool. Nobody else should use this */
-int cman_get_extra_info(cman_handle_t handle, cman_extra_info_t *info, int maxlen);
-
-/* Dump the objdb contents (only works if compiled with DEBUG enabled) */
-int cman_dump_objdb(cman_handle_t handle, char *filename);
-
-/*
- * -----------------------------------------------------------------------------
- * Admin functions. You will need privileges and have a handle created by
- * cman_admin_init() to use them.
- */
-
-/* Change the config file version. This should be needed much less now, as
- * cman will re-read the config file if a new node joins with a new config
- * version */
-int cman_set_version(cman_handle_t handle, const cman_version_t *version);
-
-/* Deprecated in favour of cman_shutdown(). Use cman_tool anyway please. */
-int cman_leave_cluster(cman_handle_t handle, int reason);
-
-/* Change the number of votes for this node. NOTE: a CCS update will
- overwrite this, so make sure you change both. Or, better, change CCS
- and call set_version() */
-int cman_set_votes(cman_handle_t handle, int votes, int nodeid);
-
-/* As above, for expected_votes */
-int cman_set_expected_votes(cman_handle_t handle, int expected_votes);
-
-/* Tell a particular node to leave the cluster NOW */
-int cman_kill_node(cman_handle_t handle, int nodeid);
-
-/* Tell CMAN a node has been fenced, when and by what means. */
-int cman_node_fenced(cman_handle_t handle, int nodeid, uint64_t fence_time, char *agent);
-
-/*
- * cman_shutdown() will send a REASON_TRY_SHUTDOWN event to all
- * clients registered for notifications. They should respond by calling
- * cman_replyto_shutdown() to indicate whether they will allow
- * cman to close down or not. If cman gets >=1 "no" (0) replies or the
- * request times out (default 5 seconds) then shutdown will be
- * cancelled and cman_shutdown() will return -1 with errno == EBUSY.
- *
- * Set flags to CMAN_SHUTDOWN_ANYWAY to force shutdown. Clients will still
- * be notified /and/ they will know you want a forced shutdown.
- *
- * Setting flags to CMAN_SHUTDOWN_REMOVED will tell the rest of the
- * cluster to adjust quorum to keep running with this node has left
- */
-int cman_shutdown(cman_handle_t, int flags);
-
-/* -----------------------------------------------------------------------------
- * Data transmission API. Uses the same FD as the rest of the calls.
- * If the nodeid passed to cman_send_data() is zero then it will be
- * broadcast to all nodes in the cluster.
- * cman_start_recv_data() is like a bind(), and marks the port
- * as "listening". See cman_is_listening() above.
- */
-int cman_send_data(cman_handle_t handle, const void *buf, int len, int flags, uint8_t port, int nodeid);
-int cman_start_recv_data(cman_handle_t handle, cman_datacallback_t, uint8_t port);
-int cman_end_recv_data(cman_handle_t handle);
-
-/*
- * Barrier API.
- * Here for backwards compatibility. Most of the things you would achieve
- * with this can now be better done using openAIS services or just messaging.
- */
-int cman_barrier_register(cman_handle_t handle, const char *name, int flags, int nodes);
-int cman_barrier_change(cman_handle_t handle, const char *name, int flags, int arg);
-int cman_barrier_wait(cman_handle_t handle, const char *name);
-int cman_barrier_delete(cman_handle_t handle, const char *name);
-
-/*
- * Add your own quorum device here, needs an admin socket
- *
- * After creating a quorum device you will need to call 'poll_quorum_device'
- * at least once every (default) 10 seconds (this can be changed in CCS)
- * otherwise it will time-out and the cluster will lose its vote.
- */
-int cman_register_quorum_device(cman_handle_t handle, char *name, int votes);
-int cman_unregister_quorum_device(cman_handle_t handle);
-int cman_poll_quorum_device(cman_handle_t handle, int isavailable);
-int cman_get_quorum_device(cman_handle_t handle, struct cman_qdev_info *info);
-
-/*
- * Sets the dirty bit inside cman. This indicates that the node has
- * some internal 'state' (eg in a daemon, filesystem or lock manager)
- * and cannot merge with another cluster that already has state.
- * This needs an admin socket. It cannot be reset.
- */
-int cman_set_dirty(cman_handle_t handle);
-
-/*
- * From STABLE3 branch this call tells corosync to execute:
- * logsys_config_debug_set(CMAN_NAME, value);
- * and debugging for all CMAN subsystems is on.
- */
-int cman_set_debuglog(cman_handle_t handle, int value);
-
-#endif
diff --git a/cman/services/cman/lib/libcman.pc.in b/cman/services/cman/lib/libcman.pc.in
deleted file mode 100644
index 7e9342c..0000000
--- a/cman/services/cman/lib/libcman.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@prefix@
-exec_prefix=${prefix}
-libdir=@libdir@
-includedir=${prefix}/include
-
-Name: libcman
-Version: @VERSION@
-Description: Cluster Manager library
-Requires:
-Libs: -L${libdir} -lcman
-Cflags: -I${includedir}
diff --git a/cman/services/cman/services/Makefile.am b/cman/services/cman/services/Makefile.am
deleted file mode 100644
index 6e4f611..0000000
--- a/cman/services/cman/services/Makefile.am
+++ /dev/null
@@ -1,14 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-AM_CPPFLAGS = -I$(top_srcdir)/cman/services/cman/include
-
-AM_CFLAGS = -fPIC \
- $(cfg_CFLAGS)
-
-LCRSO = service_cmanbits.lcrso
-
-SOURCES = cman.c
-
-EXTRA_DIST = $(SOURCES)
-
-include $(top_srcdir)/make/lcrso.mk
diff --git a/cman/services/cman/services/cman.c b/cman/services/cman/services/cman.c
deleted file mode 100644
index eb8ce25..0000000
--- a/cman/services/cman/services/cman.c
+++ /dev/null
@@ -1,571 +0,0 @@
-#include "clusterautoconfig.h"
-
-#ifndef COROSYNC_BSD
-#include <alloca.h>
-#endif
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <netinet/in.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <signal.h>
-#include <limits.h>
-#include <time.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <corosync/corotypes.h>
-#include <corosync/coroipc_types.h>
-#include <corosync/cfg.h>
-#include <corosync/list.h>
-#include <corosync/lcr/lcr_comp.h>
-#include <corosync/engine/logsys.h>
-#include <corosync/engine/coroapi.h>
-#include <corosync/ipc_cman.h>
-#include <corosync/cman.h>
-
-#define CMAN_MAJOR_VERSION 6
-#define CMAN_MINOR_VERSION 3
-#define CMAN_PATCH_VERSION 0
-
-#define MAX_INTERFACES 4
-
-LOGSYS_DECLARE_SUBSYS ("CMAN");
-
-/* Messages we send on port 0 */
-#define CLUSTER_MSG_PORTOPENED 2
-#define CLUSTER_MSG_PORTCLOSED 3
-#define CLUSTER_MSG_PORTENQ 9
-#define CLUSTER_MSG_PORTSTATUS 10
-
-/* This structure is tacked onto the start of a cluster message packet for our
- * own nefarious purposes. */
-struct cman_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 */
-};
-
-static hdb_handle_t group_handle;
-static struct corosync_tpg_group cman_group[1] = {
- { .group = "CMAN", .group_len = 4},
-};
-
-struct cman_pd {
- void *conn;
- unsigned char port; /* Bound port number */
- struct list_head list;
-};
-
-struct cluster_node {
- int nodeid;
-#define NODE_FLAG_PORTS_VALID 1
- int flags;
-#define PORT_BITS_SIZE 32
- unsigned char port_bits[PORT_BITS_SIZE]; /* bitmap of ports open on this node */
- struct list_head list;
-};
-
-/* An array of open 'ports' containing the connection to send
- responses to */
-static void *ports[256];
-static struct cluster_node our_node;
-static struct corosync_api_v1 *corosync_api;
-static struct list_head conn_list;
-static struct list_head node_list;
-
-#define list_iterate(v, head) \
- for (v = (head)->next; v != head; v = v->next)
-
-
-/*
- * Service Interfaces required by service_message_handler struct
- */
-
-static void cman_deliver_fn(unsigned int nodeid, const void *buf, unsigned int buf_len,
- int 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);
-
-static int cman_exec_init_fn (struct corosync_api_v1 *corosync_api);
-
-static int cman_lib_init_fn (void *conn);
-
-static int cman_lib_exit_fn (void *conn);
-
-static void message_handler_req_lib_cman_is_listening (void *conn, const void *msg);
-static void message_handler_req_lib_cman_sendmsg (void *conn, const void *msg);
-static void message_handler_req_lib_cman_unbind (void *conn, const void *msg);
-static void message_handler_req_lib_cman_bind (void *conn, const void *msg);
-
-/*
- * Library Handler Definition
- */
-static struct corosync_lib_handler cman_lib_service[] =
-{
- { /* 0 */
- .lib_handler_fn = message_handler_req_lib_cman_sendmsg,
- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED
- },
- { /* 1 */
- .lib_handler_fn = message_handler_req_lib_cman_is_listening,
- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
- },
- { /* 2 */
- .lib_handler_fn = message_handler_req_lib_cman_bind,
- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
- },
- { /* 3 */
- .lib_handler_fn = message_handler_req_lib_cman_unbind,
- .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
- }
-};
-
-static struct corosync_service_engine cman_service_handler = {
- .name = "corosync cluster cman service v3.01",
- .id = CMAN_SERVICE,
- .private_data_size = sizeof (struct cman_pd),
- .allow_inquorate = CS_LIB_ALLOW_INQUORATE,
- .flow_control = COROSYNC_LIB_FLOW_CONTROL_REQUIRED,
- .lib_init_fn = cman_lib_init_fn,
- .lib_exit_fn = cman_lib_exit_fn,
- .lib_engine = cman_lib_service,
- .lib_engine_count = sizeof (cman_lib_service) / sizeof (struct corosync_lib_handler),
- .exec_init_fn = cman_exec_init_fn,
- .exec_engine = NULL,
- .exec_engine_count = 0,
- .sync_mode = CS_SYNC_V1,
-};
-
-/*
- * Dynamic loader definition
- */
-static struct corosync_service_engine *cman_get_service_handler_ver0 (void);
-
-static struct corosync_service_engine_iface_ver0 cman_service_handler_iface = {
- .corosync_get_service_engine_ver0 = cman_get_service_handler_ver0
-};
-
-static struct lcr_iface corosync_cman_ver0[1] = {
- {
- .name = "corosync_cman",
- .version = 0,
- .versions_replace = 0,
- .versions_replace_count = 0,
- .dependencies = 0,
- .dependency_count = 0,
- .constructor = NULL,
- .destructor = NULL,
- .interfaces = NULL
- }
-};
-
-static struct lcr_comp cman_comp_ver0 = {
- .iface_count = 1,
- .ifaces = corosync_cman_ver0
-};
-
-
-static struct corosync_service_engine *cman_get_service_handler_ver0 (void)
-{
- return (&cman_service_handler);
-}
-
-__attribute__ ((constructor)) static void cman_comp_register (void) {
- lcr_interfaces_set (&corosync_cman_ver0[0], &cman_service_handler_iface);
-
- lcr_component_register (&cman_comp_ver0);
-}
-
-
-
-/* These just make the access a little neater */
-static inline int objdb_get_string(struct corosync_api_v1 *corosync, hdb_handle_t object_service_handle,
- char *key, char **value)
-{
- int res;
-
- *value = NULL;
- if ( !(res = corosync->object_key_get(object_service_handle,
- key,
- strlen(key),
- (void *)value,
- NULL))) {
- if (*value)
- return 0;
- }
- return -1;
-}
-
-static inline void objdb_get_int(struct corosync_api_v1 *corosync, hdb_handle_t object_service_handle,
- char *key, unsigned int *intvalue, unsigned int default_value)
-{
- char *value = NULL;
-
- *intvalue = default_value;
-
- if (!corosync->object_key_get(object_service_handle, key, strlen(key),
- (void *)&value, NULL)) {
- if (value) {
- *intvalue = atoi(value);
- }
- }
-}
-
-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 struct cluster_node *find_node(int nodeid, int allocate)
-{
- struct list_head *tmp;
- struct cluster_node *node;
-
- list_iterate(tmp, &node_list) {
- node = list_entry(tmp, struct cluster_node, list);
- if (node->nodeid == nodeid)
- return node;
- }
- if (allocate) {
- node = malloc(sizeof(struct cluster_node));
- if (node) {
- memset(node, 0, sizeof(*node));
- node->nodeid = nodeid;
- list_add(&node->list, &node_list);
- }
- }
- else {
- node = NULL;
- }
-
- return node;
-}
-
-
-static int cman_send_message(int fromport, int toport, int tonode, void *message, int len)
-{
- struct iovec iov[2];
- struct cman_protheader header;
-
- header.tgtport = toport;
- header.srcport = fromport;
- header.flags = 0;
- header.srcid = our_node.nodeid;
- header.tgtid = tonode;
-
- iov[0].iov_base = &header;
- iov[0].iov_len = sizeof(header);
- iov[1].iov_base = message;
- iov[1].iov_len = len;
-
- return corosync_api->tpg_joined_mcast(group_handle, iov, 2, TOTEM_AGREED);
-}
-
-static int cman_exec_init_fn (struct corosync_api_v1 *api)
-{
- hdb_handle_t find_handle;
-
- log_printf(LOGSYS_LEVEL_NOTICE, "cman_exec_init_fn \n");
-
- corosync_api = api;
-
- memset(ports, 0, sizeof(ports));
- memset(&our_node, 0, sizeof(our_node));
- list_init(&conn_list);
- list_init(&node_list);
-
- our_node.nodeid = corosync_api->totem_nodeid_get();
- list_add(&our_node.list, &node_list);
- set_port_bit(&our_node, 1);
- our_node.flags |= NODE_FLAG_PORTS_VALID;
-
- /* Get configuration variables */
- corosync_api->object_find_create(OBJECT_PARENT_HANDLE, "cman", strlen("cman"), &find_handle);
- // TODO ??
- corosync_api->object_find_destroy(find_handle);
-
- api->tpg_init(&group_handle, cman_deliver_fn, cman_confchg_fn);
- api->tpg_join(group_handle, cman_group, 1);
- return (0);
-}
-
-static int cman_lib_init_fn (void *conn)
-{
- struct cman_pd *cman_pd = (struct cman_pd *)corosync_api->ipc_private_data_get (conn);
-
- list_add(&cman_pd->list, &conn_list);
- return 0;
-}
-
-static int cman_lib_exit_fn (void *conn)
-{
- struct cman_pd *cman_pd = (struct cman_pd *)corosync_api->ipc_private_data_get (conn);
-
- if (cman_pd->port) {
- char portmsg[2];
-
- ports[cman_pd->port] = NULL;
-
- /* Tell the cluster */
- portmsg[0] = CLUSTER_MSG_PORTCLOSED;
- portmsg[1] = cman_pd->port;
- cman_send_message(0,0, 0, portmsg, 2);
- }
-
- list_del(&cman_pd->list);
- return (0);
-}
-
-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;
- struct cluster_node *node;
-
- /* Clear out removed nodes */
- for (i=0; i<left_list_entries; i++) {
- node = find_node(left_list[i], 0);
- if (node)
- node->flags &= ~NODE_FLAG_PORTS_VALID;
- }
-}
-
-
-static void cman_deliver_fn(unsigned int nodeid, const void *msg, unsigned int buf_len,
- int endian_conversion_required)
-{
- const struct cman_protheader *inheader = msg;
- struct cman_protheader header;
- const char *buf = msg;
-
- if (endian_conversion_required) {
- header.srcid = swab32(inheader->srcid);
- header.tgtid = swab32(inheader->tgtid);
- header.flags = swab32(inheader->flags);
- }
- else {
- memcpy(&header, buf, sizeof(header));
- }
-
- /* Messages to be sent to clients */
- if (header.tgtport != 0 &&
- (header.tgtid == our_node.nodeid ||
- header.tgtid == 0)) {
- buf += sizeof(struct cman_protheader);
-
- if (ports[header.tgtport]) {
- corosync_api->ipc_response_send(ports[header.tgtport], buf, buf_len - sizeof(struct cman_protheader));
- }
- }
-
- /* Our messages. Careful here, messages for the quorum module on port 0 also
- arrive here and must be ignored */
- if (header.tgtport == 0 &&
- (header.tgtid == our_node.nodeid ||
- header.tgtid == 0)) {
- struct cluster_node *node;
-
- buf += sizeof(struct cman_protheader);
- node = find_node(header.tgtid, 1);
-
- switch (*buf) {
- case CLUSTER_MSG_PORTOPENED:
- if (node) {
- if (!(node->flags & NODE_FLAG_PORTS_VALID)) {
- char reqmsg = CLUSTER_MSG_PORTENQ;
- cman_send_message(0,0, nodeid, &reqmsg, 1);
- }
- set_port_bit(node, buf[2]);
- }
- break;
- case CLUSTER_MSG_PORTCLOSED:
- if (node) {
- if (!(node->flags & NODE_FLAG_PORTS_VALID)) {
- char reqmsg = CLUSTER_MSG_PORTENQ;
- cman_send_message(0,0, nodeid, &reqmsg, 1);
- }
- clear_port_bit(node, buf[2]);
- }
- break;
- case CLUSTER_MSG_PORTENQ:
- if (node) {
- char portresult[PORT_BITS_SIZE+1];
-
- portresult[0] = CLUSTER_MSG_PORTSTATUS;
- memcpy(portresult+1, our_node.port_bits, PORT_BITS_SIZE);
- cman_send_message(0,0, 0, portresult, PORT_BITS_SIZE+1);
- }
- break;
- case CLUSTER_MSG_PORTSTATUS:
- if (node && node != &our_node) {
- memcpy(node->port_bits, buf+1, PORT_BITS_SIZE);
- node->flags |= NODE_FLAG_PORTS_VALID;
- }
- break;
- }
- }
-}
-
-static void message_handler_req_lib_cman_bind (void *conn, const void *msg)
-{
- coroipc_response_header_t res;
- struct req_lib_cman_bind *req_lib_cman_bind = (struct req_lib_cman_bind *)msg;
- struct cman_pd *cman_pd = (struct cman_pd *)corosync_api->ipc_private_data_get (conn);
- int error = 0;
- char portmsg[2];
-
- if (req_lib_cman_bind->port < 0 ||
- req_lib_cman_bind->port > 255)
- error = EINVAL;
-
- if (cman_pd->port || ports[req_lib_cman_bind->port]) {
- error = EADDRINUSE;
- }
- if (error == CS_OK) {
- cman_pd->port = req_lib_cman_bind->port;
- ports[cman_pd->port] = conn;
-
- /* Tell the cluster */
- portmsg[0] = CLUSTER_MSG_PORTOPENED;
- portmsg[1] = cman_pd->port;
- cman_send_message(0,0, 0, portmsg, 2);
- }
-
- res.size = sizeof(res);
- res.id = MESSAGE_RES_CMAN_BIND;
- res.error = error;
- corosync_api->ipc_response_send(conn, &res, sizeof(res));
-}
-
-static void message_handler_req_lib_cman_unbind (void *conn, const void *msg)
-{
- coroipc_response_header_t res;
- struct cman_pd *cman_pd = (struct cman_pd *)corosync_api->ipc_private_data_get (conn);
- int error = 0;
- char portmsg[2];
-
- if (cman_pd->port) {
- ports[cman_pd->port] = NULL;
- cman_pd->port = 0;
-
- /* Tell the cluster */
- portmsg[0] = CLUSTER_MSG_PORTCLOSED;
- portmsg[1] = cman_pd->port;
- cman_send_message(0,0, 0, portmsg, 2);
- }
-
- res.size = sizeof(res);
- res.id = MESSAGE_RES_CMAN_UNBIND;
- res.error = error;
- corosync_api->ipc_response_send(conn, &res, sizeof(res));
-}
-
-static void message_handler_req_lib_cman_sendmsg (void *conn, const void *msg)
-{
- struct req_lib_cman_sendmsg *req_lib_cman_sendmsg = (struct req_lib_cman_sendmsg *)msg;
- coroipc_response_header_t res;
- struct cman_pd *cman_pd = (struct cman_pd *)corosync_api->ipc_private_data_get (conn);
- int error = CS_OK;
-
-
- if (!cman_pd->port) {
- error = EINVAL;
- }
- else {
- error = cman_send_message(cman_pd->port,
- req_lib_cman_sendmsg->to_port,
- req_lib_cman_sendmsg->to_node,
- req_lib_cman_sendmsg->message,
- req_lib_cman_sendmsg->msglen);
- }
-
- res.size = sizeof(res);
- res.id = MESSAGE_RES_CMAN_SENDMSG;
- res.error = error;
- corosync_api->ipc_response_send(conn, &res, sizeof(res));
-}
-
-static void message_handler_req_lib_cman_is_listening (void *conn, const void *msg)
-{
- struct req_lib_cman_is_listening *req_lib_cman_is_listening = (struct req_lib_cman_is_listening *)msg;
- struct res_lib_cman_is_listening res_lib_cman_is_listening;
- int error = CS_OK;
- struct cluster_node *node;
-
-// How I think this should work:
-// There's a flag on the node that says whether we have complete port info or not.
-// If we do, then we can just return it.
-// If not then we do a port_enquire to get it (and return EBUSY).
-// If we get a PORTOPEN or PORTCLOSE and we don't have complete info then request it,
-// otherwise just update the record.
-// Remember - this needs to be backwards compatible
-
- node = find_node(req_lib_cman_is_listening->nodeid, 0);
- if (!node)
- error = ENOENT;
- if (node && !(node->flags & NODE_FLAG_PORTS_VALID))
- error = EBUSY;
-
- if (error == EBUSY) {
- char reqmsg = CLUSTER_MSG_PORTENQ;
- cman_send_message(0,0, req_lib_cman_is_listening->nodeid, &reqmsg, 1);
- }
- else {
- if (node) {
- res_lib_cman_is_listening.status = get_port_bit(node, req_lib_cman_is_listening->port);
- error = 0;
- }
- }
-
- res_lib_cman_is_listening.header.size = sizeof(res_lib_cman_is_listening);
- res_lib_cman_is_listening.header.id = MESSAGE_RES_CMAN_SENDMSG;
- res_lib_cman_is_listening.header.error = error;
- corosync_api->ipc_response_send(conn, &res_lib_cman_is_listening, sizeof(res_lib_cman_is_listening));
-}
diff --git a/cman/tests/Makefile.am b/cman/tests/Makefile.am
deleted file mode 100644
index 1f91f89..0000000
--- a/cman/tests/Makefile.am
+++ /dev/null
@@ -1,13 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-noinst_PROGRAMS = client sysman sysmand #libtestc qwait user_service
-
-EXTRA_DIST = user_service.c
-
-AM_CPPFLAGS = -I$(top_srcdir)/cman/services/cman/lib
-
-libcman_LDADD = $(top_builddir)/cman/services/cman/lib/libcman.la
-
-client_LDADD = $(libcman_LDADD)
-sysman_LDADD = $(libcman_LDADD)
-sysmand_LDADD = $(libcman_LDADD)
diff --git a/cman/tests/client.c b/cman/tests/client.c
deleted file mode 100644
index 3eabb6d..0000000
--- a/cman/tests/client.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/* test client */
-#include "clusterautoconfig.h"
-
-#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 callback_handle, void *private, int reason, int arg)
-{
- get_members();
-}
-
-
-static void data_callback(cman_handle_t callback_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 ce007b7..0000000
--- a/cman/tests/libtest.c
+++ /dev/null
@@ -1,134 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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 1200307..0000000
--- a/cman/tests/qwait.c
+++ /dev/null
@@ -1,60 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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 1f61844..0000000
--- a/cman/tests/sysman.c
+++ /dev/null
@@ -1,75 +0,0 @@
-#include "clusterautoconfig.h"
-
-/* "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>
-#include <limits.h>
-
-#define LOCAL_SOCKNAME CLUSTERVARRUN "/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 03591fa..0000000
--- a/cman/tests/sysmand.c
+++ /dev/null
@@ -1,472 +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 "clusterautoconfig.h"
-
-#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 <limits.h>
-
-#include "libcman.h"
-#define LOCAL_SOCKNAME CLUSTERVARRUN "/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 *rendfd;
- socklen_t sl = sizeof(socka);
- int client_fd = accept(local_sock, (struct sockaddr *)&socka, &sl);
-
- if (client_fd >= 0)
- {
- rendfd = malloc(sizeof(struct read_fd));
- if (!rendfd)
- {
- close(client_fd);
- break;
- }
- rendfd->fd = client_fd;
- rendfd->type = LOCAL_SOCK;
- rendfd->next = thisfd->next;
- rendfd->nodes_done = 0;
- rendfd->start_time = time(NULL);
- thisfd->next = rendfd;
- }
- }
- 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 *exec_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;
- exec_pipe = popen(realcmd, "r");
-
- /* Fill the buffer as full as possible */
- do
- {
- readlen = fread(reply + *len, 1, avail, exec_pipe);
- if (readlen > 0)
- {
- *len += readlen;
- avail -= readlen;
- }
- }
- while (avail>0 && readlen > 0);
-
- reply[*len] ='\0';
-
- /* Return completion status of command */
- return pclose(exec_pipe);
-}
diff --git a/cman/tests/user_service.c b/cman/tests/user_service.c
deleted file mode 100644
index 039aa72..0000000
--- a/cman/tests/user_service.c
+++ /dev/null
@@ -1,287 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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.am b/common/Makefile.am
deleted file mode 100644
index e73a7fb..0000000
--- a/common/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-SUBDIRS = liblogthread
diff --git a/common/liblogthread/Makefile.am b/common/liblogthread/Makefile.am
deleted file mode 100644
index aad208e..0000000
--- a/common/liblogthread/Makefile.am
+++ /dev/null
@@ -1,14 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-libversion = 3:0:0
-
-include_HEADERS = liblogthread.h
-
-pkgconfigdir = $(libdir)/pkgconfig
-
-pkgconfig_DATA = liblogthread.pc
-
-lib_LTLIBRARIES = liblogthread.la
-
-liblogthread_la_LDFLAGS = -lpthread \
- -version-info $(libversion)
diff --git a/common/liblogthread/liblogthread.c b/common/liblogthread/liblogthread.c
deleted file mode 100644
index 54c9d38..0000000
--- a/common/liblogthread/liblogthread.c
+++ /dev/null
@@ -1,336 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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 73f87f4..0000000
--- a/common/liblogthread/liblogthread.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@prefix@
-exec_prefix=${prefix}
-libdir=@libdir@
-includedir=${prefix}/include
-
-Name: liblogthread
-Version: @VERSION@
-Description: Cluster threaded logging library
-Requires:
-Libs: -L${libdir} -llogthread
-Cflags: -I${includedir}
diff --git a/config/Makefile.am b/config/Makefile.am
deleted file mode 100644
index 4a0b992..0000000
--- a/config/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-SUBDIRS = libs plugins tools man
diff --git a/config/libs/Makefile.am b/config/libs/Makefile.am
deleted file mode 100644
index f9dbec7..0000000
--- a/config/libs/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-SUBDIRS = libccsconfdb
diff --git a/config/libs/libccsconfdb/Makefile.am b/config/libs/libccsconfdb/Makefile.am
deleted file mode 100644
index 154c70c..0000000
--- a/config/libs/libccsconfdb/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-libversion = 3:0:0
-
-include_HEADERS = ccs.h
-
-noinst_HEADERS = ccs_internal.h
-
-pkgconfigdir = $(libdir)/pkgconfig
-
-pkgconfig_DATA = libccs.pc
-
-lib_LTLIBRARIES = libccs.la
-
-libccs_la_SOURCES = libccs.c xpathlite.c fullxpath.c extras.c
-
-libccs_la_CPPFLAGS = -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 \
- -I$(top_srcdir)/common/liblogthread/
-
-libccs_la_CFLAGS = $(confdb_CFLAGS) \
- $(xml_CFLAGS)
-
-libccs_la_LDFLAGS = $(xml_LIBS) $(confdb_LIBS) \
- -version-info $(libversion)
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 207faac..0000000
--- a/config/libs/libccsconfdb/extras.c
+++ /dev/null
@@ -1,449 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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 5b4c1af..0000000
--- a/config/libs/libccsconfdb/fullxpath.c
+++ /dev/null
@@ -1,327 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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[PATH_MAX];
- size_t key_value_len = 0, key_name_len = 0, object_name_len = 0;
- 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(dump_handle, parent_object_handle, key_name,
- &key_name_len, key_value,
- &key_value_len)) == CS_OK) {
- key_name[key_name_len] = '\0';
- key_value[key_value_len] = '\0';
-
- snprintf(temp, PATH_MAX - 1, " %s=\"%s\"", key_name, key_value);
- 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 e068358..0000000
--- a/config/libs/libccsconfdb/libccs.c
+++ /dev/null
@@ -1,651 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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
- (handle, connection_handle, "ccs_handle", strlen("ccs_handle"), buf,
- strlen(buf) + 1) != 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
- (handle, connection_handle, "config_version",
- strlen("config_version"), buf, strlen(buf) + 1) != 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
- (handle, connection_handle, "fullxpath", strlen("fullxpath"), buf,
- strlen(buf) + 1) != 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
- (handle, connection_handle, "previous_query",
- strlen("previous_query"), previous_query,
- strlen(previous_query) + 1) != 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
- (handle, connection_handle, "query_handle",
- strlen("query_handle"), &query_handle,
- sizeof(hdb_handle_t)) != 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
- (handle, connection_handle, "iterator_tracker",
- strlen("iterator_tracker"), &temptracker,
- sizeof(unsigned int)) != 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 a772ba6..0000000
--- a/config/libs/libccsconfdb/libccs.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@prefix@
-exec_prefix=${prefix}
-libdir=@libdir@
-includedir=${prefix}/include
-
-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 0086668..0000000
--- a/config/libs/libccsconfdb/xpathlite.c
+++ /dev/null
@@ -1,426 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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;
-
- 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 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 {
- if (confdb_key_get
- (handle, new_obj_handle,
- middle, strlen(middle),
- data,
- &datalen) == CS_OK) {
- if (!strcmp
- (data, value))
- goout = 1;
- }
- }
- }
- 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[PATH_MAX];
- char keyval[PATH_MAX];
- hdb_handle_t new_obj_handle;
- unsigned int value = 0;
- size_t datalen = 0, keyvallen = PATH_MAX;
-
- memset(data, 0, PATH_MAX);
- memset(resval, 0, PATH_MAX);
- memset(keyval, 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--;
- }
-
- snprintf(resval, sizeof(resval), "%s=%s", data, keyval);
- *rtn = strndup(resval, datalen + keyvallen + 2);
-
- } 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);
- if (confdb_key_iter
- (handle, query_handle, data, &datalen, keyval,
- &keyvallen) != CS_OK) {
- reset_iterator(handle, connection_handle);
- goto fail;
- }
-
- value--;
- }
-
- snprintf(resval, sizeof(resval), "%s=%s", data, keyval);
- *rtn = strndup(resval, datalen + keyvallen + 2);
-
- } 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;
-
- if (confdb_key_get
- (handle, query_handle, query, strlen(query), data,
- &datalen) != CS_OK)
- goto fail;
-
- *rtn = strndup(data, datalen);
- }
-
- 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.am b/config/man/Makefile.am
deleted file mode 100644
index 4c13505..0000000
--- a/config/man/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-dist_man_MANS = cluster.conf.5
diff --git a/config/man/cluster.conf.5 b/config/man/cluster.conf.5
deleted file mode 100644
index d9e50d4..0000000
--- a/config/man/cluster.conf.5
+++ /dev/null
@@ -1,208 +0,0 @@
-.TH cluster.conf 5
-
-.SH NAME
-cluster.conf - configuration file for cman, fence, dlm, gfs, rgmanager
-
-.SH DESCRIPTION
-
-The /etc/cluster/cluster.conf file contains configuration for:
-
-.B cman(5)
-for corosync and quorum configuration
-.br
-.B qdisk(5)
-for quorum disk configuration
-.br
-.B groupd(8)
-for daemon configuration
-.br
-.B fenced(8)
-for daemon and fence device configuration
-.br
-.B dlm_controld(8)
-for daemon configuration
-.br
-.B gfs_controld(8)
-for daemon configuration
-.br
-.B rgmanager(8)
-for daemon and resource configuration
-
-The same cluster.conf file must exist on each cluster node.
-
-When cman_tool starts corosync, the contents of cluster.conf are loaded into
-the corosync in-memory configuration database (confdb). Daemons and programs
-listed above use the libccs library to read cluster.conf data from the
-corosync confdb. (The libconfdb library can also be used for more general,
-non-xml confdb queries.)
-
-When cman configures corosync using cluster.conf, the corosync.conf file is
-not used.
-
-.SS Cluster Nodes
-
-cluster.conf is an XML file. It has one top-level \fIcluster\fP section
-containing everything else. The cluster section has two mandatory
-attributes: \fIname\fP and \fIconfig_version\fP. \fIname\fP can be up to
-15 characters long (16 including terminating null) and specifies the name
-of the cluster. It is important that this name be unique among clusters
-on the same network. \fIconfig_version\fP is a number used to identify
-the revision level of the cluster.conf file.
-
- <cluster name="alpha" config_version="1">
- </cluster>
-
-The set of nodes that make up the cluster are defined under the
-\fIclusternodes\fP section. A \fIclusternode\fP section defines each
-node. A clusternode has two mandatory attributes:
-.I name
-and
-.I nodeid
-
-The name should correspond to the hostname (the fully qualified name is
-generally not necessary) on the network interface to be used for cluster
-communication. Nodeid's must be greater than zero and unique.
-
- <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>
-
-.SS Logging
-.br
-All daemons listed above use the <logging> section to configure loggging.
-Global settings apply to all:
-
- <logging debug="on"/>
-
-Per-daemon settings override the corresponding global setting. logging_daemon
-names that can be configured include: corosync, qdiskd, groupd, fenced,
-dlm_controld, gfs_controld, rgmanager.
-
- <logging>
- <logging_daemon name="qdiskd" debug="on"/>
- <logging_daemon name="fenced" debug="on"/>
- </logging>
-
-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.
-
- <logging>
- <logging_daemon name="corosync" subsys="QUORUM" debug="on"/>
- <logging_daemon name="corosync" subsys="CONFDB" debug="on"/>
- </logging>
-
-.B Settings
-.br
-The settings available at global, daemon and subsystem levels are:
-
-.B to_syslog
-.br
-enable/disable messages to syslog (yes/no)
-.br
-default "yes"
-
-.B to_logfile
-.br
-enable/disable messages to log file (yes/no)
-.br
-default "yes"
-
-.B syslog_facility
-.br
-facility used for syslog messages
-.br
-default "daemon"
-
-.B syslog_priority
-.br
-messages at this level and up will be sent to syslog
-.br
-default "info"
-
-.B logfile_priority
-.br
-messages at this level and up will be written to log file
-.br
-default "info"
-
-.B logfile
-.br
-the log file name, default /var/log/cluster/<daemon>.log
-
-.B debug="on"
-.br
-is a shortcut for logfile_priority="debug"
-
-.B Defaults
-.br
-An explicit configuration for the default settings would be:
-
-<logging to_syslog="yes" to_logfile="yes" syslog_facility="daemon"
- syslog_priority="info" logfile_priority="info">
-.br
- <logging_daemon name="qdiskd"
- logfile="/var/log/cluster/qdisk.log"/>
-.br
- <logging_daemon name="groupd"
- logfile="/var/log/cluster/groupd.log"/>
-.br
- <logging_daemon name="fenced"
- logfile="/var/log/cluster/fenced.log"/>
-.br
- <logging_daemon name="dlm_controld"
- logfile="/var/log/cluster/dlm_controld.log"/>
-.br
- <logging_daemon name="gfs_controld"
- logfile="/var/log/cluster/gfs_controld.log"/>
-.br
- <logging_daemon name="rgmanager"
- logfile="/var/log/cluster/rgmanager.log"/>
-.br
- <logging_daemon name="corosync"
- logfile="/var/log/cluster/corosync.log"/>
-.br
-</logging>
-
-.B Examples
-.br
-To include debug messages (and above) from all daemons in their default log files, either
-.in +7
-<logging debug="on"/> or
-<logging logfile_priority="debug"/>
-.in -7
-
-To exclude all log messages from syslog
-.in +7
-<logging to_syslog="no"/>
-.in -7
-
-To disable logging to all log files
-.in +7
-<logging to_file="no"/>
-.in -7
-
-To include debug messages (and above) from all daemons in syslog
-.in +7
-<logging syslog_priority="debug"/>
-.in -7
-
-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)
-.in +7
-<logging syslog_priority="error" logfile_priority="info"/>
-.in -7
-
-
-.SH SEE ALSO
-cman(5), qdisk(5), groupd(8), fenced(8), dlm_controld(8), gfs_controld(8), rgmanager(8)
-
diff --git a/config/plugins/Makefile.am b/config/plugins/Makefile.am
deleted file mode 100644
index 64cea14..0000000
--- a/config/plugins/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-SUBDIRS = xml ldap
diff --git a/config/plugins/ldap/99cluster.ldif b/config/plugins/ldap/99cluster.ldif
deleted file mode 100644
index 7b53a12..0000000
--- a/config/plugins/ldap/99cluster.ldif
+++ /dev/null
@@ -1,138 +0,0 @@
-# Schema for Red Hat cluster suite LDAP configuration
-# 2008, Christine Caulfield ccaulfie(a)redhat.com
-#
-# This schema is incomplete, and probably always will be
-#
-#
-dn: cn=schema
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.1 NAME 'rhcsConfig-version'
- DESC 'An integer describing the configuration version'
- 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.2 NAME 'rhcsNodeid'
- DESC 'An integer describing the node ID number'
- 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'
- DESC 'An integer describing the cluster ID number'
- 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.4 NAME 'rhcsVotes'
- DESC 'An integer describing the number of votes a node has'
- 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.5 NAME 'rhcsTwo-node'
- DESC 'set to 1 for two_node mode'
- 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.6 NAME 'rhcsExpected-votes'
- DESC 'An integer describing the number of votes expected for the whole cluster'
- 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.7 NAME 'rhcsMax-queued'
- DESC 'An integer describing the maximum number of outstanding client requests to cman'
- 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.8 NAME 'rhcsToken'
- DESC 'An integer describing the totem token 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.9 NAME 'rhcsAgent'
- DESC 'The fencing agent to use'
- EQUALITY caseIgnoreIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.10 NAME 'rhcsUsername'
- DESC 'Username to log into the fencing agent'
- EQUALITY caseIgnoreIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE
- )
-attributeTypes: (
- 1.3.6.1.4.1.2312.8.1.1.11 NAME 'rhcsPassword'
- DESC 'Password to log into the fencing agent'
- EQUALITY caseIgnoreIA5Match
- SYNTAX 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'
- DESC 'IP Address the fencing agent'
- EQUALITY caseIgnoreIA5Match
- SYNTAX 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'
- DESC 'Port number for fence agent or cman'
- EQUALITY IntegerMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
- SINGLE-VALUE
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.1 NAME 'rhcsCluster' SUP top STRUCTURAL
- DESC 'Cluster top-level entry'
- MUST ( cn $ name $ rhcsConfig-version )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.2 NAME 'rhcsNode' SUP top STRUCTURAL
- DESC 'Cluster node entry'
- MUST ( name $ rhcsNodeid )
- MAY rhcsVotes
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.3 NAME 'rhcsCman' SUP top STRUCTURAL
- DESC 'Cluster node entry'
- MUST ( cn )
- MAY ( rhcsCluster-id $ rhcsTwo-node $ rhcsExpected-votes $ rhcsMax-queued $ rhcsPort )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.4 NAME 'rhcsTotem' SUP top STRUCTURAL
- DESC 'Totem options'
- MUST ( cn )
- MAY ( rhcsToken )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.5 NAME 'rhcsFencedevice' SUP top STRUCTURAL
- DESC 'A Fence device'
- MUST ( name $ rhcsAgent )
- MAY ( rhcsIpaddr $ rhcsUsername $ rhcsPassword )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.6 NAME 'rhcsFenceagent' SUP top STRUCTURAL
- DESC 'A Fence device'
- MUST ( name )
- MAY ( rhcsPort $ rhcsIpaddr )
- )
-objectClasses: (
- 1.3.6.1.4.1.2312.8.1.2.7 NAME 'rhcsFencemethod' SUP top STRUCTURAL
- DESC 'A Fence method placeholder'
- MUST ( name )
-)
diff --git a/config/plugins/ldap/Makefile.am b/config/plugins/ldap/Makefile.am
deleted file mode 100644
index 520b093..0000000
--- a/config/plugins/ldap/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-dist_doc_DATA = 99cluster.ldif example.ldif
-
-AM_CFLAGS = -fPIC $(corosync_CFLAGS)
-
-AM_LDFLAGS = -lldap
-
-LCRSO = config_ldap.lcrso
-
-SOURCES = configldap.c
-
-EXTRA_DIST = $(SOURCES)
-
-include $(top_srcdir)/make/lcrso.mk
diff --git a/config/plugins/ldap/configldap.c b/config/plugins/ldap/configldap.c
deleted file mode 100644
index 557b08f..0000000
--- a/config/plugins/ldap/configldap.c
+++ /dev/null
@@ -1,288 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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, int always_create)
-{
- char search_dn[4096];
- int rc;
- 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= */
- if (strncmp(parsed_dn[0][0][0].la_attr.bv_val, "name", 4)) {
- 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);
- }
- else {
- 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(object_handle, attr, strlen(attr),
- val_ber[i]->bv_val,
- val_ber[i]->bv_len+1);
- }
- 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_simple_bind 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", 1);
-
- 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/xml/Makefile.am b/config/plugins/xml/Makefile.am
deleted file mode 100644
index d0b4094..0000000
--- a/config/plugins/xml/Makefile.am
+++ /dev/null
@@ -1,14 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-AM_CFLAGS = -fPIC \
- $(xml_CFLAGS) $(corosync_CFLAGS)
-
-AM_LDFLAGS = $(xml_LIBS)
-
-LCRSO = config_xml.lcrso
-
-SOURCES = config.c
-
-EXTRA_DIST = $(SOURCES)
-
-include $(top_srcdir)/make/lcrso.mk
diff --git a/config/plugins/xml/config.c b/config/plugins/xml/config.c
deleted file mode 100644
index 5a53ba8..0000000
--- a/config/plugins/xml/config.c
+++ /dev/null
@@ -1,150 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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(object_handle,
- (char *)tmpattr->name,
- strlen((char *)tmpattr->name),
- (char *)tmpattr->children->
- content,
- strlen((char *)tmpattr->
- children->content) + 1);
- }
-}
-
-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);
-
- xmlCleanupParser();
-
- return err;
-}
diff --git a/config/tools/Makefile.am b/config/tools/Makefile.am
deleted file mode 100644
index 2cebdd3..0000000
--- a/config/tools/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-SUBDIRS = ccs_tool ldap mkconf man
diff --git a/config/tools/ccs_tool/Makefile.am b/config/tools/ccs_tool/Makefile.am
deleted file mode 100644
index 295950d..0000000
--- a/config/tools/ccs_tool/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-sbin_PROGRAMS = ccs_tool
-
-noinst_HEADERS = editconf.h
-
-ccs_tool_SOURCES = ccs_tool.c editconf.c
-
-ccs_tool_CPPFLAGS = -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 \
- -I$(top_srcdir)/config/libs/libccsconfdb
-
-ccs_tool_CFLAGS = $(xml_CFLAGS)
-
-ccs_tool_LDFLAGS = $(xml_LIBS)
-
-ccs_tool_LDADD = $(top_builddir)/config/libs/libccsconfdb/libccs.la
-
-install-exec-hook:
- (cd $(DESTDIR)/$(sbindir) && \
- rm -f ccs_test && \
- $(LN_S) ccs_tool ccs_test)
-
-uninstall-hook:
- (cd $(DESTDIR)/$(sbindir) && rm -f ccs_test)
diff --git a/config/tools/ccs_tool/ccs_tool.c b/config/tools/ccs_tool/ccs_tool.c
deleted file mode 100644
index a00f0dc..0000000
--- a/config/tools/ccs_tool/ccs_tool.c
+++ /dev/null
@@ -1,309 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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], PACKAGE_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], PACKAGE_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 5205257..0000000
--- a/config/tools/ccs_tool/editconf.c
+++ /dev/null
@@ -1,1252 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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;
- int tell_ccsd;
- int force_ccsd;
-};
-
-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");
- fprintf(stderr, " -C --no_ccs Don't tell CCSD about this change\n");
- fprintf(stderr, " default: run \"ccs_tool update\" if file is updated in place)\n");
- fprintf(stderr, " -F --force_ccs Force \"ccs_tool upgrade\" even if input & output files differ\n");
- }
-}
-
-static void help_usage(void)
-{
- fprintf(stderr, " -h --help Display this help text\n");
-}
-
-static void list_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [options]\n", prog_name, name);
- fprintf(stderr, " -v --verbose Print all properties of the item\n");
- config_usage(0);
- help_usage();
-
- exit(0);
-}
-
-static void create_usage(const char *name)
-{
- fprintf(stderr, "Usage: %s %s [-2] <clustername>\n", prog_name, name);
- fprintf(stderr, " -2 Create a 2-node cman cluster config file\n");
- config_usage(0);
- help_usage();
- fprintf(stderr, "\n"
- "Note that \"create\" on its own will not create a valid configuration file.\n"
- "Fence agents and nodes will need to be added to it before handing it over\n"
- "to ccsd.\n"
- "\n"
- "eg:\n"
- " ccs_tool create MyCluster\n"
- " ccs_tool addfence apc fence_apc ipaddr=apc.domain.net user=apc password=apc\n"
- " ccs_tool addnode node1 -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");
-
- 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 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 -n 1 -f manual ipaddr=newnode\n", prog_name, name);
- fprintf(stderr, "\n");
- fprintf(stderr, "Add a new node and dump config file to stdout rather than save it\n");
- fprintf(stderr, " %s %s -n 2 -f apc -o- newnode.temp.net port=1\n", prog_name, name);
-
- exit(0);
-}
-
-/* Is it really ?
- * Actually, we don't check that this is a valid multicast address(!),
- * merely that it is a valid IP[46] address.
- */
-static int valid_mcast_addr(char *mcast)
-{
- struct addrinfo *ainfo;
- struct addrinfo ahints;
- int ret;
-
- memset(&ahints, 0, sizeof(ahints));
-
- ret = getaddrinfo(mcast, NULL, &ahints, &ainfo);
- if (ret) {
- freeaddrinfo(ainfo);
- return 0;
- }
- return 1;
-}
-
-static void save_file(xmlDoc *doc, struct option_info *ninfo)
-{
- char 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 (!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 */
- 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'},
- { "no_ccs", no_argument, NULL, 'C'},
- { "force_ccs", no_argument, NULL, 'F'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option delnode_options[] =
-{
- { "outputfile", required_argument, NULL, 'o'},
- { "configfile", required_argument, NULL, 'c'},
- { "no_ccs", no_argument, NULL, 'C'},
- { "force_ccs", no_argument, NULL, 'F'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option addfence_options[] =
-{
- { "outputfile", required_argument, NULL, 'o'},
- { "configfile", required_argument, NULL, 'c'},
- { "no_ccs", no_argument, NULL, 'C'},
- { "force_ccs", no_argument, NULL, 'F'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option addnodeid_options[] =
-{
- { "outputfile", required_argument, NULL, 'o'},
- { "configfile", required_argument, NULL, 'c'},
- { "multicast", required_argument, NULL, 'm'},
- { "nodeid", no_argument, NULL, 'n'},
- { "verbose", no_argument, NULL, 'v'},
- { NULL, 0, NULL, 0 },
-};
-
-struct option list_options[] =
-{
- { "configfile", required_argument, NULL, 'c'},
- { "verbose", no_argument, NULL, 'v'},
- { NULL, 0, NULL, 0 },
-};
-
-
-static int next_nodeid(int startid, int *nodeids, int nodecount)
-{
- int i;
- int nextid = startid;
-
-retry:
- for (i=0; i<nodecount; i++)
- {
- if (nodeids[i] == nextid)
- {
- nextid++;
- goto retry;
- }
- }
-
- return nextid;
-}
-
-void add_nodeids(int argc, char **argv)
-{
- struct option_info ninfo;
- unsigned char *nodenames[MAX_NODES];
- xmlDoc *doc;
- xmlNode *root_element;
- xmlNode *clusternodes;
- xmlNode *cur_node;
- 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.tell_ccsd = 1;
- ninfo.votes = "1";
-
- while ( (opt = getopt_long(argc, argv, "v:n:a:f:o:c:CFh?", addnode_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'v':
- validate_int_arg(opt, optarg);
- ninfo.votes = optarg;
- break;
-
- case 'n':
- validate_int_arg(opt, optarg);
- ninfo.nodeid = optarg;
- break;
-
- case '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 'C':
- ninfo.tell_ccsd = 0;
- break;
-
- case 'F':
- ninfo.force_ccsd = 1;
- break;
-
- case '?':
- default:
- addnode_usage(argv[0]);
- }
- }
-
- /* Get node name parameter */
- if (optind < argc)
- ninfo.name = strdup(argv[optind]);
- else
- addnode_usage(argv[0]);
-
- if (!ninfo.fence_type)
- addnode_usage(argv[0]);
-
-
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
-
- increment_version(root_element);
-
- add_clusternode(root_element, &ninfo, argc, argv, optind);
-
- /* Write it out */
- save_file(doc, &ninfo);
- /* Shutdown libxml */
- xmlCleanupParser();
-
-}
-
-void del_node(int argc, char **argv)
-{
- struct option_info ninfo;
- int opt;
- xmlDoc *doc;
- xmlNode *root_element;
-
- memset(&ninfo, 0, sizeof(ninfo));
- ninfo.tell_ccsd = 1;
-
- while ( (opt = getopt_long(argc, argv, "o:c:CFh?", delnode_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
-
- case 'o':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case 'C':
- ninfo.tell_ccsd = 0;
- break;
-
- case 'F':
- ninfo.force_ccsd = 1;
- break;
-
- case '?':
- default:
- delnode_usage(argv[0]);
- }
- }
-
- /* Get node name parameter */
- if (optind < argc)
- ninfo.name = strdup(argv[optind]);
- else
- delnode_usage(argv[0]);
-
- doc = open_configfile(&ninfo);
-
- root_element = xmlDocGetRootElement(doc);
-
- increment_version(root_element);
-
- del_clusternode(root_element, &ninfo);
-
- /* Write it out */
- save_file(doc, &ninfo);
-}
-
-void list_nodes(int argc, char **argv)
-{
- xmlNode *cur_node;
- xmlNode *root_element;
- xmlNode *clusternodes;
- xmlNode *fencenode = NULL;
- xmlDocPtr doc;
- 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)
-{
- xmlNode *root_element;
- xmlNode *fencedevices;
- xmlNode *clusternodes;
- xmlNode *rm;
- xmlNode *rm1;
- xmlNode *rm2;
- xmlDocPtr doc;
- char *clustername;
- struct option_info ninfo;
- struct stat st;
- int twonode = 0;
- int opt;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "c:2h?", list_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case '2':
- twonode = 1;
- break;
-
- case '?':
- default:
- create_usage(argv[0]);
- }
- }
- if (!ninfo.outputfile)
- ninfo.outputfile = DEFAULT_CONFIG_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 */
- xmlInitParser();
- LIBXML_TEST_VERSION;
-
- doc = xmlNewDoc(BAD_CAST "1.0");
- root_element = xmlNewNode(NULL, BAD_CAST "cluster");
- xmlDocSetRootElement(doc, root_element);
-
- xmlSetProp(root_element, BAD_CAST "name", BAD_CAST clustername);
- xmlSetProp(root_element, BAD_CAST "config_version", BAD_CAST "1");
-
- /* Generate extra bits for a 2node cman cluster */
- if (twonode) {
-
- xmlNode *cman = xmlNewNode(NULL, BAD_CAST "cman");
- xmlSetProp(cman, BAD_CAST "two_node", BAD_CAST "1");
- xmlSetProp(cman, BAD_CAST "expected_votes", BAD_CAST "1");
- xmlAddChild(root_element, cman);
- }
-
- clusternodes = xmlNewNode(NULL, BAD_CAST "clusternodes");
- fencedevices = xmlNewNode(NULL, BAD_CAST "fencedevices");
- rm = xmlNewNode(NULL, BAD_CAST "rm");
- rm1 = xmlNewNode(NULL, BAD_CAST "failoverdomains");
-
- xmlAddChild(root_element, clusternodes);
- xmlAddChild(root_element, fencedevices);
- xmlAddChild(root_element, rm);
-
- /* Create empty resource manager sections to keep GUI happy */
- rm2 = xmlNewNode(NULL, BAD_CAST "resources");
- xmlAddChild(rm, rm1);
- xmlAddChild(rm, rm2);
-
- save_file(doc, &ninfo);
-
-}
-
-void add_fence(int argc, char **argv)
-{
- xmlNode *root_element;
- xmlNode *fencedevices;
- xmlNode *fencenode = NULL;
- xmlDocPtr doc;
- char *fencename;
- char *agentname;
- struct option_info ninfo;
- int opt;
-
- memset(&ninfo, 0, sizeof(ninfo));
- ninfo.tell_ccsd = 1;
-
- while ( (opt = getopt_long(argc, argv, "c:o:CFh?", list_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
- case 'o':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case 'C':
- ninfo.tell_ccsd = 0;
- break;
-
- case 'F':
- ninfo.force_ccsd = 1;
- break;
-
- case '?':
- default:
- addfence_usage(argv[0]);
- }
- }
-
- if (argc - optind < 2)
- addfence_usage(argv[0]);
-
- doc = open_configfile(&ninfo);
- root_element = xmlDocGetRootElement(doc);
-
- increment_version(root_element);
-
- fencedevices = findnode(root_element, "fencedevices");
- if (!fencedevices)
- die("Can't find \"fencedevices\" %s\n", ninfo.configfile);
-
- /* First param is the fence name - check it doesn't already exist */
- fencename = argv[optind++];
-
- if (valid_fence_type(root_element, fencename))
- die("fence type %s already exists\n", fencename);
-
- agentname = argv[optind++];
-
- /* Add it */
- fencenode = xmlNewNode(NULL, BAD_CAST "fencedevice");
- xmlSetProp(fencenode, BAD_CAST "name", BAD_CAST fencename);
- xmlSetProp(fencenode, BAD_CAST "agent", BAD_CAST agentname);
-
- /* Add name=value options */
- add_fence_args(fencenode, argc, argv, optind);
-
- xmlAddChild(fencedevices, fencenode);
-
- save_file(doc, &ninfo);
-}
-
-void del_fence(int argc, char **argv)
-{
- xmlNode *root_element;
- xmlNode *fencedevices;
- xmlNode *fencenode;
- xmlDocPtr doc;
- char *fencename;
- struct option_info ninfo;
- int opt;
-
- memset(&ninfo, 0, sizeof(ninfo));
- ninfo.tell_ccsd = 1;
-
- while ( (opt = getopt_long(argc, argv, "c:o:CFhv?", list_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
- case 'o':
- ninfo.outputfile = strdup(optarg);
- break;
-
- case 'C':
- ninfo.tell_ccsd = 0;
- break;
-
- case 'F':
- ninfo.force_ccsd = 1;
- break;
-
- case '?':
- default:
- delfence_usage(argv[0]);
- }
- }
-
- if (argc - optind < 1)
- delfence_usage(argv[0]);
-
- fencename = argv[optind];
-
- doc = open_configfile(&ninfo);
- root_element = xmlDocGetRootElement(doc);
- increment_version(root_element);
-
- fencedevices = findnode(root_element, "fencedevices");
- if (!fencedevices)
- die("Can't find \"fencedevices\" in %s\n", ninfo.configfile);
-
- fencenode = valid_fence_type(root_element, fencename);
- if (!fencenode)
- die("fence type %s does not exist\n", fencename);
-
- xmlUnlinkNode(fencenode);
-
- save_file(doc, &ninfo);
-}
-
-void list_fences(int argc, char **argv)
-{
- xmlNode *cur_node;
- xmlNode *root_element;
- xmlNode *fencedevices;
- xmlDocPtr doc;
- struct option_info ninfo;
- int opt;
- int verbose=0;
-
- memset(&ninfo, 0, sizeof(ninfo));
-
- while ( (opt = getopt_long(argc, argv, "c:hv?", list_options, NULL)) != EOF)
- {
- switch(opt)
- {
- case 'c':
- ninfo.configfile = strdup(optarg);
- break;
- case 'v':
- verbose++;
- break;
- case '?':
- default:
- list_usage(argv[0]);
- }
- }
- doc = open_configfile(&ninfo);
- root_element = xmlDocGetRootElement(doc);
-
- fencedevices = findnode(root_element, "fencedevices");
- if (!fencedevices)
- die("Can't find \"fencedevices\" in %s\n", ninfo.configfile);
-
-
- printf("Name Agent\n");
- for (cur_node = fencedevices->children; cur_node; cur_node = cur_node->next)
- {
- if (cur_node->type == XML_ELEMENT_NODE && strcmp((char *)cur_node->name, "fencedevice") == 0)
- {
- xmlChar *name = xmlGetProp(cur_node, BAD_CAST "name");
- xmlChar *agent = xmlGetProp(cur_node, BAD_CAST "agent");
-
- printf("%-16s %s\n", name, agent);
- if (verbose)
- print_properties(cur_node, " Properties: ", "agent", "");
- }
- }
-}
-
diff --git a/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.am b/config/tools/ldap/Makefile.am
deleted file mode 100644
index 1c5c4a8..0000000
--- a/config/tools/ldap/Makefile.am
+++ /dev/null
@@ -1,9 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-sbin_PROGRAMS = confdb2ldif
-
-confdb2ldif_CPPFLAGS = -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64
-
-confdb2ldif_CFLAGS = $(confdb_CFLAGS)
-
-confdb2ldif_LDFLAGS = $(confdb_LIBS)
diff --git a/config/tools/ldap/confdb2ldif.c b/config/tools/ldap/confdb2ldif.c
deleted file mode 100644
index 607d87d..0000000
--- a/config/tools/ldap/confdb2ldif.c
+++ /dev/null
@@ -1,203 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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/corotypes.h>
-#include <corosync/confdb.h>
-
-confdb_callbacks_t callbacks = {
-};
-
-/* This structure maps object parent names to object classes */
-struct objectclasses
-{
- const char *name;
- const char *class;
-} objectclasses[] =
-{
- { "cluster", "rhcsCluster" },
- { "cman", "rhcsCman" },
- { "totem", "rhcsTotem" },
- { "clusternode", "rhcsNode" },
- { "device", "rhcsFenceagent" },
- { "fencedevice", "rhcsFencedevice" },
- { "method", "rhcsFencemethod" },
- { "logging", "rhcsLoggersubsys" },
-};
-/* TODO: Add more here as the schema gets filled in */
-
-
-static char *ldap_attr_name(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];
- size_t key_name_len;
- char key_value[1024];
- size_t key_value_len;
- char cumulative_dn[4096];
- int res;
- int i;
- 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(handle, parent_object_handle, key_name, &key_name_len,
- key_value, &key_value_len)) == CS_OK) {
- key_name[key_name_len] = '\0';
- key_value[key_value_len] = '\0';
-
- printf("%s: %s\n", ldap_attr_name(key_name), key_value);
- keycount++;
- }
- if (strncmp(fulldn, "cn=", 3) == 0) {
- printf("cn: %s\n", dn);
- }
-
-
- /* Determine objectclass... */
- if (keycount == 0) {
- printf("objectclass: nsContainer\n");
- }
- else {
- for (i = 0; i < sizeof(objectclasses)/sizeof(struct objectclasses); i++) {
- if (strcmp(objectclasses[i].name, dn) == 0)
- printf("objectclass: %s\n", objectclasses[i].class);
- }
- }
-
- /* 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(handle, object_handle, "name", strlen("name"), key_value, &key_value_len);
- 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");
-
- sprintf(cumulative_dn, "name=%s,cn=%s,%s", key_value, object_name, fulldn);
- }
- 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/man/Makefile.am b/config/tools/man/Makefile.am
deleted file mode 100644
index 4eb4002..0000000
--- a/config/tools/man/Makefile.am
+++ /dev/null
@@ -1,4 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-dist_man_MANS = ccs_tool.8 \
- confdb2ldif.8
diff --git a/config/tools/man/ccs_tool.8 b/config/tools/man/ccs_tool.8
deleted file mode 100644
index ef13406..0000000
--- a/config/tools/man/ccs_tool.8
+++ /dev/null
@@ -1,185 +0,0 @@
-.TH "ccs_tool" "8" "" "" ""
-.SH "NAME"
-ccs_tool \- The tool used to make online updates of CCS config files.
-
-.SH "SYNOPSIS"
-.B ccs_tool
-[\fIOPTION\fR].. <\fBcommand\fP>
-
-.SH "DESCRIPTION"
-
-\fBccs_tool\fP is part of the Cluster Configuration System (CCS). It is
-used to make online updates to cluster.conf. It can also be used to
-upgrade old style (GFS <= 6.0) CCS archives to the new xml cluster.conf
-format.
-
-.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
-\fBupdate\fP \fI<xml file>\fP
-This command is used to update the config file that ccsd is working with
-while the cman cluster is operational (i.e. online). Run this on a single
-machine to update cluster.conf on all current cluster members. This also
-notifies cman of the new config version.
-
-.TP
-\fBupgrade\fP \fI<location>\fP
-This command is used to upgrade an old CCS format archive to the new
-xml format. \fI<location>\fP is the location of the old archive,
-which can be either a block device archive or a file archive. The
-converted configuration will be printed to stdout.
-
-.TP
-\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
-.br
-\-C Don't run "ccs_tool update" after changing file. This will
-happen by default if the input file is the same as the output file.
-.br
-\-F Force a "ccs_tool update" even if the input and output files
-are different.
-
-
-
-.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
-.br
-\-C Don't run "ccs_tool update" after changing file. This will
-happen by default if the input file is the same as the output file.
-.br
-\-F Force a "ccs_tool update" even if the input and output files
-are different.
-
-
-
-.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
-.br
-\-C Don't run "ccs_tool update" after changing file. This will
-happen by default if the input file is the same as the output file.
-.br
-\-F Force a "ccs_tool update" even if the input and output files
-are different.
-
-.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
-.br
-\-C Don't run "ccs_tool update" after changing file. This will
-happen by default if the input file is the same as the output file.
-.br
-\-F Force a "ccs_tool update" even if the input and output files
-are different.
-
-
-.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"
-ccs(7), ccsd(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/mkconf/Makefile.am b/config/tools/mkconf/Makefile.am
deleted file mode 100644
index a380bea..0000000
--- a/config/tools/mkconf/Makefile.am
+++ /dev/null
@@ -1,14 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-sbin_PROGRAMS = cman-mkconf
-
-cman_mkconf_SOURCES = mkconf.c
-
-cman_mkconf_CPPFLAGS = -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 \
- -I$(top_srcdir)/config/libs/libccsconfdb/
-
-cman_mkconf_CFLAGS = $(confdb_CFLAGS) $(quorum_CFLAGS) $(cfg_CFLAGS)
-
-cman_mkconf_LDFLAGS = $(confdb_LIBS) $(quorum_LIBS) $(cfg_LIBS)
-
-cman_mkconf_LDADD = $(top_builddir)/config/libs/libccsconfdb/libccs.la
diff --git a/config/tools/mkconf/mkconf.c b/config/tools/mkconf/mkconf.c
deleted file mode 100644
index 0845202..0000000
--- a/config/tools/mkconf/mkconf.c
+++ /dev/null
@@ -1,248 +0,0 @@
-#include "clusterautoconfig.h"
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-
-#include <corosync/corotypes.h>
-#include <corosync/quorum.h>
-#include <corosync/confdb.h>
-#include <corosync/cfg.h>
-#include <ccs.h>
-
-struct node_info {
- uint32_t nodeid;
- char name[256];
-};
-
-static uint32_t node_list_size;
-static struct node_info *node_list;
-
-
-static char *node_name(corosync_cfg_node_address_t *addr)
-{
- static char name[256];
-
- if (getnameinfo((struct sockaddr *)addr->address, addr->address_length, name, sizeof(name),
- NULL, 0, NI_NAMEREQD))
- return NULL;
- else
- return name;
-}
-
-static char *ip_address(corosync_cfg_node_address_t *addr)
-{
- static char name[256];
- struct sockaddr *sa = (struct sockaddr *)addr->address;
- char *addrpart;
-
- if (sa->sa_family == AF_INET) {
- struct sockaddr_in *sin = (struct sockaddr_in *)sa;
- addrpart = (char *)&sin->sin_addr;
- }
- else {
- struct sockaddr_in6 *sin = (struct sockaddr_in6 *)sa;
- addrpart = (char *)&sin->sin6_addr;
- }
-
- if (inet_ntop(sa->sa_family, addrpart, name, sizeof(name)))
- return name;
- else
- return NULL;
-}
-
-static void quorum_notification_callback(
- quorum_handle_t handle,
- uint32_t quorate,
- uint64_t ring_seq,
- uint32_t view_list_entries,
- uint32_t *view_list)
-{
- int i;
-
- node_list = malloc(sizeof(struct node_info) * view_list_entries);
- if (node_list) {
- for (i=0; i<view_list_entries; i++) {
- node_list[i].nodeid = view_list[i];
- }
- node_list_size = view_list_entries;
- }
-}
-
-
-static int refresh_node_list(int use_ip_addrs)
-{
- int error;
- int i;
- quorum_handle_t quorum_handle;
- corosync_cfg_handle_t cfg_handle;
- quorum_callbacks_t quorum_callbacks = {.quorum_notify_fn = quorum_notification_callback};
- int max_addrs = 4;
- corosync_cfg_node_address_t addrs[max_addrs];
- int num_addrs;
- char *name = NULL;
-
- if (quorum_initialize(&quorum_handle, &quorum_callbacks) != CS_OK) {
- errno = ENOMEM;
- return -1;
- }
- if (corosync_cfg_initialize(&cfg_handle, NULL) != CS_OK) {
- quorum_finalize(quorum_handle);
- errno = ENOMEM;
- return -1;
- }
-
- quorum_trackstart(quorum_handle, CS_TRACK_CURRENT);
-
- error = quorum_dispatch(quorum_handle, CS_DISPATCH_ONE);
- if (error != CS_OK)
- return -1;
-
- quorum_finalize(quorum_handle);
-
- for (i=0; i < node_list_size; i++) {
-
- error = corosync_cfg_get_node_addrs(cfg_handle, node_list[i].nodeid, max_addrs, &num_addrs, addrs);
- if (error == CS_OK) {
- if (use_ip_addrs)
- name = ip_address(&addrs[0]);
- else
- name = node_name(&addrs[0]);
- }
- if (name) {
- sprintf(node_list[i].name, "%s", name);
- }
- else {
- sprintf(node_list[i].name, "Node-%x", node_list[i].nodeid);
- }
-
- }
- corosync_cfg_finalize(cfg_handle);
- return 0;
-}
-
-static void usage(char *prog)
-{
- printf("Usage:\n\n");
- printf(" %s [options]\n", prog);
- printf("\n");
-
- printf(" -N Generate sequential nodeids\n");
- printf(" -n <name> Use this cluster name\n");
- printf(" -i Use IP Addresses rather than resolved node names\n");
- printf(" -f <name> Fence agent name (default: 'default')\n");
- printf(" -F <name> Fence agent parameter name (default: 'ipaddr'\n");
- printf(" -v <num> Config version number (default: 0)\n");
-
- printf("\n");
-
- printf("NOTE: It is stringly recommended that the existing cluster is shut down\n");
- printf(" completely before restarting any nodes using the generated file\n");
-
- printf("\n");
-}
-
-int main(int argc, char *argv[])
-{
- unsigned int ccs_handle;
- char *value;
- int optchar;
- int nodeid = 0;
- int i;
-
- int seq_nodeids=0;
- int use_ip_addrs=0;
- int config_version = 0;
- char *cluster_name = NULL;
- const char *fence_type = "default";
- const char *fence_param = "ipaddr";
- const char *fence_agent = "fence_manual";
-
- /* Parse options... */
- do {
- optchar = getopt(argc, argv, "?hNn:if:F:v:a:");
- switch (optchar) {
- case 'N':
- seq_nodeids=1;
- break;
- case 'n':
- cluster_name = strdup(optarg);
- break;
- case 'i':
- use_ip_addrs=1;
- break;
- case 'f':
- fence_type = strdup(optarg);
- break;
- case 'a':
- fence_agent = strdup(optarg);
- break;
- case 'F':
- fence_param = strdup(optarg);
- break;
- case 'v':
- config_version = atoi(optarg);
- break;
- case '?':
- case 'h':
- usage(argv[0]);
- exit(0);
- case EOF:
- break;
-
- }
- } while (optchar != EOF);
-
-
- /* Get the list of nodes and names */
- if (refresh_node_list(use_ip_addrs)){
- fprintf(stderr, "Unable to get node information from corosync\n");
- return 1;
- }
-
- ccs_handle = ccs_connect();
-
- if (!cluster_name) {
- if (!ccs_get(ccs_handle, "/cluster/@name", &value)) {
- cluster_name = strdup(value);
- free(value);
- }
- }
-
- /* Print config file header */
- printf("<?xml version=\"1.0\" ?>\n");
- printf("<cluster name=\"%s\" config_version=\"0\">\n", cluster_name);
- printf(" <clusternodes>\n\n");
- for (i=0; i<node_list_size; i++) {
- printf(" <clusternode name=\"%s\" nodeid=\"%u\">\n", node_list[i].name,
- seq_nodeids?++nodeid:node_list[i].nodeid);
- printf(" <fence>\n");
- printf(" <method name=\"single\">\n");
- printf(" <device name=\"%s\" %s=\"%s\"/>\n", fence_type, fence_param,node_list[i].name);
- printf(" </method>\n");
- printf(" </fence>\n");
- printf(" </clusternode>\n");
- printf("\n");
- }
- printf(" </clusternodes>\n");
-
- /* Make up something for fence devices */
- printf("<fencedevices>\n");
-
- printf(" <fencedevice name=\"%s\"> agent=\"%s\"/>\n", fence_type, fence_agent);
-
- printf("</fencedevices>\n");
-
-
- printf("</cluster>\n");
-
- ccs_disconnect(ccs_handle);
- return 0;
-}
diff --git a/configure.ac b/configure.ac
deleted file mode 100644
index c0996a3..0000000
--- a/configure.ac
+++ /dev/null
@@ -1,308 +0,0 @@
-
-# Process this file with autoconf to produce a configure script.
-
-AC_PREREQ([2.63])
-AC_INIT([cluster], [master], [linux-cluster(a)redhat.com]
-AM_INIT_AUTOMAKE([-Wno-portability])
-LT_PREREQ([2.2.6])
-LT_INIT
-
-AC_CONFIG_MACRO_DIR([m4])
-AC_CONFIG_SRCDIR([config/plugins/xml/config.c])
-AC_CONFIG_HEADERS([make/clusterautoconfig.h])
-
-AC_CANONICAL_HOST
-AC_PROG_LIBTOOL
-
-AC_LANG([C])
-
-# Sanitize path
-
-if test "$prefix" = "NONE"; then
- prefix="/usr"
- if test "$localstatedir" = "\${prefix}/var"; then
- localstatedir="/var"
- fi
- if test "$sysconfdir" = "\${prefix}/etc"; then
- sysconfdir="/etc"
- fi
- if test "$libdir" = "\${exec_prefix}/lib"; then
- if test -e /usr/lib64; then
- libdir="/usr/lib64"
- else
- libdir="/usr/lib"
- fi
- fi
-fi
-
-case $exec_prefix in
- NONE) exec_prefix=$prefix;;
- prefix) exec_prefix=$prefix;;
-esac
-
-# Checks for programs.
-
-# check stolen from gnulib/m4/gnu-make.m4
-if ! ${MAKE-make} --version /cannot/make/this >/dev/null 2>&1; then
- AC_MSG_ERROR([you don't seem to have GNU make; it is required])
-fi
-
-AC_PROG_CC
-AM_PROG_CC_C_O
-AC_PROG_LN_S
-AC_PROG_INSTALL
-AC_PROG_MAKE_SET
-
-## local helper functions
-
-# this function checks if CC support options passed as
-# args. Global CFLAGS are ignored during this test.
-cc_supports_flag() {
- local CFLAGS="$@"
- AC_MSG_CHECKING([whether $CC supports "$@"])
- AC_COMPILE_IFELSE([int main(){return 0;}] ,
- [RC=0; AC_MSG_RESULT([yes])],
- [RC=1; AC_MSG_RESULT([no])])
- return $RC
-}
-
-# this function tests if a library has a certain function
-# by using AC_CHECK_LIB but restores the original LIBS global
-# envvar. This is required to avoid libtool to link everything
-# with everything.
-check_lib_no_libs() {
- AC_CHECK_LIB([$1], [$2],,
- [AC_MSG_ERROR([Unable to find $1 library])])
- LIBS=$ac_check_lib_save_LIBS
-}
-
-# corosync libs
-PKG_CHECK_MODULES([corosync],[corosync])
-PKG_CHECK_MODULES([cfg],[libcfg])
-PKG_CHECK_MODULES([confdb],[libconfdb])
-PKG_CHECK_MODULES([coroipcc],[libcoroipcc])
-PKG_CHECK_MODULES([quorum],[libquorum])
-PKG_CHECK_MODULES([votequorum],[libvotequorum])
-
-# external libs
-PKG_CHECK_MODULES([xml],[libxml-2.0])
-
-# external libs (no pkgconfig)
-check_lib_no_libs pthread pthread_mutex_lock
-check_lib_no_libs ldap ldap_initialize
-check_lib_no_libs rt clock_gettime
-check_lib_no_libs z crc32
-
-# Checks for header files.
-AC_FUNC_ALLOCA
-AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h limits.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h])
-
-# Checks for typedefs, structures, and compiler characteristics.
-AC_C_INLINE
-AC_TYPE_MODE_T
-AC_TYPE_OFF_T
-AC_TYPE_PID_T
-AC_TYPE_SIZE_T
-AC_TYPE_SSIZE_T
-AC_CHECK_MEMBERS([struct stat.st_rdev])
-AC_TYPE_UID_T
-AC_TYPE_UINT16_T
-AC_TYPE_UINT32_T
-AC_TYPE_UINT64_T
-AC_TYPE_UINT8_T
-
-# Checks for library functions.
-AC_FUNC_FORK
-AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
-AC_HEADER_MAJOR
-AC_FUNC_MALLOC
-AC_CHECK_FUNCS([alarm atexit clock_gettime dup2 ftruncate gethostname gettimeofday memmove memset select socket strcasecmp strchr strdup strerror strncasecmp strndup strstr strtol uname])
-
-# local options
-AC_ARG_ENABLE([debug],
- [ --enable-debug enable debug build. ],
- [ default="no" ])
-
-AC_ARG_WITH([lcrso-dir],
- [ --with-lcrso-dir=DIR corosync lcrso files. ],
- [ LCRSODIR="$withval" ],
- [ LCRSODIR="$libexecdir/lcrso" ])
-
-AC_ARG_WITH([default-config-dir],
- [ --default-config-dir=DIR
- cluster config directory. ],
- [ DEFAULT_CONFIG_DIR="$withval" ],
- [ DEFAULT_CONFIG_DIR="$sysconfdir/cluster" ])
-
-AC_ARG_WITH([default-config-file],
- [ --default-config-file=FILE
- cluster config file. ],
- [ DEFAULT_CONFIG_FILE="$withval" ],
- [ DEFAULT_CONFIG_FILE="cluster.conf" ])
-
-AC_ARG_WITH([syslogfacility],
- [ --syslogfacility=FACILITY
- cluster default syslog facility. ],
- [ SYSLOGFACILITY="$withval" ],
- [ SYSLOGFACILITY="LOG_LOCAL4" ])
-
-AC_ARG_WITH([sysloglevel],
- [ --sysloglevel=LEVEL
- cluster default syslog level. ],
- [ SYSLOGLEVEL="$withval" ],
- [ SYSLOGLEVEL="LOG_INFO" ])
-
-AC_ARG_ENABLE([bindings],
- [ --enable-bindings enable bindings build. ],
- [ default="no" ])
-
-## random vars
-
-NOTIFYDDIR=${DEFAULT_CONFIG_DIR}/cman-notify.d
-LOGDIR=${localstatedir}/log/cluster
-LOGROTATEDIR=${sysconfdir}/logrotate.d
-CLUSTERVARRUN=${localstatedir}/run/cluster
-CLUSTERVARLIB=${localstatedir}/lib/cluster
-
-## do subst
-
-AC_SUBST([LCRSODIR])
-AC_DEFINE_UNQUOTED([LCRSODIR], "$(eval echo ${LCRSODIR})", [LCRSO directory])
-
-AC_SUBST([DEFAULT_CONFIG_DIR])
-AC_DEFINE_UNQUOTED([DEFAULT_CONFIG_DIR], "$(eval echo ${DEFAULT_CONFIG_DIR})",
- [Default config directory])
-
-AC_SUBST([DEFAULT_CONFIG_FILE])
-AC_DEFINE_UNQUOTED([DEFAULT_CONFIG_FILE], "$(eval echo ${DEFAULT_CONFIG_FILE})",
- [Default config file])
-
-AC_SUBST([LOGDIR])
-AC_DEFINE_UNQUOTED([LOGDIR], "$(eval echo ${LOGDIR})",
- [Default logging directory])
-
-AC_SUBST([NOTIFYDDIR])
-
-AC_SUBST([LOGROTATEDIR])
-
-AC_SUBST([CLUSTERVARRUN])
-AC_DEFINE_UNQUOTED([CLUSTERVARRUN], "$(eval echo ${CLUSTERVARRUN})",
- [Default cluster var/run directory])
-
-AC_SUBST([CLUSTERVARLIB])
-
-AC_DEFINE_UNQUOTED([SBINDIR], "$(eval echo ${sbindir})",
- [/sbin path])
-
-AC_DEFINE_UNQUOTED([COROSYNCBIN], "$(eval echo ${sbindir}/corosync)",
- [corosync executable file])
-
-AC_DEFINE_UNQUOTED([SYSLOGFACILITY], $(eval echo ${SYSLOGFACILITY}),
- [Default syslog facility])
-
-AC_DEFINE_UNQUOTED([SYSLOGLEVEL], $(eval echo ${SYSLOGLEVEL}),
- [Default syslog level])
-
-AM_CONDITIONAL(BUILD_BINDINGS, test "x${enable_bindings}" = xyes)
-
-## *FLAGS handling
-
-ENV_CFLAGS="$CFLAGS"
-ENV_CPPFLAGS="$CPPFLAGS"
-ENV_LDFLAGS="$LDFLAGS"
-
-# debug build stuff
-if test "x${enable_debug}" = xyes; then
- AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code])
- OPT_CFLAGS="-O0"
-else
- OPT_CFLAGS="-O2"
-fi
-
-# gdb flags
-if test "x${GCC}" = xyes; then
- GDB_FLAGS="-ggdb3"
-else
- GDB_FLAGS="-g"
-fi
-
-# extra warnings
-EXTRA_WARNINGS=""
-
-WARNLIST="
- all
- shadow
- missing-prototypes
- missing-declarations
- strict-prototypes
- declaration-after-statement
- pointer-arith
- write-strings
- cast-align
- bad-function-cast
- missing-format-attribute
- format=2
- format-security
- format-nonliteral
- no-long-long
- unsigned-char
- gnu89-inline
- no-strict-aliasing
- "
-
-for j in $WARNLIST; do
- if cc_supports_flag -W$j; then
- EXTRA_WARNINGS="$EXTRA_WARNINGS -W$j";
- fi
-done
-
-CFLAGS="$ENV_CFLAGS $OPT_CFLAGS $GDB_FLAGS \
- $EXTRA_WARNINGS $WERROR_CFLAGS"
-CPPFLAGS="-I\$(top_builddir)/make -I\$(top_srcdir)/make -I. $ENV_CPPFLAGS"
-LDFLAGS="$ENV_LDFLAGS"
-
-#
-# missing:
-# cman/init.d/Makefile
-# bindings/perl/ccs/Makefile
-
-AC_CONFIG_FILES([Makefile
- common/Makefile
- common/liblogthread/Makefile
- common/liblogthread/liblogthread.pc
- config/Makefile
- config/libs/Makefile
- config/libs/libccsconfdb/Makefile
- config/libs/libccsconfdb/libccs.pc
- config/plugins/Makefile
- config/plugins/ldap/Makefile
- config/plugins/xml/Makefile
- config/tools/Makefile
- config/tools/ccs_tool/Makefile
- config/tools/ldap/Makefile
- config/tools/mkconf/Makefile
- config/tools/man/Makefile
- config/man/Makefile
- cman/Makefile
- cman/services/Makefile
- cman/services/cman/Makefile
- cman/services/cman/include/Makefile
- cman/services/cman/services/Makefile
- cman/services/cman/lib/Makefile
- cman/services/cman/lib/libcman.pc
- cman/cman_tool/Makefile
- cman/config/Makefile
- cman/qdisk/Makefile
- cman/notifyd/Makefile
- cman/man/Makefile
- cman/tests/Makefile
- group/Makefile
- group/man/Makefile
- group/tool/Makefile
- doc/Makefile
- bindings/Makefile
- bindings/perl/Makefile
- bindings/perl/ccs/Makefile
- ])
-
-AC_OUTPUT
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 71fa6a9..0000000
--- a/doc/COPYRIGHT
+++ /dev/null
@@ -1,58 +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:
-
-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>
-
-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.am b/doc/Makefile.am
deleted file mode 100644
index a9332de..0000000
--- a/doc/Makefile.am
+++ /dev/null
@@ -1,34 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-dist_doc_DATA = gfs2.txt \
- journaling.txt \
- min-gfs.txt \
- usage.txt \
- COPYING.applications \
- COPYING.libraries \
- COPYRIGHT \
- README.licence
-
-EXTRA_DIST = cman_notify_template.sh \
- cluster.logrotate.in
-
-logrotate_TARGET = cluster
-
-$(logrotate_TARGET): $(logrotate_TARGET).logrotate.in
- cat $(srcdir)/$^ | sed \
- -e 's#_LOGDIR_#${LOGDIR}#g' \
- > $@
-
-all-local: $(logrotate_TARGET)
-
-clean-local:
- rm -f $(logrotate_TARGET)
-
-install-exec-local:
- $(INSTALL) -d $(DESTDIR)/$(LOGROTATEDIR)
- $(INSTALL) -m 644 cluster $(DESTDIR)/$(LOGROTATEDIR)
-
-uninstall-local:
- cd $(DESTDIR)/$(LOGROTATEDIR) && \
- rm -f $(logrotate_TARGET)
- rmdir $(DESTDIR)/$(LOGROTATEDIR) || :;
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 44451a6..0000000
--- a/doc/cluster.logrotate.in
+++ /dev/null
@@ -1,8 +0,0 @@
-_LOGDIR_/*log {
- missingok
- compress
- notifempty
- daily
- rotate 7
- create 0600 root root
-}
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/gfs2.txt b/doc/gfs2.txt
deleted file mode 100644
index 88f0143..0000000
--- a/doc/gfs2.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-Global File System
-------------------
-
-http://sources.redhat.com/cluster/
-
-GFS is a cluster file system. It allows a cluster of computers to
-simultaneously use a block device that is shared between them (with FC,
-iSCSI, NBD, etc). GFS reads and writes to the block device like a local
-file system, but also uses a lock module to allow the computers coordinate
-their I/O so file system consistency is maintained. One of the nifty
-features of GFS is perfect consistency -- changes made to the file system
-on one machine show up immediately on all other machines in the cluster.
-
-GFS uses interchangable inter-node locking mechanisms. Different lock
-modules can plug into GFS and each file system selects the appropriate
-lock module at mount time. Lock modules include:
-
- lock_nolock -- does no real locking and allows gfs to be used as a
- local file system
-
- lock_dlm -- uses a distributed lock manager (dlm) for inter-node locking
- The dlm is found at linux/fs/dlm/
-
-In addition to interfacing with an external locking manager, a gfs lock
-module is responsible for interacting with external cluster management
-systems. Lock_dlm depends on user space cluster management systems found
-at the URL above.
-
-To use gfs as a local file system, no external clustering systems are
-needed, simply:
-
- $ gfs2_mkfs -p lock_nolock -j 1 /dev/block_device
- $ mount -t gfs2 /dev/block_device /dir
-
-GFS2 is not on-disk compatible with previous versions of GFS.
-
-The following man pages can be found at the URL above:
- gfs2_mkfs to make a filesystem
- gfs2_fsck to repair a filesystem
- gfs2_grow to expand a filesystem online
- gfs2_jadd to add journals to a filesystem online
- gfs2_tool to manipulate, examine and tune a filesystem
- gfs2_quota to examine and change quota values in a filesystem
- mount.gfs2 to find mount options
-
diff --git a/doc/journaling.txt b/doc/journaling.txt
deleted file mode 100644
index e89eefa..0000000
--- a/doc/journaling.txt
+++ /dev/null
@@ -1,155 +0,0 @@
-o Journaling & Replay
-
-The fundamental problem with a journaled cluster filesystem is
-handling journal replay with multiple journals. A single block of
-metadata can be modified sequentially by many different nodes in the
-cluster. As the block is modified by each node, it gets logged in the
-journal for each node. If care is not taken, it's possible to get
-into a situation where a journal replay can actually corrupt a
-filesystem. The error scenario is:
-
-1) Node A modifies a metadata block by putting a updated copy into its
- incore log.
-2) Node B wants to read and modify the block so it requests the lock
- and a blocking callback is sent to Node A.
-3) Node A flushes its incore log to disk, and then syncs out the
- metadata block to its inplace location.
-4) Node A then releases the lock.
-5) Node B reads in the block and puts a modified copy into its ondisk
- log and then the inplace block location.
-6) Node A crashes.
-
-At this point, Node A's journal needs to be replayed. Since there is
-a newer version of block inplace, if that block is replayed, the
-filesystem will be corrupted. There are a few different ways of
-avoiding this problem.
-
-1) Generation Numbers (GFS1)
-
- Each metadata block has header in it that contains a 64-bit
- generation number. As each block is logged into a journal, the
- generation number is incremented. This provides a strict ordering
- of the different versions of the block a they are logged in the FS'
- different journals. When journal replay happens, each block in the
- journal is not replayed if generation number in the journal is less
- than the generation number in place. This ensures that a newer
- version of a block is never replaced with an older version. So,
- this solution basically allows multiple copies of the same block in
- different journals, but it allows you to always know which is the
- correct one.
-
- Pros:
-
- A) This method allows the fastest callbacks. To release a lock,
- the incore log for the lock must be flushed and then the inplace
- data and metadata must be synced. That's it. The sync
- operations involved are: start the log body and wait for it to
- become stable on the disk, synchronously write the commit block,
- start the inplace metadata and wait for it to become stable on
- the disk.
-
- Cons:
-
- A) Maintaining the generation numbers is expensive. All newly
- allocated metadata block must be read off the disk in order to
- figure out what the previous value of the generation number was.
- When deallocating metadata, extra work and care must be taken to
- make sure dirty data isn't thrown away in such a way that the
- generation numbers stop doing their thing.
- B) You can't continue to modify the filesystem during journal
- replay. Basically, replay of a block is a read-modify-write
- operation: the block is read from disk, the generation number is
- compared, and (maybe) the new version is written out. Replay
- requires that the R-M-W operation is atomic with respect to
- other R-M-W operations that might be happening (say by a normal
- I/O process). Since journal replay doesn't (and can't) play by
- the normal metadata locking rules, you can't count on them to
- protect replay. Hence GFS1, quieces all writes on a filesystem
- before starting replay. This provides the mutual exclusion
- required, but it's slow and unnecessarily interrupts service on
- the whole cluster.
-
-2) Total Metadata Sync (OCFS2)
-
- This method is really simple in that it uses exactly the same
- infrastructure that a local journaled filesystem uses. Every time
- a node receives a callback, it stops all metadata modification,
- syncs out the whole incore journal, syncs out any dirty data, marks
- the journal as being clean (unmounted), and then releases the lock.
- Because journal is marked as clean and recovery won't look at any
- of the journaled blocks in it, a valid copy of any particular block
- only exists in one journal at a time and that journal always the
- journal who modified it last.
-
- Pros:
-
- A) Very simple to implement.
- B) You can reuse journaling code from other places (such as JBD).
- C) No quiece necessary for replay.
- D) No need for generation numbers sprinkled throughout the metadata.
-
- Cons:
-
- A) This method has the slowest possible callbacks. The sync
- operations are: stop all metadata operations, start and wait for
- the log body, write the log commit block, start and wait for all
- the FS' dirty metadata, write an unmount block. Writing the
- metadata for the whole filesystem can be particularly expensive
- because it can be scattered all over the disk and there can be a
- whole journal's worth of it.
-
-3) Revocation of a lock's buffers (GFS2)
-
- This method prevents a block from appearing in more than one
- journal by canceling out the metadata blocks in the journal that
- belong to the lock being released. Journaling works very similarly
- to a local filesystem or to #2 above.
-
- The biggest difference is you have to keep track of buffers in the
- active region of the ondisk journal, even after the inplace blocks
- have been written back. This is done in GFS2 by adding a second
- part to the Active Items List. The first part (in GFS2 called
- AIL1) contains a list of all the blocks which have been logged to
- the journal, but not written back to their inplace location. Once
- an item in AIL1 has been written back to its inplace location, it
- is moved to AIL2. Once the tail of the log moves past the block's
- transaction in the log, it can be removed from AIL2.
-
- When a callback occurs, the log is flushed to the disk and the
- metadata for the lock is synced to disk. At this point, any
- metadata blocks for the lock that are in the current active region
- of the log will be in the AIL2 list. We then build a transaction
- that contains revoke tags for each buffer in the AIL2 list that
- belongs to that lock.
-
- Pros:
-
- A) No quiece necessary for Replay
- B) No need for generation numbers sprinkled throughout the
- metadata.
- C) The sync operations are: stop all metadata operations, start and
- wait for the log body, write the log commit block, start and
- wait for all the FS' dirty metadata, start and wait for the log
- body of a transaction that revokes any of the lock's metadata
- buffers in the journal's active region, and write the commit
- block for that transaction.
-
- Cons:
-
- A) Recovery takes two passes, one to find all the revoke tags in
- the log and one to replay the metadata blocks using the revoke
- tags as a filter. This is necessary for a local filesystem and
- the total sync method, too. It's just that there will probably
- be more tags.
-
-Comparing #2 and #3, both do extra I/O during a lock callback to make
-sure that any metadata blocks in the log for that lock will be
-removed. I believe #2 will be slower because syncing out all the
-dirty metadata for entire filesystem requires lots of little,
-scattered I/O across the whole disk. The extra I/O done by #3 is a
-log write to the disk. So, not only should it be less I/O, but it
-should also be better suited to get good performance out of the disk
-subsystem.
-
-KWP 07/06/05
-
diff --git a/doc/min-gfs.txt b/doc/min-gfs.txt
deleted file mode 100644
index af1399c..0000000
--- a/doc/min-gfs.txt
+++ /dev/null
@@ -1,159 +0,0 @@
-
-Minimum GFS HowTo
------------------
-
-The following gfs configuration requires a minimum amount of hardware and
-no expensive storage system. It's the cheapest and quickest way to "play"
-with gfs.
-
-
- ---------- ----------
- | GNBD | | GNBD |
- | client | | client | <-- these nodes use gfs
- | node2 | | node3 |
- ---------- ----------
- | |
- ------------------ IP network
- |
- ----------
- | GNBD |
- | server | <-- this node doesn't use gfs
- | node1 |
- ----------
-
-- There are three machines to use with hostnames: node1, node2, node3
-
-- node1 has an extra disk /dev/sda1 to use for gfs
- (this could be hda1 or an lvm LV or an md device)
-
-- node1 will use gnbd to export this disk to node2 and node3
-
-- Node1 cannot use gfs, it only acts as a gnbd server.
- (Node1 will /not/ actually be part of the cluster since it is only
- running the gnbd server.)
-
-- Only node2 and node3 will be in the cluster and use gfs.
- (A two-node cluster is a special case for cman, noted in the config below.)
-
-- There's not much point to using clvm in this setup so it's left out.
-
-- Download the "cluster" source tree.
-
-- Build and install from the cluster source tree. (The kernel components
- are not required on node1 which will only need the gnbd_serv program.)
-
- cd cluster
- ./configure --kernel_src=/path/to/kernel
- make; make install
-
-- Create /etc/cluster/cluster.conf on node2 with the following contents:
-
-<?xml version="1.0"?>
-<cluster name="gamma" config_version="1">
-
-<cman two_node="1" expected_votes="1">
-</cman>
-
-<clusternodes>
-<clusternode name="node2">
- <fence>
- <method name="single">
- <device name="gnbd" ipaddr="node2"/>
- </method>
- </fence>
-</clusternode>
-
-<clusternode name="node3">
- <fence>
- <method name="single">
- <device name="gnbd" ipaddr="node3"/>
- </method>
- </fence>
-</clusternode>
-</clusternodes>
-
-<fencedevices>
- <fencedevice name="gnbd" agent="fence_gnbd" servers="node1"/>
-</fencedevices>
-
-</cluster>
-
-
-- load kernel modules on nodes
-
-node2 and node3> modprobe gnbd
-node2 and node3> modprobe gfs
-node2 and node3> modprobe lock_dlm
-
-- run the following commands
-
-node1> gnbd_serv -n
-node1> gnbd_export -c -d /dev/sda1 -e global_disk
-
-node2 and node3> gnbd_import -n -i node1
-node2 and node3> ccsd
-node2 and node3> cman_tool join
-node2 and node3> fence_tool join
-
-node2> gfs_mkfs -p lock_dlm -t gamma:gfs1 -j 2 /dev/gnbd/global_disk
-
-node2 and node3> mount -t gfs /dev/gnbd/global_disk /mnt
-
-- the end, you now have a gfs file system mounted on node2 and node3
-
-
-Appendix A
-----------
-
-To use manual fencing instead of gnbd fencing, the cluster.conf file
-would look like this:
-
-<?xml version="1.0"?>
-<cluster name="gamma" config_version="1">
-
-<cman two_node="1" expected_votes="1">
-</cman>
-
-<clusternodes>
-<clusternode name="node2">
- <fence>
- <method name="single">
- <device name="manual" ipaddr="node2"/>
- </method>
- </fence>
-</clusternode>
-
-<clusternode name="node3">
- <fence>
- <method name="single">
- <device name="manual" ipaddr="node3"/>
- </method>
- </fence>
-</clusternode>
-</clusternodes>
-
-<fencedevices>
- <fencedevice name="manual" agent="fence_manual"/>
-</fencedevices>
-
-</cluster>
-
-
-FAQ
----
-
-- Why can't node3 use gfs, too?
-
-You might be able to make it work, but we recommend that you not try.
-This software was not intended or designed to allow that kind of usage.
-
-- Isn't node3 a single point of failure? how do I avoid that?
-
-Yes it is. For the time being, there's no way to avoid that, apart from
-not using gnbd, of course. Eventually, there will be a way to avoid this
-using cluster mirroring.
-
-- More info from
- http://sources.redhat.com/cluster/gnbd/gnbd_usage.txt
- http://sources.redhat.com/cluster/doc/usage.txt
-
diff --git a/doc/usage.txt b/doc/usage.txt
deleted file mode 100644
index f9e2866..0000000
--- a/doc/usage.txt
+++ /dev/null
@@ -1,177 +0,0 @@
-How to install and run GFS.
-
-Refer to the cluster project page for the latest information.
-http://sources.redhat.com/cluster/
-
-
-Install
--------
-
-Install a Linux kernel with GFS2, DLM, configfs, IPV6 and SCTP,
- 2.6.23-rc1 or later
-
- If you want to use gfs1 (from cluster/gfs-kernel), then you need to
- export three additional symbols from gfs2 by adding the following lines
- to the end of linux/fs/gfs2/locking.c:
- EXPORT_SYMBOL_GPL(gfs2_unmount_lockproto);
- EXPORT_SYMBOL_GPL(gfs2_mount_lockproto);
- EXPORT_SYMBOL_GPL(gfs2_withdraw_lockproto);
-
-Install openais
- get the latest "whitetank" (stable) release from
- http://openais.org/
- or
- svn checkout http://svn.osdl.org/openais
- cd openais/branches/whitetank
- make; make install DESTDIR=/
-
-Install gfs/dlm/fencing/etc components
- get the latest cluster-2.xx.yy tarball from
- ftp://sources.redhat.com/pub/cluster/
- or
- cvs -d :pserver:cvs@sources.redhat.com:/cvs/cluster login cvs
- cvs -d :pserver:cvs@sources.redhat.com:/cvs/cluster checkout cluster
- the password is "cvs"
- cd cluster
- ./configure --kernel_src=/path/to/kernel
- make install
-
- NOTE: On 64-bit systems, you will usually need to add '--libdir=/usr/lib64'
- to the configure line.
-
-Install LVM2/CLVM (optional)
- cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 login cvs
- cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 checkout LVM2
- cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2
- the password is "cvs"
- cd LVM2
- ./configure --with-clvmd=cman --with-cluster=shared
- make; make install
-
- NOTE: On 64-bit systems, you will usually need to add '--libdir=/usr/lib64'
- to the configure line.
-
-Load kernel modules
--------------------
-
-modprobe gfs2
-modprobe gfs
-modprobe lock_dlm
-modprobe lock_nolock
-modprobe dlm
-
-
-Configuration
--------------
-
-Create /etc/cluster/cluster.conf and copy it to all nodes.
-
- The format and content of cluster.conf has changed little since the
- last generation of the software. See old example here:
- http://sources.redhat.com/cluster/doc/usage.txt
- The one change you will need to make is to add nodeids for all nodes
- in the cluster. These are now mandatory. eg:
-
- <clusternode name="node12.mycluster.mycompany.com" votes="1" nodeid="12">
-
- If you already have a cluster.conf file with no nodeids in it, then you can
- use the 'ccs_tool addnodeids' command to add them.
-
-
-Example cluster.conf
---------------------
-
-This is a basic cluster.conf file that requires manual fencing. The node
-names should resolve to the address on the network interface you want to
-use for openais/cman/dlm communication.
-
-<?xml version="1.0"?>
-<cluster name="alpha" config_version="1">
-
-<clusternodes>
-<clusternode name="node01" nodeid="1">
- <fence>
- </fence>
-</clusternode>
-
-<clusternode name="node02" nodeid="2">
- <fence>
- </fence>
-</clusternode>
-
-<clusternode name="node03" nodeid="3">
- <fence>
- </fence>
-</clusternode>
-</clusternodes>
-
-<fencedevices>
-</fencedevices>
-
-</cluster>
-
-
-Startup procedure
------------------
-
-Run these commands on each cluster node:
-
-> mount -t configfs none /sys/kernel/config
-> ccsd
-> cman_tool join
-> groupd
-> fenced
-> fence_tool join
-> dlm_controld
-> gfs_controld
-> clvmd (optional)
-> mkfs -t gfs2 -p lock_dlm -t <clustername>:<fsname> -j <#journals> <blockdev>
-> mount -t gfs2 [-v] <blockdev> <mountpoint>
-
-Notes:
-- replace "gfs2" with "gfs" above to use gfs1 instead of gfs2
-- <clustername> in mkfs should match the one in cluster.conf.
-- <fsname> in mkfs is any name you pick, each fs must have a different name.
-- <#journals> in mkfs should be greater than or equal to the number of nodes
- that you want to mount this fs, each node uses a separate journal.
-- To avoid unnecessary fencing when starting the cluster, it's best for
- all nodes to join the cluster (complete cman_tool join) before any
- of them do fence_tool join.
-- The cman_tool "status" and "nodes" options show the status and members
- of the cluster.
-- The group_tool command shows the status of fencing, dlm and gfs groups
- that the local node is part of.
-- The "cman" init script can be used for starting everything up through
- gfs_controld in the list above.
-
-
-Shutdown procedure
-------------------
-
-Run these commands on each cluster node:
-
-> umount [-v] <mountpoint>
-> fence_tool leave
-> cman_tool leave
-
-
-Converting from GFS1 to GFS2
-----------------------------
-
-If you have GFS1 filesystems that you need to convert to GFS2, follow
-this procedure:
-
-1. Back up your entire filesystem first.
- e.g. cp /dev/your_vg/lvol0 /your_gfs_backup
-
-2. Run fsck to ensure filesystem integrity.
- e.g. gfs2_fsck /dev/your_vg/lvol0
-
-3. Make sure the filesystem is not mounted from any node.
- e.g. for i in `grep "<clusternode name" /etc/cluster/cluster.conf | cut -d '"' -f2` ; do ssh $i "mount | grep gfs" ; done
-
-4. Make sure you have the latest software versions.
-
-5. Run gfs2_convert <blockdev> from one of the nodes.
- e.g. gfs2_convert /dev/your_vg/lvol0
-
diff --git a/group/Makefile.am b/group/Makefile.am
deleted file mode 100644
index 9345392..0000000
--- a/group/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-SUBDIRS = tool man
diff --git a/group/man/Makefile.am b/group/man/Makefile.am
deleted file mode 100644
index fcc1510..0000000
--- a/group/man/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-dist_man_MANS = group_tool.8
diff --git a/group/man/group_tool.8 b/group/man/group_tool.8
deleted file mode 100644
index 6cf5e7f..0000000
--- a/group/man/group_tool.8
+++ /dev/null
@@ -1,61 +0,0 @@
-.TH group_tool 8
-
-.SH NAME
-group_tool - display/dump information about fence, dlm and gfs groups
-
-.SH SYNOPSIS
-.B
-group_tool
-[\fISUBCOMMAND\fR] [\fIOPTION\fR]...
-
-.SH DESCRIPTION
-
-The group_tool program displays the status of fence, dlm and gfs groups.
-The information is read from the groupd daemon which controls the fenced,
-dlm_controld and gfs_controld daemons. group_tool will also dump debug
-logs from various daemons.
-
-.SH SUBCOMMANDS
-
-.TP
-\fBls\fP
-displays the list of groups and their membership. It is the default
-subcommand if none is specified.
-
-.TP
-\fBdump\fP
-dumps the debug log from groupd.
-
-.TP
-\fBdump fence\fP
-dumps the debug log from fenced.
-
-.TP
-\fBdump gfs\fP
-dumps the debug log from gfs_controld.
-
-.TP
-\fBdump plocks\fP <fsname>
-prints the posix locks on the named gfs fs from gfs_controld.
-
-.SH OPTIONS
-.TP
-\fB-v\fP
-Verbose output, used with the 'ls' subcommand.
-.TP
-\fB-D\fP
-Run the daemon in the foreground and print debug statements to stdout.
-.TP
-\fB-V\fP
-Print the version information and exit.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-
-.SH DEBUGGING
-The groupd daemon keeps a circular buffer of debug messages that can be
-dumped with the 'group_tool dump' command.
-
-.SH SEE ALSO
-groupd(8)
-
diff --git a/group/tool/Makefile.am b/group/tool/Makefile.am
deleted file mode 100644
index 5c36907..0000000
--- a/group/tool/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-MAINTAINERCLEANFILES = Makefile.in
-
-sbin_PROGRAMS = group_tool
-
-group_tool_SOURCES = main.c
diff --git a/group/tool/main.c b/group/tool/main.c
deleted file mode 100644
index aed540f..0000000
--- a/group/tool/main.c
+++ /dev/null
@@ -1,147 +0,0 @@
-#include "clusterautoconfig.h"
-
-#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 "copyright.cf"
-
-#define OP_LIST 1
-#define OP_DUMP 2
-
-static char *prog_name;
-static int operation;
-static int opt_ind;
-static int verbose;
-static int ls_all_nodes;
-
-static void print_usage(void)
-{
- printf("Usage:\n");
- printf("\n");
- printf("%s [options] [ls|dump]\n", prog_name);
- printf("\n");
- printf("Options:\n");
- printf(" -v Verbose output, extra information\n");
- printf(" -n Show all node information\n");
- printf(" -h Print this help, then exit\n");
- printf(" -V Print program version information, then exit\n");
- printf("\n");
- printf("Display debugging information\n");
- printf("dump fence Show debug log from fenced\n");
- printf("dump dlm Show debug log from dlm_controld\n");
- printf("dump gfs Show debug log from gfs_controld\n");
- printf("\n");
-}
-
-#define OPTION_STRING "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 '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, PACKAGE_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;
- }
- optind++;
- }
-
- if (!operation)
- operation = OP_LIST;
-}
-
-int main(int argc, char **argv)
-{
- prog_name = argv[0];
- decode_arguments(argc, argv);
-
- switch (operation) {
- case OP_LIST:
- 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");
- }
- break;
-
- 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");
- }
- break;
- }
-
- return 0;
-}
-
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/lcrso.mk b/make/lcrso.mk
deleted file mode 100644
index a2ab978..0000000
--- a/make/lcrso.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-LCRSO_OBJS = $(SOURCES:%.c=%.o)
-
-$(LCRSO): $(LCRSO_OBJS)
- $(CC) $(AM_LDFLAGS) $(LDFLAGS) -shared -Wl,-soname=$@ $^ -o $@
-
-%.o: %.c
- $(CC) $(AM_CPPFLAGS) $(AM_CFLAGS) \
- $(CFLAGS) $(CPPFLAGS) \
- $(INCLUDES) \
- -c -o $@ $<
-
-all-local: $(LCRSO_OBJS) $(LCRSO)
-
-install-exec-local:
- $(INSTALL) -d $(DESTDIR)/$(LCRSODIR)
- $(INSTALL) -m 755 $(LCRSO) $(DESTDIR)/$(LCRSODIR)
-
-uninstall-local:
- cd $(DESTDIR)/$(LCRSODIR) && \
- rm -f $(LCRSO)
-
-clean-local:
- rm -f *.o *.a *.lcrso