Gitweb: http://git.fedorahosted.org/git/fence-agents.git?p=fence-agents.git;a=commi…
Commit: d168962374ab52999d1be46fa218fb66066833da
Parent: d2c04e14faa0da39a8d3fe2b54fa628617b6a8c5
Author: Digimer <digital.mermaid(a)gmail.com>
AuthorDate: Sat Nov 27 22:47:58 2010 -0500
Committer: Digimer <digital.mermaid(a)gmail.com>
CommitterDate: Sat Nov 27 22:47:58 2010 -0500
fence_na: Updated node_assassin to v1.1.6. Fixed a few bugs and cleaned up the configuration file and docs to be more neutral and professional.
---
fence/agents/node_assassin/fence_na.conf.in | 33 ++++++++++++++------------
fence/agents/node_assassin/fence_na.lib.in | 10 +++++---
fence/agents/node_assassin/fence_na.pl | 7 ++++-
fence/agents/node_assassin/fence_na.pod.in | 14 +++++-----
4 files changed, 36 insertions(+), 28 deletions(-)
diff --git a/fence/agents/node_assassin/fence_na.conf.in b/fence/agents/node_assassin/fence_na.conf.in
index 3ae6866..53a8956 100644
--- a/fence/agents/node_assassin/fence_na.conf.in
+++ b/fence/agents/node_assassin/fence_na.conf.in
@@ -4,9 +4,11 @@
#
# Node Assassin - Fence Agent
# Digimer; digimer(a)alteeve.com
-# Jun. 27, 2010
-# Version: 1.1.5
-
+# Nov. 27, 2010
+# Version: 1.1.6
+#
+# This software is released under the GPL v2. See the LICENSE file for a copy
+# of the GPL v2.
###############################################################################
# System: #
@@ -19,9 +21,9 @@
system::na_num = 1
# Version of the fence_na fence agent.
-system::agent_version = 1.1.5.1
+system::agent_version = 1.1.6
-# This is the log file. If unset, no logging will occur. If using '@LOGDIR@',
+# This is the log file. If unset, no logging will occur. If using '/var/log/',
# be sure that this agent is able to create or edit the file. The default is to
# write to '/tmp' to prevent accidental failure of the agent due to
# misconfiguration.
@@ -38,7 +40,7 @@ system::debug = 0
# This is the authentication information... It is currently a simple plain text
# compare, but this will change prior to first release.
-system::username = motoko
+system::username = admin
system::password = secret
@@ -50,15 +52,16 @@ system::password = secret
### Define values for Node 1.
-# The nodes name. This must match exactly with the name set in the given node.
-na::1::na_name = Motoko
+# The node assassin name. This must match exactly with the name programmed into
+# the given node.
+na::1::na_name = fence_na01
# This is the IP address and port where I will connect to this node at.
-# NOTE: THIS MUST MATCH THE VALUE USED IN '@CONFDIR@/@CONFFILE@'! If you used a
-# resolvable name there, use the same name here. Vice versa for IP addresses.
-# If this doesn't match the 'ipaddr' argument sent by the 'fenced' daemon the
-# fence will not work properly!
-na::1::ipaddr = motoko.alteeve.com
+# NOTE: THIS MUST MATCH THE VALUE USED IN '@CONFDIR@/@CONFFILE@'! If you
+# used a resolvable name there, use the same name here. Vice versa for IP
+# addresses. If this doesn't match the 'ipaddr' argument sent by the 'fenced'
+# daemon the fence will not work properly!
+na::1::ipaddr = fence_na01.domain.com
na::1::tcp_port = 238
# This is the number of nodes supported by this Node Assassin
@@ -77,8 +80,8 @@ na::1::gateway = 192.168.1.1
# then the 'list' action will return '<node_id>,<value>'. If a port is not
# defined, 'list' will return '<node_id>,<node::X::name-node_id>'. If a port is
# set to 'unused', it will be skipped when replying to a 'list'.
-na::1::alias::1 = an_node01.alteeve.com
-na::1::alias::2 = an_node02.alteeve.com
+na::1::alias::1 = node01.domain.com
+na::1::alias::2 = node02.domain.com
na::1::alias::3 = unused
na::1::alias::4 = unused
diff --git a/fence/agents/node_assassin/fence_na.lib.in b/fence/agents/node_assassin/fence_na.lib.in
index aa7300e..67d5367 100644
--- a/fence/agents/node_assassin/fence_na.lib.in
+++ b/fence/agents/node_assassin/fence_na.lib.in
@@ -4,9 +4,11 @@
#
# Node Assassin - Fence Agent
# Digimer; digimer(a)alteeve.com
-# Jun. 27, 2010.
-# Version: 1.1.5
+# Nov. 27, 2010.
+# Version: 1.1.6
#
+# This software is released under the GPL v2. See the LICENSE file for a copy
+# of the GPL v2.
# This connects to a Node Assassin and puts the handle in
@@ -242,8 +244,8 @@ sub no_connection_error
my ($conf, $log, $na_id)=@_;
record ($conf, $log, "\nERROR: Unable to query Node Assassin: [$conf->{na}{$na_id}{na_name}]!\n", 1);
record ($conf, $log, "ERROR: Please check that it is connected, that the information in\n", 1);
- record ($conf, $log, "ERROR: '@NACONFFILE@' is accurate and that the proper configuration\n", 1);
- record ($conf, $log, "ERROR: has be uploaded to the device.\n\n", 1);
+ record ($conf, $log, "ERROR: '@NACONFFILE@' is accurate and that the proper\n", 1);
+ record ($conf, $log, "ERROR: configuration has be uploaded to the device.\n\n", 1);
return (0);
}
diff --git a/fence/agents/node_assassin/fence_na.pl b/fence/agents/node_assassin/fence_na.pl
old mode 100644
new mode 100755
index 0d272b3..bc7fb00
--- a/fence/agents/node_assassin/fence_na.pl
+++ b/fence/agents/node_assassin/fence_na.pl
@@ -2,8 +2,11 @@
#
# Node Assassin - Fence Agent
# Digimer; digimer(a)alteeve.com
-# Jun. 27, 2010
-# Version: 1.1.5
+# Nov. 25, 2010
+# Version: 1.1.6
+#
+# This software is released under the GPL v2. See the LICENSE file in the
+# configuration directory for a copy of the GPL v2.
#
# Bugs;
# - None known, many expected
diff --git a/fence/agents/node_assassin/fence_na.pod.in b/fence/agents/node_assassin/fence_na.pod.in
index c3ec4e4..7bd6a3c 100644
--- a/fence/agents/node_assassin/fence_na.pod.in
+++ b/fence/agents/node_assassin/fence_na.pod.in
@@ -10,7 +10,7 @@ This is the fence agent for the Node Assassin fence device.
=head1 SYNOPSIS
- fence_na -a motoko.alteeve.com -n 2 -l motoko -p secret -o off
+ fence_na -a fence_na01.domain.com -n 2 -l admin -p secret -o off
=head1 DESCRIPTION
@@ -161,21 +161,21 @@ The power feeds of all nodes on the Node Assassin are checked. Any found to be o
To simulate how 'fenced' calls the script, create a text file called C<args.txt> containing:
# Test file used as input for the NA fence agent.
- ipaddr=ariel.alteeve.com
+ ipaddr=fence_na01.domain.com
port=02
- login=motoko
+ login=admin
passwd=secret
- action=off
+ action=reboot
Now use C<cat> to pipe the contents into the fence agent:
cat args.txt | fence_na
-This will call the C<off> function against node #02 connected to the Node Assassin at C<motoko.alteeve.com>, fencing it. Change the C<action> line to C<action=on> and re-run the script to release the fence and boot the node.
+This will call the C<off> function against node #02 connected to the Node Assassin at C<fence_na01.domain.com>, fencing it. Change the C<action> line to C<action=on> and re-run the script to release the fence and boot the node.
To duplicate the same call using command line arguments:
- fence_na -a motoko.alteeve.com -n 2 -l motoko -p secret -o off
+ fence_na -a fence_na01.domain.com -n 2 -l admin -p secret -o reboot
=head1 SEE ALSO
@@ -183,6 +183,6 @@ http://nodeassassin.org
=head1 UPDATED
-Jun. 26, 2010
+Nov. 27, 2010
Digimer (digimer(a)alteeve.com)
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